summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.azurepipelines/templates/pr-gate-build-job.yml3
-rw-r--r--.github/pull_request_template.md8
-rw-r--r--.github/scripts/GitHub.py285
-rw-r--r--.github/scripts/RequestPrReviewers.py98
-rw-r--r--.github/scripts/requirements.txt13
-rw-r--r--.github/workflows/pr-labeler.yml2
-rw-r--r--.github/workflows/request-reviews.yml73
-rw-r--r--.gitignore1
-rw-r--r--.mergify/config.yml4
-rw-r--r--.pytool/CISettings.py27
-rw-r--r--.pytool/Plugin/DependencyCheck/DependencyCheck.py4
-rw-r--r--.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py53
-rw-r--r--.pytool/Plugin/DscCompleteCheck/Readme.md3
-rw-r--r--.pytool/Plugin/EccCheck/EccCheck.py5
-rw-r--r--.pytool/Plugin/SpellCheck/SpellCheck.py3
-rw-r--r--.pytool/Plugin/SpellCheck/cspell.base.yaml467
-rw-r--r--.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py33
-rw-r--r--ArmPkg/ArmPkg.ci.yaml8
-rw-r--r--ArmPkg/ArmPkg.dec10
-rw-r--r--ArmPkg/ArmPkg.dsc18
-rw-r--r--ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc3
-rw-r--r--ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S2
-rw-r--r--ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S2
-rw-r--r--ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.c2
-rw-r--r--ArmPkg/Drivers/ArmPsciMpServicesDxe/MpFuncs.S2
-rw-r--r--ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c55
-rw-r--r--ArmPkg/Drivers/CpuDxe/MemoryAttribute.c21
-rw-r--r--ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c4
-rw-r--r--ArmPkg/Include/AsmMacroIoLib.inc33
-rw-r--r--ArmPkg/Include/Library/ArmMonitorLib.h12
-rw-r--r--ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c40
-rw-r--r--ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf1
-rw-r--r--ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S2
-rw-r--r--ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S2
-rw-r--r--ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S2
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S2
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c55
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h27
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/AArch64Support.S77
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S2
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S2
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S2
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S2
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S2
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c55
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h27
-rw-r--r--ArmPkg/Library/ArmLib/Arm/ArmV7Support.S69
-rw-r--r--ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c7
-rw-r--r--ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S2
-rw-r--r--ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c15
-rw-r--r--ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S2
-rw-r--r--ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S79
-rw-r--r--ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S49
-rw-r--r--ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c34
-rw-r--r--ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf11
-rw-r--r--ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c192
-rw-r--r--ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf26
-rw-r--r--ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S2
-rw-r--r--ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S2
-rw-r--r--ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c150
-rw-r--r--ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf29
-rw-r--r--ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S2
-rw-r--r--ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c10
-rw-r--r--ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S2
-rw-r--r--ArmPkg/Library/SemihostLib/Arm/GccSemihost.S2
-rw-r--r--ArmPlatformPkg/ArmPlatformPkg.ci.yaml3
-rw-r--r--ArmPlatformPkg/ArmPlatformPkg.dec3
-rw-r--r--ArmPlatformPkg/ArmPlatformPkg.dsc16
-rw-r--r--ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c23
-rw-r--r--ArmPlatformPkg/Include/Library/ArmPlatformLib.h43
-rw-r--r--ArmPlatformPkg/Include/Library/LcdPlatformLib.h2
-rw-r--r--ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.c2
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S35
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S33
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c4
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S99
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S98
-rw-r--r--ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf33
-rw-r--r--ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.c2
-rw-r--r--ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c4
-rw-r--r--ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.c6
-rw-r--r--ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c (renamed from ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c)5
-rw-r--r--ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S (renamed from ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S)47
-rw-r--r--ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c (renamed from ArmPlatformPkg/PrePi/Arm/ArchPrePi.c)5
-rw-r--r--ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S (renamed from ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S)48
-rw-r--r--ArmPlatformPkg/PeilessSec/PeilessSec.c (renamed from ArmPlatformPkg/PrePi/PrePi.c)95
-rw-r--r--ArmPlatformPkg/PeilessSec/PeilessSec.h76
-rw-r--r--ArmPlatformPkg/PeilessSec/PeilessSec.inf (renamed from ArmPlatformPkg/PrePi/PeiUniCore.inf)85
-rw-r--r--ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S73
-rw-r--r--ArmPlatformPkg/PrePeiCore/MainMPCore.c153
-rw-r--r--ArmPlatformPkg/PrePeiCore/MainUniCore.c57
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCore.c181
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCore.h76
-rw-r--r--ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf76
-rw-r--r--ArmPlatformPkg/PrePi/MainMPCore.c104
-rw-r--r--ArmPlatformPkg/PrePi/MainUniCore.c31
-rw-r--r--ArmPlatformPkg/PrePi/PeiMPCore.inf106
-rw-r--r--ArmPlatformPkg/PrePi/PrePi.h82
-rw-r--r--ArmPlatformPkg/Sec/AArch64/ArchSec.c (renamed from ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c)11
-rw-r--r--ArmPlatformPkg/Sec/AArch64/Exception.S (renamed from ArmPlatformPkg/PrePeiCore/AArch64/Exception.S)2
-rw-r--r--ArmPlatformPkg/Sec/AArch64/Helper.S (renamed from ArmPlatformPkg/PrePeiCore/AArch64/Helper.S)2
-rw-r--r--ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S (renamed from ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S)54
-rw-r--r--ArmPlatformPkg/Sec/AArch64/SwitchStack.S (renamed from ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S)2
-rw-r--r--ArmPlatformPkg/Sec/Arm/ArchSec.c (renamed from ArmPlatformPkg/PrePeiCore/Arm/ArchPrePeiCore.c)11
-rw-r--r--ArmPlatformPkg/Sec/Arm/Exception.S (renamed from ArmPlatformPkg/PrePeiCore/Arm/Exception.S)2
-rw-r--r--ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S40
-rw-r--r--ArmPlatformPkg/Sec/Arm/SwitchStack.S (renamed from ArmPlatformPkg/PrePeiCore/Arm/SwitchStack.S)2
-rw-r--r--ArmPlatformPkg/Sec/Sec.c249
-rw-r--r--ArmPlatformPkg/Sec/Sec.h54
-rw-r--r--ArmPlatformPkg/Sec/Sec.inf (renamed from ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf)45
-rw-r--r--ArmVirtPkg/ArmVirt.dsc.inc45
-rw-r--r--ArmVirtPkg/ArmVirtCloudHv.dsc2
-rw-r--r--ArmVirtPkg/ArmVirtCloudHv.fdf2
-rw-r--r--ArmVirtPkg/ArmVirtKvmTool.dsc2
-rw-r--r--ArmVirtPkg/ArmVirtQemu.dsc26
-rw-r--r--ArmVirtPkg/ArmVirtQemu.fdf2
-rw-r--r--ArmVirtPkg/ArmVirtQemuKernel.dsc4
-rw-r--r--ArmVirtPkg/ArmVirtXen.dsc2
-rw-r--r--ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c80
-rw-r--r--ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h20
-rw-r--r--ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S27
-rw-r--r--ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.c224
-rw-r--r--ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.inf42
-rw-r--r--ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c240
-rw-r--r--ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf40
-rw-r--r--ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.c128
-rw-r--r--ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.inf35
-rw-r--r--ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c28
-rw-r--r--ArmVirtPkg/Library/KvmtoolRtcFdtClientLib/KvmtoolRtcFdtClientLib.c4
-rw-r--r--ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c2
-rw-r--r--ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf5
-rw-r--r--ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLibConstructor.c1
-rw-r--r--ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S2
-rw-r--r--ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S2
-rwxr-xr-xArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf6
-rwxr-xr-xArmVirtPkg/PrePi/PrePi.c2
-rw-r--r--ArmVirtPkg/PrePi/PrePi.h6
-rw-r--r--BaseTools/Bin/GccLto/liblto-aarch64.a (renamed from ArmPkg/Library/GccLto/liblto-aarch64.a)bin1128 -> 1128 bytes
-rw-r--r--BaseTools/Bin/GccLto/liblto-aarch64.s (renamed from ArmPkg/Library/GccLto/liblto-aarch64.s)0
-rw-r--r--BaseTools/Bin/GccLto/liblto-arm.a (renamed from ArmPkg/Library/GccLto/liblto-arm.a)bin2096 -> 2096 bytes
-rw-r--r--BaseTools/Bin/GccLto/liblto-arm.s (renamed from ArmPkg/Library/GccLto/liblto-arm.s)0
-rw-r--r--BaseTools/Bin/GnuNoteBti.bin (renamed from ArmPkg/Library/GnuNoteBti.bin)bin32 -> 32 bytes
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/AmlToC14
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/BPDG12
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/BrotliCompress60
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/DevicePath29
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/Ecc13
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/EfiRom29
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/GenCrc3229
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/GenDepex12
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/GenFds12
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/GenFfs29
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/GenFv29
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/GenFw29
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/GenPatchPcdTable12
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/GenSec29
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/GenerateCapsule12
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/LzmaCompress29
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/LzmaF86Compress19
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/PatchPcdValue12
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/Pkcs7Sign12
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256GenerateKeys12
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256Sign12
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/Split29
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/TargetTool12
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/TianoCompress29
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/Trim13
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/UPT12
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/VfrCompile29
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/VolInfo29
-rwxr-xr-xBaseTools/BinPipWrappers/PosixLike/build12
-rw-r--r--BaseTools/BinPipWrappers/PosixLike/posix_path_env.yaml11
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/AmlToC.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/BPDG.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/Ecc.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/GenDepex.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/GenFds.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/GenPatchPcdTable.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/GenerateCapsule.bat1
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/PatchPcdValue.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/Pkcs7Sign.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256GenerateKeys.bat1
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256Sign.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/Split.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/TargetTool.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/Trim.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/UPT.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/build.bat3
-rw-r--r--BaseTools/BinPipWrappers/WindowsLike/win_build_tools_path_env.yaml11
-rwxr-xr-xBaseTools/BuildEnv11
-rwxr-xr-xBaseTools/Conf/tools_def.template244
-rw-r--r--BaseTools/Plugin/CodeQL/CodeQlQueries.qls4
-rw-r--r--BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml13
-rw-r--r--BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml13
-rw-r--r--BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml13
-rw-r--r--BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py1
-rw-r--r--BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py154
-rw-r--r--BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain_plug_in.yaml12
-rw-r--r--BaseTools/Plugin/LinuxGccToolChain/LinuxGccToolChain.py165
-rw-r--r--BaseTools/Plugin/LinuxGccToolChain/LinuxGccToolChain_plug_in.yaml12
-rw-r--r--BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py36
-rw-r--r--BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py158
-rw-r--r--BaseTools/Scripts/BinToPcd.py4
-rw-r--r--BaseTools/Scripts/GetMaintainer.py11
-rwxr-xr-xBaseTools/Scripts/PatchCheck.py1
-rw-r--r--BaseTools/Source/C/Common/Decompress.c2
-rw-r--r--BaseTools/Source/C/Include/Common/BaseTypes.h4
-rw-r--r--BaseTools/Source/C/Include/Common/UefiMultiPhase.h15
-rwxr-xr-xBaseTools/Source/Python/AutoGen/GenC.py31
-rwxr-xr-xBaseTools/Source/Python/AutoGen/GenMake.py1
-rw-r--r--BaseTools/Source/Python/Capsule/GenerateCapsule.py141
-rwxr-xr-xBaseTools/Source/Python/Common/GlobalData.py3
-rw-r--r--BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py22
-rw-r--r--BaseTools/Source/Python/Ecc/Check.py22
-rw-r--r--BaseTools/Source/Python/Ecc/Configuration.py5
-rw-r--r--BaseTools/Source/Python/Ecc/EccToolError.py2
-rw-r--r--BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py10
-rw-r--r--BaseTools/Source/Python/Ecc/c.py2
-rw-r--r--BaseTools/Source/Python/Ecc/config.ini4
-rw-r--r--BaseTools/Source/Python/Eot/EotGlobalData.py2
-rw-r--r--BaseTools/Source/Python/Eot/c.py2
-rw-r--r--BaseTools/Source/Python/README.md29
-rw-r--r--BaseTools/Source/Python/Trim/Trim.py33
-rw-r--r--BaseTools/Source/Python/UPT/Library/CommentParsing.py2
-rw-r--r--BaseTools/Source/Python/UPT/Library/ExpressionValidate.py18
-rw-r--r--BaseTools/Source/Python/UPT/Library/Misc.py10
-rw-r--r--BaseTools/Source/Python/UPT/Library/StringUtils.py2
-rw-r--r--BaseTools/Source/Python/UPT/Parser/DecParserMisc.py2
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py18
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py2
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfParserMisc.py10
-rw-r--r--BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py18
-rw-r--r--BaseTools/Source/Python/UPT/Xml/IniToXml.py4
-rw-r--r--BaseTools/Source/Python/UPT/Xml/PcdXml.py26
-rw-r--r--BaseTools/Source/Python/UPT/Xml/XmlParser.py12
-rw-r--r--BaseTools/Source/Python/Workspace/InfBuildData.py14
-rwxr-xr-xBaseTools/Source/Python/build/build.py21
-rw-r--r--BaseTools/set_vsprefix_envs.bat74
-rwxr-xr-xBaseTools/toolsetup.bat28
-rw-r--r--CryptoPkg/CryptoPkg.dec1
-rw-r--r--CryptoPkg/CryptoPkg.dsc36
-rw-r--r--CryptoPkg/CryptoPkgMbedTls.dsc12
-rw-r--r--CryptoPkg/Include/Library/BaseCryptLib.h7
-rw-r--r--CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c9
-rw-r--r--CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c3
-rw-r--r--CryptoPkg/Library/BaseCryptLib/SysCall/ConstantTimeClock.c29
-rw-r--r--CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c92
-rw-r--r--CryptoPkg/Library/BaseCryptLib/SysCall/UnitTestHostCrtWrapper.c22
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf3
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c1
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptTs.c15
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf6
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/SecCryptLib.inf6
-rw-r--r--CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf7
-rw-r--r--CryptoPkg/Library/Include/CrtLibSupport.h22
-rw-r--r--CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf3
-rw-r--r--CryptoPkg/Library/MbedTlsLib/MbedTlsLibFull.inf3
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/aesv8-armx.S3180
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/vpaes-armv8.S1196
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/arm64cpuid.S129
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/bn/armv8-mont.S2124
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/ec/ecp_nistz256-armv8.S4242
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S6389
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/ghashv8-armx.S552
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/keccak1600-armv8.S1009
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha1-armv8.S1211
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha256-armv8.S2000
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha512-armv8.S1555
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/bio.h2
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/opensslv.h10
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/pkcs7.h6
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslLib.inf5
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf650
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf5
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslLibFull.inf5
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf699
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslLibSm3.inf30
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslStub/AArch64Cap.c107
-rw-r--r--CryptoPkg/Library/OpensslLib/OpensslStub/OpensslCleanse.c20
-rw-r--r--CryptoPkg/Library/OpensslLib/UefiAsm.conf6
-rwxr-xr-xCryptoPkg/Library/OpensslLib/configure.py6
m---------CryptoPkg/Library/OpensslLib/openssl0
-rw-r--r--CryptoPkg/Readme.md14
-rw-r--r--CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c11
-rw-r--r--DynamicTablesPkg/Drivers/DynamicTableManagerDxe/Arm/ArmDynamicTableManager.c63
-rw-r--r--DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c70
-rw-r--r--DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.h63
-rw-r--r--DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf8
-rwxr-xr-xDynamicTablesPkg/Drivers/DynamicTableManagerDxe/X64/X64DynamicTableManager.c56
-rw-r--r--DynamicTablesPkg/DynamicTables.dsc.inc86
-rw-r--r--DynamicTablesPkg/DynamicTablesPkg.ci.yaml2
-rw-r--r--DynamicTablesPkg/DynamicTablesPkg.dsc6
-rw-r--r--DynamicTablesPkg/Include/AcpiTableGenerator.h23
-rw-r--r--DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h696
-rw-r--r--DynamicTablesPkg/Include/ArmNameSpaceObjects.h686
-rw-r--r--DynamicTablesPkg/Include/ConfigurationManagerObject.h77
-rw-r--r--DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h42
-rw-r--r--DynamicTablesPkg/Include/Library/SsdtPcieSupportLib.h12
-rw-r--r--DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h16
-rw-r--r--DynamicTablesPkg/Include/X64NameSpaceObjects.h191
-rw-r--r--DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c16
-rw-r--r--DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h147
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf)22
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Arm/ArmDbg2Generator.c67
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c)46
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.h56
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2GeneratorNull.c60
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf)16
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/Arm/ArmFadtGenerator.c126
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c)132
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.h35
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/X64/X64FadtGenerator.c382
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf)9
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c)31
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf)2
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c)200
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.h (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h)5
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf)2
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c)137
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.h (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h)0
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf)9
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/RawGenerator.c (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c)2
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf)9
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c)22
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf)9
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/Arm/ArmSratGenerator.c262
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c)271
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.h59
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGeneratorNull.c79
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c408
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c)493
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h343
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf)9
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c)127
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.h (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h)0
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf)2
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c)26
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf (renamed from DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf)6
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf29
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c405
-rw-r--r--DynamicTablesPkg/Library/Acpi/X64/AcpiHpetLib/AcpiHpetLib.c327
-rw-r--r--DynamicTablesPkg/Library/Acpi/X64/AcpiHpetLib/AcpiHpetLib.inf31
-rw-r--r--DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.c428
-rw-r--r--DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.inf31
-rw-r--r--DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf35
-rw-r--r--DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c288
-rw-r--r--DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c2
-rw-r--r--DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c83
-rw-r--r--DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlParser.c2
-rw-r--r--DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c2
-rw-r--r--DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c71
-rw-r--r--DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c269
-rw-r--r--DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h11
-rw-r--r--DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c9
-rw-r--r--DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.c12
-rw-r--r--DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c46
-rw-r--r--DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c642
-rw-r--r--DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h19
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c83
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c118
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.c (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.c)4
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.h (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.h)0
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.c (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.c)5
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.h (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.h)0
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c)5
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.h (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h)0
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.c (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.c)5
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.h (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.h)0
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.c (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.c)12
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.h (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.h)0
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.c (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.c)5
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.h (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.h)0
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.c (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.c)5
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.h (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.h)0
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.c (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.c)5
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.h (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.h)0
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c10
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h6
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c78
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.h27
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserInclude.h1
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf50
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c72
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h30
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c)80
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.h (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h)36
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.c (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c)97
-rw-r--r--DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.h (renamed from DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h)16
-rw-r--r--DynamicTablesPkg/Readme.md115
-rw-r--r--EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c1
-rw-r--r--EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.inf1
-rw-r--r--EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c197
-rw-r--r--EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h22
-rw-r--r--EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf62
-rw-r--r--EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni17
-rw-r--r--EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr35
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dec9
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dsc13
-rw-r--r--EmbeddedPkg/GdbStub/SerialIo.c2
-rw-r--r--EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h17
-rw-r--r--EmbeddedPkg/Include/Library/EfiResetSystemLib.h48
-rw-r--r--EmbeddedPkg/Include/libfdt.h2
-rw-r--r--EmbeddedPkg/Library/AcpiLib/AcpiLib.c86
-rw-r--r--EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c1
-rw-r--r--EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf1
-rw-r--r--EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c38
-rw-r--r--EmbeddedPkg/Library/PrePiHobLib/Hob.c19
-rw-r--r--EmbeddedPkg/Library/TemplateResetSystemLib/ResetSystemLib.c91
-rw-r--r--EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf30
-rw-r--r--EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c2
-rw-r--r--EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf2
-rw-r--r--EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf45
-rw-r--r--EmbeddedPkg/ResetRuntimeDxe/reset.c64
-rw-r--r--EmulatorPkg/EmulatorPkg.ci.yaml3
-rw-r--r--EmulatorPkg/EmulatorPkg.dsc18
-rw-r--r--EmulatorPkg/Unix/Host/Host.inf1
-rw-r--r--EmulatorPkg/Win/Host/WinHost.inf2
-rw-r--r--FatPkg/EnhancedFatDxe/DiskCache.c216
-rw-r--r--FatPkg/EnhancedFatDxe/Fat.h21
-rw-r--r--FatPkg/EnhancedFatDxe/Init.c28
-rw-r--r--FatPkg/FatPkg.ci.yaml3
-rw-r--r--FatPkg/FatPkg.dsc8
-rw-r--r--FmpDevicePkg/FmpDevicePkg.dsc14
-rw-r--r--FmpDevicePkg/FmpDxe/FmpDxe.c7
-rwxr-xr-x[-rw-r--r--]FmpDevicePkg/FmpDxe/FmpDxe.inf3
-rw-r--r--IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf1
-rw-r--r--IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf1
-rw-r--r--IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm30
-rw-r--r--IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm30
-rw-r--r--IntelFsp2Pkg/FspSecCore/SecFsp.c19
-rw-r--r--IntelFsp2Pkg/FspSecCore/SecFspApiChk.c12
-rw-r--r--IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm33
-rw-r--r--IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm33
-rw-r--r--IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm2
-rw-r--r--IntelFsp2Pkg/IntelFsp2Pkg.dec8
-rw-r--r--IntelFsp2Pkg/IntelFsp2Pkg.dsc4
-rw-r--r--IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf1
-rw-r--r--IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c67
-rw-r--r--IntelFsp2Pkg/Library/BaseFspCommonLib/ReturnStatus.c42
-rw-r--r--IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf4
-rw-r--r--IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm132
-rw-r--r--IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm109
-rw-r--r--IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c38
-rw-r--r--IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf3
-rw-r--r--IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec34
-rw-r--r--IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc4
-rw-r--r--Maintainers.txt55
-rw-r--r--MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c2
-rw-r--r--MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c34
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c35
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h38
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf10
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c10
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.c582
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.h191
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c2
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTest.c1128
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf37
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c7
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c2
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c51
-rw-r--r--MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c57
-rw-r--r--MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h22
-rw-r--r--MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf5
-rw-r--r--MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c28
-rw-r--r--MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c5
-rw-r--r--MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h6
-rw-r--r--MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf4
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c27
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain.h12
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain.inf1
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c6
-rw-r--r--MdeModulePkg/Core/Dxe/Gcd/Gcd.c23
-rw-r--r--MdeModulePkg/Core/Dxe/Hand/Handle.c89
-rw-r--r--MdeModulePkg/Core/Dxe/Image/Image.c4
-rw-r--r--MdeModulePkg/Core/Dxe/Mem/HeapGuard.c51
-rw-r--r--MdeModulePkg/Core/Dxe/Mem/Imem.h16
-rw-r--r--MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c38
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeLoad.c13
-rw-r--r--MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c37
-rw-r--r--MdeModulePkg/Core/Pei/FwVol/FwVol.c12
-rw-r--r--MdeModulePkg/Core/Pei/Memory/MemoryServices.c2
-rw-r--r--MdeModulePkg/Core/Pei/PeiMain/PeiMain.c16
-rw-r--r--MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c17
-rw-r--r--MdeModulePkg/Include/Guid/MigratedFvInfo.h3
-rw-r--r--MdeModulePkg/Include/Guid/MmCommBuffer.h63
-rw-r--r--MdeModulePkg/Include/Guid/NVMeEventGroup.h16
-rw-r--r--MdeModulePkg/Include/Library/HobPrintLib.h46
-rw-r--r--MdeModulePkg/Include/Protocol/MediaSanitize.h173
-rw-r--r--MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c28
-rw-r--r--MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c76
-rw-r--r--MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf4
-rw-r--r--MdeModulePkg/Library/HobPrintLib/HobPrintLib.c469
-rw-r--r--MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf34
-rw-r--r--MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.c4
-rw-r--r--MdeModulePkg/Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf2
-rw-r--r--MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c6
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h10
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c9
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h4
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c251
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c57
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf8
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c349
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.h43
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.c138
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf53
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c630
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c152
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf47
-rw-r--r--MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.uni15
-rw-r--r--MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c9
-rw-r--r--MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.h9
-rw-r--r--MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c11
-rw-r--r--MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibTraditional.c5
-rw-r--r--MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c6
-rw-r--r--MdeModulePkg/MdeModulePkg.ci.yaml1
-rw-r--r--MdeModulePkg/MdeModulePkg.dec30
-rw-r--r--MdeModulePkg/MdeModulePkg.dsc24
-rw-r--r--MdeModulePkg/Test/MdeModulePkgHostTest.dsc5
-rw-r--r--MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h6
-rw-r--r--MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf1
-rw-r--r--MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c119
-rw-r--r--MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c21
-rw-r--r--MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h4
-rw-r--r--MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c15
-rw-r--r--MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c10
-rw-r--r--MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c9
-rw-r--r--MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c6
-rw-r--r--MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h13
-rw-r--r--MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.c13
-rw-r--r--MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c6
-rw-r--r--MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c8
-rw-r--r--MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.c23
-rw-r--r--MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.inf1
-rw-r--r--MdeModulePkg/Universal/Variable/Pei/Variable.c1
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h33
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c2
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf2
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c18
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c53
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf4
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c28
-rw-r--r--MdePkg/Include/AArch64/AsmMacroLib.h (renamed from ArmPkg/Include/AsmMacroIoLibV8.h)0
-rw-r--r--MdePkg/Include/Arm/AsmMacroLib.h (renamed from ArmPkg/Include/AsmMacroIoLib.h)0
-rw-r--r--MdePkg/Include/Base.h2
-rw-r--r--MdePkg/Include/ConfidentialComputingGuestAttr.h15
-rw-r--r--MdePkg/Include/Guid/ConformanceProfiles.h67
-rw-r--r--MdePkg/Include/IndustryStandard/Acpi51.h1
-rw-r--r--MdePkg/Include/IndustryStandard/Acpi60.h1
-rw-r--r--MdePkg/Include/IndustryStandard/Acpi61.h2
-rw-r--r--MdePkg/Include/IndustryStandard/Acpi62.h2
-rw-r--r--MdePkg/Include/IndustryStandard/Acpi63.h2
-rw-r--r--MdePkg/Include/IndustryStandard/Acpi64.h2
-rw-r--r--MdePkg/Include/IndustryStandard/Acpi65.h90
-rw-r--r--MdePkg/Include/IndustryStandard/Http11.h28
-rw-r--r--MdePkg/Include/IndustryStandard/IoRemappingTable.h8
-rw-r--r--MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h77
-rw-r--r--MdePkg/Include/IndustryStandard/Mpam.h246
-rw-r--r--MdePkg/Include/IndustryStandard/Nvme.h88
-rw-r--r--MdePkg/Include/IndustryStandard/Pci.h2
-rw-r--r--MdePkg/Include/IndustryStandard/PciExpress21.h72
-rw-r--r--MdePkg/Include/IndustryStandard/PciExpress60.h121
-rw-r--r--MdePkg/Include/IndustryStandard/SmBios.h16
-rw-r--r--MdePkg/Include/IndustryStandard/Tdx.h2
-rw-r--r--MdePkg/Include/IndustryStandard/Tpm20.h19
-rw-r--r--MdePkg/Include/IndustryStandard/Tpm2Acpi.h4
-rw-r--r--MdePkg/Include/Library/ArmLib.h18
-rw-r--r--MdePkg/Include/Library/BaseLib.h108
-rw-r--r--MdePkg/Include/Library/DebugLib.h13
-rw-r--r--MdePkg/Include/Library/FdtLib.h426
-rw-r--r--MdePkg/Include/Library/PerformanceLib.h9
-rw-r--r--MdePkg/Include/Library/StackCheckFailureHookLib.h26
-rw-r--r--MdePkg/Include/Protocol/Http.h3
-rw-r--r--MdePkg/Include/Protocol/Smbios.h4
-rw-r--r--MdePkg/Include/Register/Amd/SevSnpMsr.h95
-rw-r--r--MdePkg/Include/Register/Intel/StmApi.h2
-rw-r--r--MdePkg/Include/Register/LoongArch64/Csr.h2
-rw-r--r--MdePkg/Include/Register/RiscV64/RiscVEncoding.h10
-rw-r--r--MdePkg/Include/Uefi/UefiMultiPhase.h17
-rw-r--r--MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.c2
-rw-r--r--MdePkg/Library/BaseFdtLib/BaseFdtLib.inf7
-rw-r--r--MdePkg/Library/BaseFdtLib/FdtLib.c390
-rw-r--r--MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.S30
-rw-r--r--MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.asm30
-rw-r--r--MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.S (renamed from MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S)10
-rw-r--r--MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.asm (renamed from MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm)10
-rw-r--r--MdePkg/Library/BaseLib/BaseLib.inf11
-rw-r--r--MdePkg/Library/BaseLib/CheckSum.c69
-rw-r--r--MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S33
-rw-r--r--MdePkg/Library/BaseLib/LoongArch64/Csr.c7
-rw-r--r--MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf1
-rw-r--r--MdePkg/Library/BaseMemoryLib/SetMemNWrapper.c54
-rw-r--r--MdePkg/Library/BaseMemoryLib/SetMemWrapper.c36
-rw-r--r--MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf24
-rw-r--r--MdePkg/Library/BaseMemoryLibMmx/SetMemNWrapper.c54
-rw-r--r--MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c36
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf12
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/SetMemNWrapper.c54
-rw-r--r--MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c36
-rw-r--r--MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf52
-rw-r--r--MdePkg/Library/BaseMemoryLibOptPei/SetMemNWrapper.c54
-rw-r--r--MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c36
-rw-r--r--MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf23
-rw-r--r--MdePkg/Library/BaseMemoryLibRepStr/SetMemNWrapper.c54
-rw-r--r--MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c36
-rw-r--r--MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf23
-rw-r--r--MdePkg/Library/BaseMemoryLibSse2/SetMemNWrapper.c54
-rw-r--r--MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c36
-rw-r--r--MdePkg/Library/BasePeCoffLib/BasePeCoff.c2
-rw-r--r--MdePkg/Library/BaseRngLib/AArch64/ArmRng.h12
-rw-r--r--MdePkg/Library/BaseRngLib/AArch64/Rndr.c10
-rw-r--r--MdePkg/Library/BaseRngLib/BaseRngLib.inf10
-rw-r--r--MdePkg/Library/BaseRngLib/Riscv/Rng.c277
-rw-r--r--MdePkg/Library/BaseRngLib/Riscv/Seed.S19
-rw-r--r--MdePkg/Library/BaseStackCheckLib/BaseStackCheckGcc.c50
-rw-r--r--MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf39
-rw-r--r--MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.uni16
-rw-r--r--MdePkg/Library/BaseStackCheckLib/BaseStackCheckNull.c9
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/div.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/div.asm (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/lasr.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/llsl.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/llsr.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/memmove.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/mullu.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/switch16.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/switch32.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/switch8.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/uread.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S (renamed from ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S)2
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf (renamed from ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf)5
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/memcmp_ms.c (renamed from ArmPkg/Library/CompilerIntrinsicsLib/memcmp_ms.c)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/memcpy.c (renamed from ArmPkg/Library/CompilerIntrinsicsLib/memcpy.c)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/memcpy_ms.c (renamed from ArmPkg/Library/CompilerIntrinsicsLib/memcpy_ms.c)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/memmove_ms.c (renamed from ArmPkg/Library/CompilerIntrinsicsLib/memmove_ms.c)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/memset.c (renamed from ArmPkg/Library/CompilerIntrinsicsLib/memset.c)0
-rw-r--r--MdePkg/Library/CompilerIntrinsicsLib/memset_ms.c (renamed from ArmPkg/Library/CompilerIntrinsicsLib/memset_ms.c)0
-rw-r--r--MdePkg/Library/DxeRngLib/DxeRngLib.c204
-rw-r--r--MdePkg/Library/DxeRngLib/DxeRngLib.inf8
-rw-r--r--MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHook.c25
-rw-r--r--MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf20
-rw-r--r--MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S21
-rw-r--r--MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm25
-rw-r--r--MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S21
-rw-r--r--MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm25
-rw-r--r--MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm43
-rw-r--r--MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm23
-rw-r--r--MdePkg/Library/StackCheckLib/Readme.md126
-rw-r--r--MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c38
-rw-r--r--MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c40
-rw-r--r--MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf58
-rw-r--r--MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm43
-rw-r--r--MdePkg/Library/StackCheckLibNull/IA32/StackCheckFunctionsMsvc.nasm21
-rw-r--r--MdePkg/Library/StackCheckLibNull/StackCheckLibHostApplicationMsvc.c13
-rw-r--r--MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf41
-rw-r--r--MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c23
-rw-r--r--MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf34
-rw-r--r--MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c10
-rw-r--r--MdePkg/Library/StackCheckLibNull/X64/StackCheckFunctionsMsvc.nasm21
-rw-r--r--MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf2
-rw-r--r--MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLib.c28
-rw-r--r--MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c7
-rw-r--r--MdePkg/Library/UefiDebugLibStdErr/DebugLib.c28
-rw-r--r--MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c4
-rw-r--r--MdePkg/Library/UefiDevicePathLib/DevicePathToText.c3
-rw-r--r--MdePkg/Library/UefiMemoryLib/SetMemNWrapper.c54
-rw-r--r--MdePkg/Library/UefiMemoryLib/SetMemWrapper.c36
-rw-r--r--MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf2
-rw-r--r--MdePkg/MdeLibs.dsc.inc17
-rw-r--r--MdePkg/MdePkg.ci.yaml4
-rw-r--r--MdePkg/MdePkg.dec29
-rw-r--r--MdePkg/MdePkg.dsc6
-rw-r--r--MdePkg/Test/MdePkgHostTest.dsc2
-rw-r--r--MdePkg/Test/Mock/Include/GoogleTest/Library/MockFdtLib.h4
-rw-r--r--MdePkg/Test/Mock/Library/GoogleTest/MockFdtLib/MockFdtLib.cpp4
-rw-r--r--MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c2
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c2
-rw-r--r--NetworkPkg/HttpBootDxe/HttpBootClient.c182
-rw-r--r--NetworkPkg/HttpBootDxe/HttpBootClient.h1
-rw-r--r--NetworkPkg/HttpBootDxe/HttpBootDxe.h2
-rw-r--r--NetworkPkg/HttpBootDxe/HttpBootDxe.inf6
-rw-r--r--NetworkPkg/HttpBootDxe/HttpBootImpl.c246
-rw-r--r--NetworkPkg/HttpBootDxe/HttpBootImpl.h7
-rw-r--r--NetworkPkg/HttpDxe/HttpImpl.c12
-rw-r--r--NetworkPkg/HttpDxe/HttpProto.c6
-rw-r--r--NetworkPkg/HttpDxe/HttpProto.h3
-rw-r--r--NetworkPkg/Include/Library/HttpLib.h3
-rw-r--r--NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c10
-rw-r--r--NetworkPkg/Library/DxeNetLib/DxeNetLib.c14
-rw-r--r--NetworkPkg/Library/DxeNetLib/DxeNetLib.inf2
-rw-r--r--NetworkPkg/MnpDxe/MnpConfig.c2
-rw-r--r--NetworkPkg/NetworkPcds.dsc.inc2
-rw-r--r--NetworkPkg/NetworkPkg.ci.yaml3
-rw-r--r--NetworkPkg/NetworkPkg.dec16
-rw-r--r--NetworkPkg/NetworkPkg.dsc11
-rw-r--r--NetworkPkg/SnpDxe/Reset.c9
-rw-r--r--NetworkPkg/Test/NetworkPkgHostTest.dsc13
-rw-r--r--NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp25
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c7
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c7
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h1
-rw-r--r--NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf1
-rw-r--r--NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c34
-rw-r--r--OvmfPkg/AmdSev/AmdSevX64.dsc3
-rw-r--r--OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c10
-rw-r--r--OvmfPkg/Bhyve/BhyveX64.dsc3
-rw-r--r--OvmfPkg/CloudHv/CloudHvX64.dsc5
-rw-r--r--OvmfPkg/CpuHotplugSmm/CpuHotplug.c5
-rw-r--r--OvmfPkg/Include/Guid/XenInfo.h4
-rw-r--r--OvmfPkg/Include/IndustryStandard/Xen/sched.h50
-rw-r--r--OvmfPkg/Include/Library/MemEncryptSevLib.h12
-rw-r--r--OvmfPkg/Include/Library/XenHypercallLib.h7
-rw-r--r--OvmfPkg/IntelTdx/IntelTdxX64.dsc3
-rw-r--r--OvmfPkg/IntelTdx/README.md4
-rw-r--r--OvmfPkg/IntelTdx/Sec/SecMain.c12
-rw-r--r--OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c27
-rw-r--r--OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c19
-rw-r--r--OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c19
-rw-r--r--OvmfPkg/Library/CcExitLib/CcExitVcHandler.c8
-rw-r--r--OvmfPkg/Library/HardwareInfoLib/HardwareInfoDxe.c2
-rw-r--r--OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c1
-rw-r--r--OvmfPkg/Library/PlatformInitLib/IntelTdx.c12
-rw-r--r--OvmfPkg/Library/PlatformInitLib/MemDetect.c141
-rw-r--r--OvmfPkg/Library/PlatformInitLib/Platform.c20
-rw-r--r--OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf4
-rw-r--r--OvmfPkg/Library/PlatformInitLib/X64/Paging.nasm76
-rw-r--r--OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c5
-rw-r--r--OvmfPkg/Library/ResetSystemLib/BaseResetShutdownXen.c65
-rw-r--r--OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf41
-rw-r--r--OvmfPkg/Library/ResetSystemLib/DxeResetShutdownXen.c77
-rw-r--r--OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf46
-rw-r--r--OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm37
-rw-r--r--OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm37
-rw-r--r--OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c112
-rw-r--r--OvmfPkg/Library/XenHypercallLib/XenHypercall.c14
-rw-r--r--OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf6
-rw-r--r--OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c6
-rw-r--r--OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c6
-rw-r--r--OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c2
-rw-r--r--OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc12
-rw-r--r--OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc32
-rw-r--r--OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf2
-rw-r--r--OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S2
-rw-r--r--OvmfPkg/Microvm/MicrovmX64.dsc5
-rw-r--r--OvmfPkg/OvmfPkg.ci.yaml3
-rw-r--r--OvmfPkg/OvmfPkgIa32.dsc9
-rw-r--r--OvmfPkg/OvmfPkgIa32X64.dsc8
-rw-r--r--OvmfPkg/OvmfPkgX64.dsc5
-rw-r--r--OvmfPkg/OvmfXen.dsc11
-rw-r--r--OvmfPkg/PlatformPei/AmdSev.c13
-rw-r--r--OvmfPkg/PlatformPei/IntelTdx.c4
-rw-r--r--OvmfPkg/PlatformPei/Platform.c5
-rw-r--r--OvmfPkg/QemuVideoDxe/Initialize.c18
-rw-r--r--OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm11
-rw-r--r--OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc10
-rw-r--r--OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc2
-rw-r--r--OvmfPkg/Sec/SecMain.c15
-rw-r--r--OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c12
-rw-r--r--OvmfPkg/VirtioBlkDxe/VirtioBlk.c30
-rw-r--r--OvmfPkg/VirtioGpuDxe/Gop.c3
-rw-r--r--OvmfPkg/VirtioScsiDxe/VirtioScsi.c24
-rw-r--r--OvmfPkg/XenPlatformPei/Xen.c23
-rw-r--r--PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml3
-rw-r--r--PcAtChipsetPkg/PcAtChipsetPkg.dsc4
-rw-r--r--PrmPkg/PrmConfigDxe/PrmConfigDxe.c7
-rw-r--r--PrmPkg/PrmPkg.ci.yaml1
-rw-r--r--PrmPkg/PrmPkg.dsc16
-rw-r--r--RedfishPkg/Include/Protocol/EdkIIRedfishCredential2.h128
-rw-r--r--RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h5
-rw-r--r--RedfishPkg/Include/RedfishCommon.h17
-rw-r--r--RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c77
-rw-r--r--RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.h2
-rw-r--r--RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.inf3
-rw-r--r--RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c6
-rw-r--r--RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c2
-rw-r--r--RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c798
-rw-r--r--RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h91
-rw-r--r--RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf9
-rw-r--r--RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c9
-rw-r--r--RedfishPkg/RedfishHttpDxe/RedfishHttpData.h16
-rw-r--r--RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c107
-rw-r--r--RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.h4
-rw-r--r--RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.inf2
-rw-r--r--RedfishPkg/RedfishHttpDxe/RedfishHttpOperation.c12
-rw-r--r--RedfishPkg/RedfishPkg.dec7
-rw-r--r--RedfishPkg/RedfishPkg.dsc9
-rw-r--r--RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c6
-rw-r--r--RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h8
-rw-r--r--RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h2
-rw-r--r--RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c8
-rw-r--r--RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c2
-rw-r--r--RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c2
-rw-r--r--SecurityPkg/FvReportPei/FvReportPei.c20
-rw-r--r--SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c3
-rw-r--r--SecurityPkg/SecurityPkg.ci.yaml3
-rw-r--r--SecurityPkg/SecurityPkg.dsc14
-rw-r--r--SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c2
-rw-r--r--SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl65
-rw-r--r--SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c20
-rw-r--r--SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c11
-rw-r--r--SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c103
-rw-r--r--SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h27
-rw-r--r--SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c30
-rw-r--r--SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c26
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c207
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h178
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c36
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c8
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c370
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c28
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c24
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c14
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c982
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c12
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c19
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c32
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c311
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/MpamParser.c1241
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c56
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c38
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ras2/Ras2Parser.c118
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c14
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c14
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c26
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c20
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c6
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf6
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni3
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c282
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c34
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c2
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni56
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf4
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni31
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Reset.c2
-rw-r--r--ShellPkg/ShellPkg.ci.yaml3
-rw-r--r--ShellPkg/ShellPkg.dsc19
-rw-r--r--SignedCapsulePkg/SignedCapsulePkg.ci.yaml3
-rw-r--r--SignedCapsulePkg/SignedCapsulePkg.dsc15
-rw-r--r--SourceLevelDebugPkg/SourceLevelDebugPkg.ci.yaml3
-rw-r--r--SourceLevelDebugPkg/SourceLevelDebugPkg.dsc4
-rw-r--r--StandaloneMmPkg/Core/Dependency.c7
-rw-r--r--StandaloneMmPkg/Core/Dispatcher.c151
-rw-r--r--StandaloneMmPkg/Core/FwVol.c41
-rw-r--r--StandaloneMmPkg/Core/MemoryAttributesTable.c493
-rw-r--r--StandaloneMmPkg/Core/Page.c648
-rw-r--r--StandaloneMmPkg/Core/Pool.c25
-rw-r--r--StandaloneMmPkg/Core/StandaloneMmCore.c462
-rw-r--r--StandaloneMmPkg/Core/StandaloneMmCore.h123
-rw-r--r--StandaloneMmPkg/Core/StandaloneMmCore.inf11
-rw-r--r--StandaloneMmPkg/Core/StandaloneMmCorePrivateData.h2
-rw-r--r--StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c478
-rw-r--r--StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h176
-rw-r--r--StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf56
-rw-r--r--StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c932
-rw-r--r--StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c800
-rw-r--r--StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h145
-rw-r--r--StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf81
-rw-r--r--StandaloneMmPkg/Include/Guid/MmCoreData.h126
-rw-r--r--StandaloneMmPkg/Include/Library/FvLib.h2
-rw-r--r--StandaloneMmPkg/Include/Library/MmPlatformHobProducerLib.h54
-rw-r--r--StandaloneMmPkg/Library/FvLib/FvLib.c14
-rw-r--r--StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.c66
-rw-r--r--StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf28
-rw-r--r--StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.c50
-rw-r--r--StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf34
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c39
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf1
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationServices.h2
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf2
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c38
-rw-r--r--StandaloneMmPkg/StandaloneMmPkg.ci.yaml7
-rw-r--r--StandaloneMmPkg/StandaloneMmPkg.dec23
-rw-r--r--StandaloneMmPkg/StandaloneMmPkg.dsc33
-rw-r--r--UefiCpuPkg/CpuDxe/LoongArch64/Exception.c4
-rw-r--r--UefiCpuPkg/Include/Guid/MmAcpiS3Enable.h34
-rw-r--r--UefiCpuPkg/Include/Guid/MmCpuSyncConfig.h53
-rw-r--r--UefiCpuPkg/Include/Guid/MmProfileData.h35
-rw-r--r--UefiCpuPkg/Include/Guid/MmUnblockRegion.h42
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ArchExceptionHandler.c2
-rw-r--r--UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c15
-rw-r--r--UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c81
-rw-r--r--UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf47
-rw-r--r--UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c6
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.c311
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.h29
-rw-r--r--UefiCpuPkg/Library/MtrrLib/MtrrLib.c7
-rw-r--r--UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.c27
-rw-r--r--UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.inf6
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c36
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c12
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c43
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm1
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c2
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArchDxeSmm.c22
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c24
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h6
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c32
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c742
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c214
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c1538
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h (renamed from UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h)229
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c1622
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf14
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c270
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf133
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c672
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c4
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c4
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c484
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h22
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h50
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c4
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c12
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c257
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm6
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c2
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArchDxeSmm.c22
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c173
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h61
-rw-r--r--UefiCpuPkg/UefiCpuPkg.ci.yaml3
-rw-r--r--UefiCpuPkg/UefiCpuPkg.dec14
-rw-r--r--UefiCpuPkg/UefiCpuPkg.dsc21
-rw-r--r--UefiPayloadPkg/Include/Guid/PciSegmentInfoGuid.h32
-rw-r--r--UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h10
-rw-r--r--UefiPayloadPkg/Include/Guid/UniversalPayloadSerialPortDeviceParentInfo.h28
-rw-r--r--UefiPayloadPkg/Include/Library/BuildFdtLib.h22
-rw-r--r--UefiPayloadPkg/Include/Library/FdtParserLib.h64
-rw-r--r--UefiPayloadPkg/Include/Library/HobParserLib.h70
-rw-r--r--UefiPayloadPkg/Include/UniversalPayload/DeviceTree.h30
-rw-r--r--UefiPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.c1
-rw-r--r--UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c69
-rw-r--r--UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf6
-rw-r--r--UefiPayloadPkg/Library/BaseSerialPortLibHob/DxeBaseSerialPortLibHob.inf10
-rw-r--r--UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf65
-rw-r--r--UefiPayloadPkg/Library/BuildFdtLib/X86_BuildFdtLib.c945
-rw-r--r--UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c164
-rw-r--r--UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf46
-rw-r--r--UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.c46
-rw-r--r--UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf27
-rw-r--r--UefiPayloadPkg/Library/DebugPrintErrorLevelLibHob/DebugPrintErrorLevelLibHob.c4
-rw-r--r--UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf65
-rw-r--r--UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c1039
-rw-r--r--UefiPayloadPkg/Library/HobParseLib/HobParseLib.c280
-rw-r--r--UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf40
-rw-r--r--UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c6
-rw-r--r--UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf2
-rw-r--r--UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c219
-rw-r--r--UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf5
-rw-r--r--UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c4
-rw-r--r--UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c6
-rw-r--r--UefiPayloadPkg/PayloadLoaderPeim/FitLib.h2
-rw-r--r--UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c246
-rw-r--r--UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf13
-rw-r--r--UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c73
-rw-r--r--UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.inf12
-rw-r--r--UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c6
-rw-r--r--UefiPayloadPkg/Readme.md54
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/AcpiTable.c11
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c372
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf28
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c12
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c405
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c52
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/PrintHob.c345
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFunc.c74
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFuncFit.c34
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c8
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h68
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf1
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c6
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf15
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c12
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFuncFit.c135
-rw-r--r--UefiPayloadPkg/UefiPayloadPkg.ci.yaml3
-rw-r--r--UefiPayloadPkg/UefiPayloadPkg.dec28
-rw-r--r--UefiPayloadPkg/UefiPayloadPkg.dsc39
-rw-r--r--UefiPayloadPkg/UniversalPayloadBuild.py2
-rw-r--r--UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc22
-rw-r--r--UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc3
-rw-r--r--UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc28
-rwxr-xr-xedksetup.bat2
-rw-r--r--pip-requirements.txt11
1009 files changed, 65701 insertions, 14401 deletions
diff --git a/.azurepipelines/templates/pr-gate-build-job.yml b/.azurepipelines/templates/pr-gate-build-job.yml
index 689e2f0..3cad858 100644
--- a/.azurepipelines/templates/pr-gate-build-job.yml
+++ b/.azurepipelines/templates/pr-gate-build-job.yml
@@ -90,6 +90,9 @@ jobs:
extra_install_step: ${{ parameters.extra_install_step }}
- job: Build_${{ parameters.tool_chain_tag }}_TARGET_CODE_COVERAGE
+ # Disable this job from running in PR gatees. It causes the entire pipeline run to wait while the job is requeued
+ # causing runs take several hours.
+ condition: false
dependsOn: Build_${{ parameters.tool_chain_tag }}
workspace:
clean: all
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 70e8c56..3ecabed 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -9,13 +9,13 @@
<_Delete lines in \<\> tags before creating the PR._>
- [ ] Breaking change?
- - **Breaking change** - Will this cause a break in build or boot behavior?
- - Examples: Add a new library class or move a module to a different repo.
+ - **Breaking change** - Does this PR cause a break in build or boot behavior?
+ - Examples: Does it add a new library class or move a module to a different repo.
- [ ] Impacts security?
- - **Security** - Does the change have a direct security impact?
+ - **Security** - Does this PR have a direct security impact?
- Examples: Crypto algorithm change or buffer overflow fix.
- [ ] Includes tests?
- - **Tests** - Does the change include any explicit test code?
+ - **Tests** - Does this PR include any explicit test code?
- Examples: Unit tests or integration tests.
## How This Was Tested
diff --git a/.github/scripts/GitHub.py b/.github/scripts/GitHub.py
new file mode 100644
index 0000000..885975a
--- /dev/null
+++ b/.github/scripts/GitHub.py
@@ -0,0 +1,285 @@
+## @file
+# GitHub API helper functions.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+import git
+import logging
+import re
+
+from collections import OrderedDict
+from edk2toollib.utility_functions import RunPythonScript
+from github import Auth, Github, GithubException
+from io import StringIO
+from typing import List
+
+
+"""GitHub API helper functions."""
+
+
+def _authenticate(token: str):
+ """Authenticate to GitHub using a token.
+
+ Returns a GitHub instance that is authenticated using the provided
+ token.
+
+ Args:
+ token (str): The GitHub token to use for authentication.
+
+ Returns:
+ Github: A GitHub instance.
+ """
+ auth = Auth.Token(token)
+ return Github(auth=auth)
+
+
+def _get_pr(token: str, owner: str, repo: str, pr_number: int):
+ """Get the PR object from GitHub.
+
+ Args:
+ token (str): The GitHub token to use for authentication.
+ owner (str): The GitHub owner (organization) name.
+ repo (str): The GitHub repository name (e.g. 'edk2').
+ pr_number (int): The pull request number.
+
+ Returns:
+ PullRequest: A PyGithub PullRequest object for the given pull request
+ or None if the attempt to get the PR fails.
+ """
+ try:
+ g = _authenticate(token)
+ return g.get_repo(f"{owner}/{repo}").get_pull(pr_number)
+ except GithubException as ge:
+ print(
+ f"::error title=Error Getting PR {pr_number} Info!::"
+ f"{ge.data['message']}"
+ )
+ return None
+
+
+def leave_pr_comment(
+ token: str, owner: str, repo: str, pr_number: int, comment_body: str
+):
+ """Leaves a comment on a PR.
+
+ Args:
+ token (str): The GitHub token to use for authentication.
+ owner (str): The GitHub owner (organization) name.
+ repo (str): The GitHub repository name (e.g. 'edk2').
+ pr_number (int): The pull request number.
+ comment_body (str): The comment text. Markdown is supported.
+ """
+ if pr := _get_pr(token, owner, repo, pr_number):
+ try:
+ pr.create_issue_comment(comment_body)
+ except GithubException as ge:
+ print(
+ f"::error title=Error Commenting on PR {pr_number}!::"
+ f"{ge.data['message']}"
+ )
+
+
+def get_reviewers_for_range(
+ workspace_path: str,
+ maintainer_file_path: str,
+ range_start: str = "master",
+ range_end: str = "HEAD",
+) -> List[str]:
+ """Get the reviewers for the current branch.
+
+ !!! note
+ This function accepts a range of commits and returns the reviewers
+ for that set of commits as a single list of GitHub usernames. To get
+ the reviewers for a single commit, set `range_start` and `range_end`
+ to the commit SHA.
+
+ Args:
+ workspace_path (str): The workspace path.
+ maintainer_file_path (str): The maintainer file path.
+ range_start (str, optional): The range start ref. Defaults to "master".
+ range_end (str, optional): The range end ref. Defaults to "HEAD".
+
+ Returns:
+ List[str]: A list of GitHub usernames.
+ """
+ if range_start == range_end:
+ commits = [range_start]
+ else:
+ commits = [
+ c.hexsha
+ for c in git.Repo(workspace_path).iter_commits(
+ f"{range_start}..{range_end}"
+ )
+ ]
+
+ raw_reviewers = []
+ for commit_sha in commits:
+ reviewer_stream_buffer = StringIO()
+ cmd_ret = RunPythonScript(
+ maintainer_file_path,
+ f"-g {commit_sha}",
+ workingdir=workspace_path,
+ outstream=reviewer_stream_buffer,
+ logging_level=logging.INFO,
+ )
+ if cmd_ret != 0:
+ print(
+ f"::error title=Reviewer Lookup Error!::Error calling "
+ f"GetMaintainer.py: [{cmd_ret}]: "
+ f"{reviewer_stream_buffer.getvalue()}"
+ )
+ return []
+
+ commit_reviewers = reviewer_stream_buffer.getvalue()
+
+ pattern = r"\[(.*?)\]"
+ matches = re.findall(pattern, commit_reviewers)
+ if not matches:
+ return []
+
+ print(
+ f"::debug title=Commit {commit_sha[:7]} "
+ f"Reviewer(s)::{', '.join(matches)}"
+ )
+
+ raw_reviewers.extend(matches)
+
+ reviewers = list(OrderedDict.fromkeys([r.strip() for r in raw_reviewers]))
+
+ print(f"::debug title=Total Reviewer Set::{', '.join(reviewers)}")
+
+ return reviewers
+
+
+def get_pr_sha(token: str, owner: str, repo: str, pr_number: int) -> str:
+ """Returns the commit SHA of given PR branch.
+
+ This returns the SHA of the merge commit that GitHub creates from a
+ PR branch. This commit contains all of the files in the PR branch in
+ a single commit.
+
+ Args:
+ token (str): The GitHub token to use for authentication.
+ owner (str): The GitHub owner (organization) name.
+ repo (str): The GitHub repository name (e.g. 'edk2').
+ pr_number (int): The pull request number.
+
+ Returns:
+ str: The commit SHA of the PR branch. An empty string is returned
+ if the request fails.
+ """
+ if pr := _get_pr(token, owner, repo, pr_number):
+ merge_commit_sha = pr.merge_commit_sha
+ print(f"::debug title=PR {pr_number} Merge Commit SHA::{merge_commit_sha}")
+ return merge_commit_sha
+
+ return ""
+
+
+def add_reviewers_to_pr(
+ token: str, owner: str, repo: str, pr_number: int, user_names: List[str]
+) -> List[str]:
+ """Adds the set of GitHub usernames as reviewers to the PR.
+
+ Args:
+ token (str): The GitHub token to use for authentication.
+ owner (str): The GitHub owner (organization) name.
+ repo (str): The GitHub repository name (e.g. 'edk2').
+ pr_number (int): The pull request number.
+ user_names (List[str]): List of GitHub usernames to add as reviewers.
+
+ Returns:
+ List[str]: A list of GitHub usernames that were successfully added as
+ reviewers to the PR. This list will exclude any reviewers
+ from the list provided if they are not relevant to the PR.
+ """
+ if not user_names:
+ print(
+ "::debug title=No PR Reviewers Requested!::"
+ "The list of PR reviewers is empty so not adding any reviewers."
+ )
+ return []
+
+ try:
+ g = _authenticate(token)
+ repo_gh = g.get_repo(f"{owner}/{repo}")
+ pr = repo_gh.get_pull(pr_number)
+ except GithubException as ge:
+ print(
+ f"::error title=Error Getting PR {pr_number} Info!::"
+ f"{ge.data['message']}"
+ )
+ return None
+
+ # The pull request author cannot be a reviewer.
+ pr_author = pr.user.login.strip()
+
+ # The current PR reviewers do not need to be requested again.
+ current_pr_requested_reviewers = [
+ r.login.strip() for r in pr.get_review_requests()[0]
+ ]
+ current_pr_reviewed_reviewers = [r.user.login.strip() for r in pr.get_reviews()]
+ current_pr_reviewers = list(
+ set(current_pr_requested_reviewers + current_pr_reviewed_reviewers)
+ )
+
+ # A user can only be added if they are a collaborator of the repository.
+ repo_collaborators = [c.login.strip() for c in repo_gh.get_collaborators()]
+ non_collaborators = [u for u in user_names if u not in repo_collaborators]
+
+ excluded_pr_reviewers = [pr_author] + current_pr_reviewers + non_collaborators
+ new_pr_reviewers = [u for u in user_names if u not in excluded_pr_reviewers]
+
+ # Notify the admins of the repository if non-collaborators are requested.
+ if non_collaborators:
+ print(
+ f"::warning title=Non-Collaborator Reviewers Found!::"
+ f"{', '.join(non_collaborators)}"
+ )
+
+ for comment in pr.get_issue_comments():
+ # If a comment has already been made for these non-collaborators,
+ # do not make another comment.
+ if (
+ comment.user.login == "tianocore-assign-reviewers[bot]"
+ and "WARNING: Cannot add some reviewers" in comment.body
+ and all(u in comment.body for u in non_collaborators)
+ ):
+ break
+ else:
+ repo_admins = [
+ a.login for a in repo_gh.get_collaborators(permission="admin")
+ ]
+
+ leave_pr_comment(
+ token,
+ owner,
+ repo,
+ pr_number,
+ f"&#9888; **WARNING: Cannot add some reviewers**: A user "
+ f"specified as a reviewer for this PR is not a collaborator "
+ f"of the repository. Please add them as a collaborator to "
+ f"the repository so they can be requested in the future.\n\n"
+ f"Non-collaborators requested:\n"
+ f"{'\n'.join([f'- @{c}' for c in non_collaborators])}"
+ f"\n\nAttn Admins:\n"
+ f"{'\n'.join([f'- @{a}' for a in repo_admins])}\n---\n"
+ f"**Admin Instructions:**\n"
+ f"- Add the non-collaborators as collaborators to the "
+ f"appropriate team(s) listed in "
+ f"[teams](https://github.com/orgs/tianocore/teams)\n"
+ f"- If they are no longer needed as reviewers, remove them "
+ f"from [`Maintainers.txt`](https://github.com/tianocore/edk2/blob/HEAD/Maintainers.txt)",
+ )
+
+ # Add any new reviewers to the PR if needed.
+ if new_pr_reviewers:
+ print(
+ f"::debug title=Adding New PR Reviewers::" f"{', '.join(new_pr_reviewers)}"
+ )
+
+ pr.create_review_request(reviewers=new_pr_reviewers)
+
+ return new_pr_reviewers
diff --git a/.github/scripts/RequestPrReviewers.py b/.github/scripts/RequestPrReviewers.py
new file mode 100644
index 0000000..fdff657
--- /dev/null
+++ b/.github/scripts/RequestPrReviewers.py
@@ -0,0 +1,98 @@
+## @file
+# Used in a CI workflow to request reviewers for a pull request.
+#
+# Refer to the following link for a list of pre-defined GitHub workflow
+# environment variables:
+# https://docs.github.com/actions/reference/environment-variables
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+import git
+import GitHub
+import os
+import sys
+
+
+"""Request Pull Request Reviewers Helpers"""
+
+
+def request_pr_reviewers():
+ """Request pull request reviewers for a GitHub PR.
+
+ This function is intended to be used in a GitHub Actions workflow to
+ request reviewers for a pull request triggered by a GitHub event. The
+ function makes assumptions about GitHub workflow environment variables and
+ the pull request context in which it is run.
+
+ The function will exit with a non-zero status indicating an error if a
+ critical error occurs during execution so the workflow fails.
+
+ The following environment variables are expected to be set before calling
+ this function. The recommend GitHub context values are show for reference:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ ORG_NAME: ${{ github.repository_owner }}
+ PR_NUMBER: ${{ github.event.number}}
+ REPO_NAME: ${{ github.event.pull_request.base.repo.name }}
+ TARGET_BRANCH: ${{ github.event.pull_request.base.ref }}
+ WORKSPACE_PATH: ${{ github.workspace }}
+ """
+ WORKSPACE_PATH = os.environ["WORKSPACE_PATH"]
+ GET_MAINTAINER_LOCAL_PATH = os.path.join(
+ WORKSPACE_PATH, os.environ["GET_MAINTAINER_REL_PATH"]
+ )
+
+ # Step 1: Get the GitHub created PR commit SHA (contains all changes in a single commit)
+ pr_commit_sha = GitHub.get_pr_sha(
+ os.environ["GH_TOKEN"],
+ os.environ["ORG_NAME"],
+ os.environ["REPO_NAME"],
+ int(os.environ["PR_NUMBER"]),
+ )
+ if not pr_commit_sha:
+ sys.exit(1)
+
+ print(
+ f"::notice title=PR Commit SHA::Looking at files in consolidated PR commit: {pr_commit_sha}"
+ )
+
+ # Step 2: Fetch only the PR commit to get the files changed in the PR
+ git.Repo(WORKSPACE_PATH).remotes.origin.fetch(pr_commit_sha, depth=1)
+
+ # Step 3: Get the list of reviewers for the PR
+ reviewers = GitHub.get_reviewers_for_range(
+ WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, pr_commit_sha, pr_commit_sha
+ )
+ if not reviewers:
+ print("::notice title=No New Reviewers Found!::No reviewers found for this PR.")
+ sys.exit(0)
+
+ print(
+ f"::notice title=Preliminary Reviewer List::Total reviewer candidates for "
+ f"PR {os.environ['PR_NUMBER']}: {', '.join(reviewers)}"
+ )
+
+ # Step 4: Add the reviewers to the PR
+ # Note the final requested reviewer list in the workflow run for reference
+ new_reviewers = GitHub.add_reviewers_to_pr(
+ os.environ["GH_TOKEN"],
+ os.environ["ORG_NAME"],
+ os.environ["REPO_NAME"],
+ int(os.environ["PR_NUMBER"]),
+ reviewers,
+ )
+ if new_reviewers:
+ print(
+ f"::notice title=New Reviewers Added::New reviewers requested for PR "
+ f"{os.environ['PR_NUMBER']}: {', '.join(new_reviewers)}"
+ )
+ else:
+ print(
+ "::notice title=No New Reviewers Added::No reviewers were found that "
+ "should be newly requested."
+ )
+
+
+if __name__ == '__main__':
+ request_pr_reviewers()
diff --git a/.github/scripts/requirements.txt b/.github/scripts/requirements.txt
new file mode 100644
index 0000000..c589084
--- /dev/null
+++ b/.github/scripts/requirements.txt
@@ -0,0 +1,13 @@
+## @file
+# GitHub Helpers Python PIP requirements file
+#
+# This file provides the list of python components used in GitHub scripts in this repository.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+edk2-pytool-library==0.*
+GitPython==3.*
+PyGithub==2.*
diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml
index 1b7daa6..b984898 100644
--- a/.github/workflows/pr-labeler.yml
+++ b/.github/workflows/pr-labeler.yml
@@ -29,7 +29,7 @@ jobs:
steps:
- name: Apply Labels Based on PR Description
- uses: github/issue-labeler@v3.1
+ uses: github/issue-labeler@v3.4
with:
configuration-path: .github/workflows/pr-labeler/regex.yml
enable-versioned-regex: 0
diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml
new file mode 100644
index 0000000..e5db19c
--- /dev/null
+++ b/.github/workflows/request-reviews.yml
@@ -0,0 +1,73 @@
+
+# This workflow automatically adds the appropriate reviewers to a pull request.
+#
+# The workflow directly reuses logic in the BaseTools/Scripts/GetMaintainer.py script
+# to determine the appropriate reviewers, so it matches what a user would see running
+# the script locally.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+name: Add Pull Request Reviewers
+
+on:
+ pull_request_target:
+ branches:
+ - master
+ types: [opened, ready_for_review, reopened, synchronize]
+
+env:
+ GET_MAINTAINER_REL_PATH: "BaseTools/Scripts/GetMaintainer.py"
+
+jobs:
+ auto-request-review:
+ name: Add Pull Request Reviewers
+ # Do not run on draft PRs and only run on PRs in the tianocore organization
+ if: ${{ github.event.pull_request.draft == false && github.repository_owner == 'tianocore' }}
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+ issues: write
+ pull-requests: write
+
+ steps:
+ - name: Generate Token
+ id: generate-token
+ uses: actions/create-github-app-token@v1
+ with:
+ app-id: ${{ secrets.TIANOCORE_ASSIGN_REVIEWERS_APPLICATION_ID }}
+ private-key: ${{ secrets.TIANOCORE_ASSIGN_REVIEWERS_APPLICATION_PRIVATE_KEY }}
+
+ # Reduce checkout time with sparse-checkout
+ # - .github: Contains the scripts to interact with Github and add reviewers
+ # - BaseTools/Scripts: Contains the GetMaintainer.py script
+ # - Maintainers.txt: Contains the list of maintainers for the repository
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 1
+ sparse-checkout: |
+ .github
+ BaseTools/Scripts
+ Maintainers.txt
+
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.x'
+ cache: 'pip'
+ cache-dependency-path: '.github/scripts/requirements.txt'
+
+ - name: Install PIP Modules
+ run: pip install -r .github/scripts/requirements.txt --upgrade
+
+ - name: Add Reviewers to Pull Request
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ ORG_NAME: ${{ github.repository_owner }}
+ PR_NUMBER: ${{ github.event.number}}
+ REPO_NAME: ${{ github.event.pull_request.base.repo.name }}
+ TARGET_BRANCH: ${{ github.event.pull_request.base.ref }}
+ WORKSPACE_PATH: ${{ github.workspace }}
+ run: python .github/scripts/RequestPrReviewers.py
diff --git a/.gitignore b/.gitignore
index 1dd30c1..274a66c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ Build/
__pycache__/
tags/
.vscode/
+.venv/
diff --git a/.mergify/config.yml b/.mergify/config.yml
index 3471896..fd77b17 100644
--- a/.mergify/config.yml
+++ b/.mergify/config.yml
@@ -26,9 +26,10 @@
queue_rules:
- name: default
- conditions:
+ queue_conditions:
- base~=(^main|^master|^stable/)
- label=push
+ merge_method: rebase
pull_request_rules:
- name: Automatically merge a PR when all required checks pass and 'push' label is present
@@ -37,7 +38,6 @@ pull_request_rules:
- label=push
actions:
queue:
- method: rebase
name: default
- name: Post a comment on a PR that can not be merged due to a merge conflict
diff --git a/.pytool/CISettings.py b/.pytool/CISettings.py
index 314758d..e14b77d 100644
--- a/.pytool/CISettings.py
+++ b/.pytool/CISettings.py
@@ -37,7 +37,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
self.ActualTargets = []
self.ActualArchitectures = []
self.ActualToolChainTag = ""
- self.UseBuiltInBaseTools = None
self.ActualScopes = None
# ####################################################################################### #
@@ -45,10 +44,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
# ####################################################################################### #
def AddCommandLineOptions(self, parserObj):
- group = parserObj.add_mutually_exclusive_group()
- group.add_argument("-force_piptools", "--fpt", dest="force_piptools", action="store_true", default=False, help="Force the system to use pip tools")
- group.add_argument("-no_piptools", "--npt", dest="no_piptools", action="store_true", default=False, help="Force the system to not use pip tools")
-
try:
codeql_helpers.add_command_line_option(parserObj)
except NameError:
@@ -56,10 +51,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
def RetrieveCommandLineOptions(self, args):
super().RetrieveCommandLineOptions(args)
- if args.force_piptools:
- self.UseBuiltInBaseTools = True
- if args.no_piptools:
- self.UseBuiltInBaseTools = False
try:
self.codeql = codeql_helpers.is_codeql_enabled_on_command_line(args)
@@ -176,24 +167,6 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
self.ActualToolChainTag = shell_environment.GetBuildVars().GetValue("TOOL_CHAIN_TAG", "")
- is_linux = GetHostInfo().os.upper() == "LINUX"
-
- if self.UseBuiltInBaseTools is None:
- is_linux = GetHostInfo().os.upper() == "LINUX"
- # try and import the pip module for basetools
- try:
- import edk2basetools
- self.UseBuiltInBaseTools = True
- except ImportError:
- self.UseBuiltInBaseTools = False
- pass
-
- if self.UseBuiltInBaseTools == True:
- scopes += ('pipbuild-unix',) if is_linux else ('pipbuild-win',)
- logging.warning("Using Pip Tools based BaseTools")
- else:
- logging.warning("Falling back to using in-tree BaseTools")
-
try:
scopes += codeql_helpers.get_scopes(self.codeql)
diff --git a/.pytool/Plugin/DependencyCheck/DependencyCheck.py b/.pytool/Plugin/DependencyCheck/DependencyCheck.py
index 07c5682..30b0c02 100644
--- a/.pytool/Plugin/DependencyCheck/DependencyCheck.py
+++ b/.pytool/Plugin/DependencyCheck/DependencyCheck.py
@@ -108,8 +108,8 @@ class DependencyCheck(ICiBuildPlugin):
if mod_specific_key in pkgconfig and p in pkgconfig[mod_specific_key]:
continue
- logging.error("Dependency Check: Invalid Dependency INF: {0} depends on pkg {1}".format(file, p))
- tc.LogStdError("Dependency Check: Invalid Dependency INF: {0} depends on pkg {1}".format(file, p))
+ logging.error(f"Dependency Check: {file} depends on pkg {p} but pkg is not listed in AcceptableDependencies")
+ tc.LogStdError(f"Dependency Check: {file} depends on pkg {p} but pkg is not listed in AcceptableDependencies")
overall_status += 1
# If XML object exists, add results
diff --git a/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py b/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py
index 351137c..14f9933 100644
--- a/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py
+++ b/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py
@@ -6,9 +6,12 @@
import logging
import os
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
+from edk2toollib.uefi.edk2.path_utilities import Edk2Path
from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser
from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser
from edk2toolext.environment.var_dict import VarDict
+from edk2toollib.gitignore_parser import parse_gitignore_lines
+from pathlib import Path
class DscCompleteCheck(ICiBuildPlugin):
@@ -71,38 +74,39 @@ class DscCompleteCheck(ICiBuildPlugin):
# Get INF Files
INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path)
- INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(
- x) for x in INFFiles] # make edk2relative path so can compare with DSC
# remove ignores
-
+ ignored_paths = []
if "IgnoreInf" in pkgconfig:
- for a in pkgconfig["IgnoreInf"]:
- a = a.replace(os.sep, "/")
+ ignore_filter = parse_gitignore_lines(
+ pkgconfig["IgnoreInf"],
+ "DSC Complete Check Config",
+ os.path.dirname(abs_pkg_path))
+
+ # INFFiles must be a list of absolute paths
+ ignored_paths = list(filter(ignore_filter, INFFiles))
+ for a in ignored_paths:
try:
tc.LogStdOut("Ignoring INF {0}".format(a))
INFFiles.remove(a)
- except:
+ except Exception:
tc.LogStdError(
"DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
logging.info(
"DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
+ # make edk2relative path so can compare with DSC
+ INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(x) for x in INFFiles]
+
# DSC Parser
- dp = DscParser()
- dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath)
- dp.SetPackagePaths(Edk2pathObj.PackagePathList)
+ dp = DscParser().SetEdk2Path(Edk2pathObj)
dp.SetInputVars(environment.GetAllBuildKeyValues())
dp.ParseFile(wsr_dsc_path)
# Check if INF in component section
for INF in INFFiles:
- if not any(INF.strip() in x for x in dp.ThreeMods) and \
- not any(INF.strip() in x for x in dp.SixMods) and \
- not any(INF.strip() in x for x in dp.OtherMods):
-
- infp = InfParser().SetBaseAbsPath(Edk2pathObj.WorkspacePath)
- infp.SetPackagePaths(Edk2pathObj.PackagePathList)
+ if not DscCompleteCheck._module_in_dsc(INF, dp, Edk2pathObj):
+ infp = InfParser().SetEdk2Path(Edk2pathObj)
infp.ParseFile(INF)
if("MODULE_TYPE" not in infp.Dict):
tc.LogStdOut(
@@ -131,3 +135,22 @@ class DscCompleteCheck(ICiBuildPlugin):
else:
tc.SetSuccess()
return overall_status
+
+ @staticmethod
+ def _module_in_dsc(inf: str, dsc: DscParser, Edk2pathObj: Edk2Path) -> bool:
+
+ """Checks if the given module (inf) is in the given dsc.
+ Args:
+ inf (str): The inf file to check for
+ dsc (DscParser): The parsed dsc file.
+ Edk2pathObj (Edk2Path): The path object capturing the workspace and package paths.
+ Returns:
+ bool: if the module is in the dsc.
+ """
+ for module_type in (dsc.ThreeMods, dsc.SixMods, dsc.OtherMods):
+ for module in module_type:
+ if Path(module).is_absolute():
+ module = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(module)
+ if inf in module:
+ return True
+ return False
diff --git a/.pytool/Plugin/DscCompleteCheck/Readme.md b/.pytool/Plugin/DscCompleteCheck/Readme.md
index 8aaa4f7..9f7291b 100644
--- a/.pytool/Plugin/DscCompleteCheck/Readme.md
+++ b/.pytool/Plugin/DscCompleteCheck/Readme.md
@@ -29,4 +29,5 @@ Path to DSC to consider platform dsc
### IgnoreInf
-Ignore error if Inf file is not listed in DSC file
+A list of paths in git ignore syntax to ignore in the check. These can include directory and file paths. The path is
+relative to the directory that contains the package.
diff --git a/.pytool/Plugin/EccCheck/EccCheck.py b/.pytool/Plugin/EccCheck/EccCheck.py
index 7235fcb..0002143 100644
--- a/.pytool/Plugin/EccCheck/EccCheck.py
+++ b/.pytool/Plugin/EccCheck/EccCheck.py
@@ -182,6 +182,11 @@ class EccCheck(ICiBuildPlugin):
#
file_dir = os.path.dirname(file_path[-1])
#
+ # strip the prefix path till the package name
+ #
+ if pkg in file_dir:
+ file_dir = file_dir[file_dir.find(pkg):]
+ #
# Skip directory names that do not start with the package being scanned.
#
if file_dir.split('/')[0] != pkg:
diff --git a/.pytool/Plugin/SpellCheck/SpellCheck.py b/.pytool/Plugin/SpellCheck/SpellCheck.py
index 8347fa9..d540847 100644
--- a/.pytool/Plugin/SpellCheck/SpellCheck.py
+++ b/.pytool/Plugin/SpellCheck/SpellCheck.py
@@ -186,13 +186,14 @@ class SpellCheck(ICiBuildPlugin):
# Helper - Log the syntax needed to add these words to dictionary
if len(EasyFix) > 0:
EasyFix = sorted(set(a.lower() for a in EasyFix))
+ logging.error(f'SpellCheck found {len(EasyFix)} failing words. See CI log for details.')
tc.LogStdOut("\n Easy fix:")
OneString = "If these are not errors add this to your ci.yaml file.\n"
OneString += '"SpellCheck": {\n "ExtendWords": ['
for a in EasyFix:
tc.LogStdOut(f'\n"{a}",')
OneString += f'\n "{a}",'
- logging.info(OneString.rstrip(",") + '\n ]\n}')
+ logging.critical(OneString.rstrip(",") + '\n ]\n}')
# add result to test case
overall_status = len(Errors)
diff --git a/.pytool/Plugin/SpellCheck/cspell.base.yaml b/.pytool/Plugin/SpellCheck/cspell.base.yaml
index 92e65ec..d701c06 100644
--- a/.pytool/Plugin/SpellCheck/cspell.base.yaml
+++ b/.pytool/Plugin/SpellCheck/cspell.base.yaml
@@ -28,269 +28,270 @@
"muchange"
],
"words": [
- "MTRRs",
- "Microarchitecture",
- "Goldmont",
- "cpuid",
- "mwait",
- "cstate",
- "smram",
- "scrtm",
- "smbus",
- "selftest",
- "socket",
- "MMRAM",
- "qword",
- "ENDBR",
- "SMBASE",
- "FXSAVE",
- "FXRSTOR",
- "RDRAND",
- "IOAPIC",
- "ATAPI",
- "movsb",
- "iretw",
- "XENSTORE",
- "cdrom",
- "oprom",
- "oproms",
- "varstore",
- "EKU",
+ "ACPICA",
+ "ACPINVS",
+ "armltd",
"ascii",
- "nmake",
- "NVDIMM",
- "nasmb",
- "Mtftp",
- "Hypercall",
- "hypercalls",
- "IOMMU",
- "QEMU",
- "qemus",
- "OVMF",
- "tiano",
- "tianocore",
- "edkii",
- "coreboot",
- "uefipayload",
+ "ASMLINK",
+ "ATAPI",
+ "autodetect",
+ "autogen",
+ "autoreload",
+ "basetools",
+ "blockio",
+ "bootability",
+ "bootable",
+ "bootflow",
"bootloader",
"bootloaders",
- "mdepkg",
- "skuid",
- "dxefv",
- "toolchain",
- "libraryclass",
- "preboot",
- "pythonpath",
- "cygpath",
- "nuget",
- "basetools",
- "prepi",
- "OPTEE",
- "stringid",
- "peims",
- "memmap",
- "guids",
- "uuids",
- "smbios",
+ "bootup",
+ "bringup",
+ "brotli",
+ "bugbug",
+ "bytecodes",
+ "bytelist",
+ "bytestream",
+ "cacheability",
+ "cachetype",
+ "cdrom",
"certdb",
"certdbv",
- "EfiSigList",
- "depex",
- "IHANDLE",
- "Virtio",
- "Mbytes",
"Citrix",
- "initrd",
- "semihost",
- "Semihosting",
- "Trustzone",
- "Fastboot",
- "framebuffer",
- "genfw",
- "TTYTERM",
- "miniport",
- "LFENCE",
- "PCANSI",
- "submodule",
- "submodules",
- "brotli",
- "PCCTS",
- "softfloat",
- "whitepaper",
- "ACPICA",
- "plugfest",
- "bringup",
- "formset", #VFR
- "ideqvallist",
- "numberof",
- "oneof",
- "endformset",
- "endnumeric",
- "endoneof",
- "disableif",
- "guidid",
+ "CLANGPDB",
"classguid",
+ "cmocka",
+ "conout",
+ "Consplitter", # common module in UEFI
+ "coreboot",
+ "countof",
+ "cpuid",
+ "creatorid",
+ "cstate",
+ "cygpath",
+ "datacache",
+ "deadloop",
+ "depex",
+ "depexes",
+ "deregistering",
+ "devicepath",
+ "devicetree",
+ "devpath",
+ "disableif",
+ "Disasm",
+ "drhds",
+ "dxefv",
+ "dxeipl",
+ "dynamicex",
+ "edkii",
+ "edksetup",
+ "EfiSigList",
"efivarstore",
- "formsetguid",
- "formid",
- "suppressif",
- "grayoutif",
- "ideqval",
- "endform",
+ "EKU",
+ "ENDBR",
"endcheckbox",
- "questionid",
- "questionref",
"enddate",
- "endstring",
- "guidop",
+ "endform",
+ "endformset",
"endguidop",
- "langdef",
- "dynamicex",
- "tokenspace",
- "tokenguid",
- "pcd's", #seems like cspell bug
- "peim's",
- "autogen",
- "Disasm",
- "Torito",
- "SRIOV",
- "MRIOV",
- "UARTs",
- "Consplitter", # common module in UEFI
- "FIFOs",
- "ACPINVS",
+ "endiannness",
+ "endnumeric",
"Endof", # due to of not being uppercase
- "bootability",
- "Sdhci",
+ "endoneof",
+ "endstring",
+ "Fastboot",
+ "FIFOs",
+ "formid",
+ "formsetguid",
+ "formset", #VFR
+ "framebuffer",
+ "fvmain",
+ "fwvol",
+ "FXRSTOR",
+ "FXSAVE",
+ "genfw",
+ "Goldmont",
+ "grayoutif",
+ "guidid",
+ "guidop",
+ "guids",
+ "harddisk",
+ "hisilicon",
+ "hoblist",
+ "hwerrrec",
+ "Hypercall",
+ "hypercalls",
+ "ideqval",
+ "ideqvallist",
+ "IHANDLE",
+ "imagehandle",
+ "initrd",
"inmodule",
- "RISCV",
- "edksetup",
+ "IOAPIC",
+ "IOMMU",
+ "iretw",
"iscsi",
- "nvdata",
- "pytools",
- "NTDDI",
- "Wnonportable",
- "CLANGPDB",
- "nologo",
+ "langcode",
+ "langcodes",
+ "langdef",
+ "lastattemptstatus",
+ "lastattemptversion",
+ "LFENCE",
+ "libraryclass",
+ "littleendian",
"lldmap",
- "ASMLINK",
- "NODEFAULTLIB",
- "vcruntimed",
- "ucrtd",
+ "lockv",
+ "LOONGARCH",
+ "Loongson",
+ "lowestsupportedversion",
+ "mainpage",
+ "Mbytes",
+ "mdepkg",
+ "memmap",
+ "Microarchitecture",
+ "miniport",
+ "mismanipulation",
+ "MMRAM",
+ "movsb",
+ "MPIDR",
+ "MRIOV",
"msvcrtd",
- "XIPFLAGS",
- "bootflow",
- "bootup",
- "cacheability",
- "cachetype",
- "conout",
- "deadloop",
- "devicepath",
- "hisilicon",
- "littleendian",
+ "Mtftp",
+ "mtrrcap",
+ "MTRRs",
+ "multiboot",
+ "mwait",
+ "nasmb",
+ "nmake",
+ "NODEFAULTLIB",
+ "nofailure",
+ "nologo",
"nonsecure",
+ "NTDDI",
+ "ntxml",
+ "ntxmlcomparestrings",
+ "ntxmlfetchcharacterdecoder",
+ "ntxmlrawnextcharacter",
+ "ntxmlspecialstringcompare",
+ "ntxmltransformcharacter",
+ "nuget",
+ "numberof",
+ "nvdata",
+ "NVDIMM",
+ "okcancel",
+ "oneof",
+ "oprom",
+ "oproms",
+ "OPTEE",
+ "osruntime",
+ "OVMF",
"pagetable",
+ "PCANSI",
+ "PCCTS",
+ "pcd's", #seems like cspell bug
+ "pcencoder",
+ "pclutf",
+ "pcunicode",
+ "pcvoid",
+ "pcxml",
+ "pcxmldoc",
+ "pcxmlstructure",
+ "pecoff",
+ "peim's",
+ "peims",
+ "plugfest",
"postmem",
+ "preboot",
+ "prefetchable",
"premem",
+ "prepi",
+ "pxmldoc",
+ "pxmlstructure",
+ "pythonpath",
+ "pytool",
+ "pytools",
+ "QEMU",
+ "qemus",
+ "qrencoder",
+ "qrencoding",
+ "qrlevel",
+ "questionid",
+ "questionref",
+ "qword",
+ "ramdisk",
+ "RDRAND",
+ "readytoboot",
"reglist",
+ "reprompt",
+ "RISCV",
+ "rmrrs",
+ "rtlxmlcallback",
+ "schedulable",
+ "scrtm",
+ "Sdhci",
+ "selawik",
+ "selftest",
"semihalf",
- "subvendor",
+ "semihost",
+ "Semihosting",
+ "setjump",
+ "shiftn",
+ "skuid",
+ "SMBASE",
+ "smbios",
+ "smbus",
+ "smram",
+ "socket",
+ "softfloat",
+ "SRIOV",
+ "StandaloneMMCore",
+ "stringid",
"subhierarchy",
+ "submodule",
+ "submodules",
+ "subvendor",
+ "suppressif",
+ "swmdialogs",
+ "systemtable",
"targetlist",
+ "testcase",
+ "testsuites",
+ "tiano",
+ "tianocore",
"tmpname",
- "watchdogtimer",
- "writeback",
- "langcode",
- "langcodes",
- "autoreload",
- "bootable",
- "endiannness",
- "fvmain",
- "prefetchable",
- "multiboot",
- "ramdisk",
- "unbootable",
- "setjump",
- "bytecodes",
- "bytelist",
- "bytestream",
- "countof",
- "deregistering",
- "devicetree",
- "mainpage",
- "mismanipulation",
- "pytool",
- "wbinvd",
- "armltd",
- "datacache",
- "lastattemptstatus",
- "lastattemptversion",
- "lowestsupportedversion",
- "updateable",
- "pecoff",
- "autodetect",
- "harddisk",
"toctou",
- "bugbug",
- "depexes",
- "fwvol",
- "hoblist",
- "imagehandle",
- "schedulable",
- "StandaloneMMCore",
- "systemtable",
+ "tokenguid",
+ "tokenspace",
+ "toolchain",
+ "Torito",
+ "Trustzone",
+ "TTYTERM",
+ "UARTs",
+ "ucrtd",
+ "uefipayload",
+ "uefishelldebug",
+ "unbootable",
"uncacheable",
- "devpath",
- "testsuites",
- "testcase",
- "pxmldoc",
- "pcxml",
- "pclutf",
- "pcunicode",
- "ntxmltransformcharacter",
- "ntxmlcomparestrings",
- "pcxmldoc",
- "ntxmlfetchcharacterdecoder",
- "ntxml",
- "ntxmlspecialstringcompare",
- "rtlxmlcallback",
- "xmlef",
- "osruntime",
- "readytoboot",
- "hwerrrec",
- "xformed",
- "xform",
+ "unconfigure",
"undock",
- "qrencoder",
- "selawik",
- "ntxmlrawnextcharacter",
"undocked",
- "reprompt",
- "yesno",
- "okcancel",
- "qrencoding",
- "qrlevel",
- "shiftn",
"unenroll",
- "pcxmlstructure",
- "pxmlstructure",
- "pcencoder",
- "pcvoid",
- "nofailure",
- "blockio",
- "lockv",
- "uefishelldebug",
- "mtrrcap",
- "drhds",
- "rmrrs",
- "creatorid",
- "dxeipl",
- "swmdialogs",
- "unrecovered",
- "cmocka",
"unenrolling",
- "unconfigure",
- "Loongson",
- "LOONGARCH"
+ "unrecovered",
+ "updateable",
+ "uuids",
+ "varstore",
+ "vcruntimed",
+ "Virtio",
+ "watchdogtimer",
+ "wbinvd",
+ "whitepaper",
+ "Wnonportable",
+ "writeback",
+ "XENSTORE",
+ "xform",
+ "xformed",
+ "XIPFLAGS",
+ "xmlef",
+ "yesno"
]
}
diff --git a/.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py b/.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py
index 73dc03c..0f59398 100644
--- a/.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py
+++ b/.pytool/Plugin/UncrustifyCheck/UncrustifyCheck.py
@@ -373,9 +373,9 @@ class UncrustifyCheck(ICiBuildPlugin):
file_template_path = pathlib.Path(os.path.join(self._plugin_path, file_template_name))
self._file_template_contents = file_template_path.read_text()
except KeyError:
- logging.warning("A file header template is not specified in the config file.")
+ logging.info("A file header template is not specified in the config file.")
except FileNotFoundError:
- logging.warning("The specified file header template file was not found.")
+ logging.info("The specified file header template file was not found.")
try:
func_template_name = parser["dummy_section"]["cmt_insert_func_header"]
@@ -385,9 +385,9 @@ class UncrustifyCheck(ICiBuildPlugin):
func_template_path = pathlib.Path(os.path.join(self._plugin_path, func_template_name))
self._func_template_contents = func_template_path.read_text()
except KeyError:
- logging.warning("A function header template is not specified in the config file.")
+ logging.info("A function header template is not specified in the config file.")
except FileNotFoundError:
- logging.warning("The specified function header template file was not found.")
+ logging.info("The specified function header template file was not found.")
def _initialize_app_info(self) -> None:
"""
@@ -563,36 +563,37 @@ class UncrustifyCheck(ICiBuildPlugin):
self._formatted_file_error_count = len(formatted_files)
if self._formatted_file_error_count > 0:
- logging.error(
+ logging.error(f'Uncrustify found {self._formatted_file_error_count} files with formatting errors\n')
+ self._tc.LogStdError(f"Uncrustify found {self._formatted_file_error_count} files with formatting errors:\n")
+ logging.warning(
"Visit the following instructions to learn "
- "how to find the detailed formatting errors in Azure "
- "DevOps CI: "
- "https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Code-Formatting#how-to-find-uncrustify-formatting-errors-in-continuous-integration-ci")
- self._tc.LogStdError("Files with formatting errors:\n")
+ "more about uncrustify setup instructions and CI:"
+ "https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Code-Formatting\n")
if self._output_file_diffs:
logging.info("Calculating file diffs. This might take a while...")
for formatted_file in formatted_files:
- pre_formatted_file = formatted_file[:-
- len(UncrustifyCheck.FORMATTED_FILE_EXTENSION)]
- logging.error(pre_formatted_file)
+ pre_formatted_file = formatted_file[:-len(UncrustifyCheck.FORMATTED_FILE_EXTENSION)]
+
+ logging.error(f"Formatting errors in {os.path.relpath(pre_formatted_file, self._abs_package_path)}")
+ self._tc.LogStdError(f"Formatting errors in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")
if (self._output_file_diffs or
self._file_template_contents is not None or
self._func_template_contents is not None):
- self._tc.LogStdError(
- f"Formatting errors in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")
with open(formatted_file) as ff:
formatted_file_text = ff.read()
if (self._file_template_contents is not None and
self._file_template_contents in formatted_file_text):
+ logging.info(f"File header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}")
self._tc.LogStdError(f"File header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")
if (self._func_template_contents is not None and
self._func_template_contents in formatted_file_text):
+ logging.info(f"A function header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}")
self._tc.LogStdError(f"A function header is missing in {os.path.relpath(pre_formatted_file, self._abs_package_path)}\n")
if self._output_file_diffs:
@@ -600,11 +601,11 @@ class UncrustifyCheck(ICiBuildPlugin):
pre_formatted_file_text = pf.read()
for line in difflib.unified_diff(pre_formatted_file_text.split('\n'), formatted_file_text.split('\n'), fromfile=pre_formatted_file, tofile=formatted_file, n=3):
+ logging.error(line)
self._tc.LogStdError(line)
+ logging.error('\n')
self._tc.LogStdError('\n')
- else:
- self._tc.LogStdError(pre_formatted_file)
def _remove_tree(self, dir_path: str, ignore_errors: bool = False) -> None:
"""
diff --git a/ArmPkg/ArmPkg.ci.yaml b/ArmPkg/ArmPkg.ci.yaml
index d312481..5c2e68b 100644
--- a/ArmPkg/ArmPkg.ci.yaml
+++ b/ArmPkg/ArmPkg.ci.yaml
@@ -5,6 +5,9 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "ArmPkg.dsc",
+ },
## options defined .pytool/Plugin/LicenseCheck
"LicenseCheck": {
"IgnoreFiles": []
@@ -239,10 +242,5 @@
],
"AdditionalIncludePaths": [] # Additional paths to spell check
# (wildcards supported)
- },
-
- # options defined in .pytool/Plugin/UncrustifyCheck
- "UncrustifyCheck": {
- "AuditOnly": True
}
}
diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index c086114..49cbffa 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -135,11 +135,6 @@
# Define if the GICv3 controller should use the GICv2 legacy
gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042
- ## Define the conduit to use for monitor calls.
- # Default PcdMonitorConduitHvc = FALSE, conduit = SMC
- # If PcdMonitorConduitHvc = TRUE, conduit = HVC
- gArmTokenSpaceGuid.PcdMonitorConduitHvc|FALSE|BOOLEAN|0x00000047
-
# Whether to remap all unused memory NX before installing the CPU arch
# protocol driver. This is needed on platforms that map all DRAM with RWX
# attributes initially, and can be disabled otherwise.
@@ -229,6 +224,11 @@
#
gArmTokenSpaceGuid.PcdUefiShellDefaultBootEnable|FALSE|BOOLEAN|0x0000052
+ ## Define the conduit to use for monitor calls.
+ # Default PcdMonitorConduitHvc = FALSE, conduit = SMC
+ # If PcdMonitorConduitHvc = TRUE, conduit = HVC
+ gArmTokenSpaceGuid.PcdMonitorConduitHvc|FALSE|BOOLEAN|0x00000047
+
[PcdsFixedAtBuild.common, PcdsPatchableInModule.common]
gArmTokenSpaceGuid.PcdFdBaseAddress|0|UINT64|0x0000002B
gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT64|0x0000002D
diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc
index 6dd91e6..25d750e 100644
--- a/ArmPkg/ArmPkg.dsc
+++ b/ArmPkg/ArmPkg.dsc
@@ -78,8 +78,6 @@
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
- FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
-
ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
@@ -93,6 +91,10 @@
OemMiscLib|ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf
+[LibraryClasses.common.SEC]
+ # ARM platforms have SEC modules with standard entry points, so we can generically link StackCheckLib
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.PEIM]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
@@ -100,23 +102,16 @@
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
-[LibraryClasses.ARM, LibraryClasses.AARCH64]
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- # Add support for GCC stack protector
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
[Components.common]
ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
- ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+ ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf
ArmPkg/Library/SemihostLib/SemihostLib.inf
- ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
ArmPkg/Library/ArmExceptionLib/ArmRelocateExceptionLib.inf
@@ -150,12 +145,10 @@
ArmPkg/Library/ArmLib/ArmBaseLib.inf
ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf
ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
- ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
ArmPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
- ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf
ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf
ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
@@ -165,6 +158,7 @@
ArmPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
[Components.AARCH64]
+ ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf
ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.inf
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
diff --git a/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc b/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc
index 2818ce6..28ebe68 100644
--- a/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc
+++ b/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc
@@ -43,8 +43,5 @@
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
[Components.common]
ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf
diff --git a/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S b/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S
index 7316502..504f026 100644
--- a/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S
+++ b/ArmPkg/Drivers/ArmGic/GicV3/AArch64/ArmGicV3.S
@@ -5,7 +5,7 @@
#
#
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
#if !defined(__clang__)
diff --git a/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S b/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S
index 8c43a61..33c0a58 100644
--- a/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S
+++ b/ArmPkg/Drivers/ArmGic/GicV3/Arm/ArmGicV3.S
@@ -5,7 +5,7 @@
#
#
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
#include <Library/ArmLib.h>
// For the moment we assume this will run in SVC mode on ARMv7
diff --git a/ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.c b/ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.c
index e7f4223..6d075df 100644
--- a/ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.c
+++ b/ArmPkg/Drivers/ArmPsciMpServicesDxe/ArmPsciMpServicesDxe.c
@@ -340,7 +340,7 @@ GetProcessorInfo (
CopyMem (
ProcessorInfoBuffer,
- &mCpuMpData.CpuData[ProcessorIndex],
+ &mCpuMpData.CpuData[ProcessorIndex].Info,
sizeof (EFI_PROCESSOR_INFORMATION)
);
return EFI_SUCCESS;
diff --git a/ArmPkg/Drivers/ArmPsciMpServicesDxe/MpFuncs.S b/ArmPkg/Drivers/ArmPsciMpServicesDxe/MpFuncs.S
index f73edc1..7a52a40 100644
--- a/ArmPkg/Drivers/ArmPsciMpServicesDxe/MpFuncs.S
+++ b/ArmPkg/Drivers/ArmPsciMpServicesDxe/MpFuncs.S
@@ -7,7 +7,7 @@
.text
.align 3
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
#include <IndustryStandard/ArmStdSmc.h>
#include <Library/ArmLib.h>
diff --git a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c b/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c
index 2d60c7d..dbe71e4 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c
+++ b/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c
@@ -90,6 +90,7 @@ SetGcdMemorySpaceAttributes (
UINTN EndIndex;
EFI_PHYSICAL_ADDRESS RegionStart;
UINT64 RegionLength;
+ UINT64 Capabilities;
DEBUG ((
DEBUG_GCD,
@@ -146,14 +147,56 @@ SetGcdMemorySpaceAttributes (
RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;
}
+ // Always add RO, RP, and XP, as all memory is capable of supporting these types (they are software constructs,
+ // not hardware features) and they are critical to maintaining a security boundary.
+ Capabilities = MemorySpaceMap[Index].Capabilities | EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP;
+
+ // Update GCD capabilities as these may have changed in the page table from the original GCD setting
+ // this follows the same pattern as x86 GCD and Page Table syncing
+ Status = gDS->SetMemorySpaceCapabilities (
+ RegionStart,
+ RegionLength,
+ Capabilities
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a - failed to update GCD capabilities: 0x%llx on memory region: 0x%llx length: 0x%llx Status: %r\n",
+ __func__,
+ Capabilities,
+ RegionStart,
+ RegionLength,
+ Status
+ ));
+
+ // If we fail to set capabilities, we should assert as this is a GCD internal error, but follow the previous
+ // behavior and try to set the attributes (which may or may not fail)
+ ASSERT_EFI_ERROR (Status);
+ }
+
//
- // Set memory attributes according to MTRR attribute and the original attribute of descriptor
+ // Set memory attributes according to page table attributes and the original attributes of descriptor
//
- gDS->SetMemorySpaceAttributes (
- RegionStart,
- RegionLength,
- (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)
- );
+ Status = gDS->SetMemorySpaceAttributes (
+ RegionStart,
+ RegionLength,
+ (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (Attributes & Capabilities)
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a - failed to update GCD attributes: 0x%llx on memory region: 0x%llx length: 0x%llx Status: %r\n",
+ __func__,
+ Attributes,
+ RegionStart,
+ RegionLength,
+ Status
+ ));
+
+ ASSERT_EFI_ERROR (Status);
+ }
}
return EFI_SUCCESS;
diff --git a/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c b/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c
index 16cc4ef..c77feb8 100644
--- a/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c
+++ b/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c
@@ -82,6 +82,13 @@ GetMemoryAttributes (
EFI_STATUS Status;
if ((Length == 0) || (Attributes == NULL)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: BaseAddress 0x%llx Length 0x%llx is zero or Attributes is NULL\n",
+ __func__,
+ BaseAddress,
+ Length
+ ));
return EFI_INVALID_PARAMETER;
}
@@ -195,6 +202,13 @@ SetMemoryAttributes (
if ((Length == 0) ||
((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0))
{
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: BaseAddress 0x%llx Length is zero or Attributes (0x%llx) is invalid\n",
+ __func__,
+ BaseAddress,
+ Attributes
+ ));
return EFI_INVALID_PARAMETER;
}
@@ -256,6 +270,13 @@ ClearMemoryAttributes (
if ((Length == 0) ||
((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0))
{
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: BaseAddress 0x%llx Length is zero or Attributes (0x%llx) is invalid\n",
+ __func__,
+ BaseAddress,
+ Attributes
+ ));
return EFI_INVALID_PARAMETER;
}
diff --git a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
index 5bff073..b91e62e 100644
--- a/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
+++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
@@ -391,6 +391,8 @@ GenericWatchdogEntry (
goto UnregisterHandler;
}
+ WatchdogDisable ();
+
// Install the Timer Architectural Protocol onto a new handle
Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
@@ -413,8 +415,6 @@ GenericWatchdogEntry (
);
ASSERT_EFI_ERROR (Status);
- WatchdogDisable ();
-
return EFI_SUCCESS;
UnregisterHandler:
diff --git a/ArmPkg/Include/AsmMacroIoLib.inc b/ArmPkg/Include/AsmMacroIoLib.inc
deleted file mode 100644
index 66b8d3d..0000000
--- a/ArmPkg/Include/AsmMacroIoLib.inc
+++ /dev/null
@@ -1,33 +0,0 @@
-;%HEADER%
-;/** @file
-; Macros to work around lack of Apple support for LDR register, =expr
-;
-; Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
-; Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
-;
-; SPDX-License-Identifier: BSD-2-Clause-Patent
-;
-;**/
-
-
- MACRO
- adrll $Reg, $Symbol
- add $Reg, pc, #-8
- RELOC R_ARM_ALU_PC_G0_NC, $Symbol
- add $Reg, $Reg, #-4
- RELOC R_ARM_ALU_PC_G1_NC, $Symbol
- add $Reg, $Reg, #0
- RELOC R_ARM_ALU_PC_G2, $Symbol
- MEND
-
- MACRO
- ldrl $Reg, $Symbol
- add $Reg, pc, #-8
- RELOC R_ARM_ALU_PC_G0_NC, $Symbol
- add $Reg, $Reg, #-4
- RELOC R_ARM_ALU_PC_G1_NC, $Symbol
- ldr $Reg, [$Reg, #0]
- RELOC R_ARM_LDR_PC_G2, $Symbol
- MEND
-
- END
diff --git a/ArmPkg/Include/Library/ArmMonitorLib.h b/ArmPkg/Include/Library/ArmMonitorLib.h
index d6e13b6..1192ee2 100644
--- a/ArmPkg/Include/Library/ArmMonitorLib.h
+++ b/ArmPkg/Include/Library/ArmMonitorLib.h
@@ -23,6 +23,18 @@ typedef struct {
UINTN Arg5;
UINTN Arg6;
UINTN Arg7;
+ #ifdef MDE_CPU_AARCH64
+ UINTN Arg8;
+ UINTN Arg9;
+ UINTN Arg10;
+ UINTN Arg11;
+ UINTN Arg12;
+ UINTN Arg13;
+ UINTN Arg14;
+ UINTN Arg15;
+ UINTN Arg16;
+ UINTN Arg17;
+ #endif
} ARM_MONITOR_ARGS;
/** Monitor call.
diff --git a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c
index ccb4f64..cc1be01 100644
--- a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c
+++ b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c
@@ -24,30 +24,6 @@
#define MULT_U64_X_N MultU64x64
#endif
-RETURN_STATUS
-EFIAPI
-TimerConstructor (
- VOID
- )
-{
- //
- // Check if the ARM Generic Timer Extension is implemented.
- //
- if (ArmIsArchTimerImplemented ()) {
- //
- // Architectural Timer Frequency must be set in Secure privileged
- // mode (if secure extension is supported).
- // If the reset value (0) is returned, just ASSERT.
- //
- ASSERT (ArmGenericTimerGetTimerFreq () != 0);
- } else {
- DEBUG ((DEBUG_ERROR, "ARM Architectural Timer is not available in the CPU, hence this library cannot be used.\n"));
- ASSERT (0);
- }
-
- return RETURN_SUCCESS;
-}
-
/**
A local utility function that returns the PCD value, if specified.
Otherwise it defaults to ArmGenericTimerGetTimerFreq.
@@ -65,6 +41,8 @@ GetPlatformTimerFreq (
TimerFreq = ArmGenericTimerGetTimerFreq ();
+ ASSERT (TimerFreq != 0);
+
return TimerFreq;
}
@@ -84,6 +62,8 @@ MicroSecondDelay (
{
UINT64 TimerTicks64;
UINT64 SystemCounterVal;
+ UINT64 PreviousSystemCounterVal;
+ UINT64 DeltaCounterVal;
// Calculate counter ticks that represent requested delay:
// = MicroSeconds x TICKS_PER_MICRO_SEC
@@ -97,13 +77,17 @@ MicroSecondDelay (
);
// Read System Counter value
- SystemCounterVal = ArmGenericTimerGetSystemCount ();
-
- TimerTicks64 += SystemCounterVal;
+ PreviousSystemCounterVal = ArmGenericTimerGetSystemCount ();
// Wait until delay count expires.
- while (SystemCounterVal < TimerTicks64) {
+ while (TimerTicks64 > 0) {
SystemCounterVal = ArmGenericTimerGetSystemCount ();
+ // Get how much we advanced this tick. Wrap around still has delta correct
+ DeltaCounterVal = (SystemCounterVal - PreviousSystemCounterVal)
+ & (MAX_UINT64 >> 8); // Account for a lesser (minimum) size
+ // Never wrap back around below zero by choosing the min and thus stop at 0
+ TimerTicks64 -= MIN (TimerTicks64, DeltaCounterVal);
+ PreviousSystemCounterVal = SystemCounterVal;
}
return MicroSeconds;
diff --git a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
index 273b1e9..76bad81 100644
--- a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+++ b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
@@ -12,7 +12,6 @@
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = TimerLib
- CONSTRUCTOR = TimerConstructor
[Sources.common]
ArmArchTimerLib.c
diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S
index de9d331..5dc6899 100644
--- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S
+++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S
@@ -9,7 +9,7 @@
#include <AArch64/AArch64.h>
#include <Library/PcdLib.h>
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
#include <Protocol/DebugSupport.h> // for exception type definitions
/*
diff --git a/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S
index 39d956a..57c2d75 100644
--- a/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S
+++ b/ArmPkg/Library/ArmHvcLib/AArch64/ArmHvc.S
@@ -6,7 +6,7 @@
//
//
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
ASM_FUNC(ArmCallHvc)
// Push x0 on the stack - The stack must always be quad-word aligned
diff --git a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S
index 0a5a959..9676529 100644
--- a/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S
+++ b/ArmPkg/Library/ArmHvcLib/Arm/ArmHvc.S
@@ -6,7 +6,7 @@
//
//
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
.arch_extension virt
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S b/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S
index 574e0d5..be6f073 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64ArchTimerSupport.S
@@ -7,7 +7,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
ASM_FUNC(ArmReadCntFrq)
mrs x0, cntfrq_el0 // Read CNTFRQ
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
index 6739f5c..53b202f 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c
@@ -18,61 +18,6 @@
#include "AArch64Lib.h"
#include "ArmLibPrivate.h"
-VOID
-AArch64DataCacheOperation (
- IN AARCH64_CACHE_OPERATION DataCacheOperation
- )
-{
- UINTN SavedInterruptState;
-
- SavedInterruptState = ArmGetInterruptState ();
- ArmDisableInterrupts ();
-
- AArch64AllDataCachesOperation (DataCacheOperation);
-
- ArmDataSynchronizationBarrier ();
-
- if (SavedInterruptState) {
- ArmEnableInterrupts ();
- }
-}
-
-VOID
-EFIAPI
-ArmInvalidateDataCache (
- VOID
- )
-{
- ASSERT (!ArmMmuEnabled ());
-
- ArmDataSynchronizationBarrier ();
- AArch64DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
-}
-
-VOID
-EFIAPI
-ArmCleanInvalidateDataCache (
- VOID
- )
-{
- ASSERT (!ArmMmuEnabled ());
-
- ArmDataSynchronizationBarrier ();
- AArch64DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
-}
-
-VOID
-EFIAPI
-ArmCleanDataCache (
- VOID
- )
-{
- ASSERT (!ArmMmuEnabled ());
-
- ArmDataSynchronizationBarrier ();
- AArch64DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
-}
-
/**
Check whether the CPU supports the GIC system register interface (any version)
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
index 6380a01..7127a76 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h
@@ -11,33 +11,6 @@
#ifndef AARCH64_LIB_H_
#define AARCH64_LIB_H_
-typedef VOID (*AARCH64_CACHE_OPERATION)(
- UINTN
- );
-
-VOID
-AArch64AllDataCachesOperation (
- IN AARCH64_CACHE_OPERATION DataCacheOperation
- );
-
-VOID
-EFIAPI
-ArmInvalidateDataCacheEntryBySetWay (
- IN UINTN SetWayFormat
- );
-
-VOID
-EFIAPI
-ArmCleanDataCacheEntryBySetWay (
- IN UINTN SetWayFormat
- );
-
-VOID
-EFIAPI
-ArmCleanInvalidateDataCacheEntryBySetWay (
- IN UINTN SetWayFormat
- );
-
UINTN
EFIAPI
ArmReadIdAA64Dfr0 (
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
index 1ec868e..66daa27 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S
@@ -10,7 +10,7 @@
#------------------------------------------------------------------------------
#include <AArch64/AArch64.h>
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
.set CTRL_M_BIT, (1 << 0)
.set CTRL_A_BIT, (1 << 1)
@@ -43,22 +43,6 @@ ASM_FUNC(ArmCleanInvalidateDataCacheEntryByMVA)
dc civac, x0 // Clean and invalidate single data cache line
ret
-
-ASM_FUNC(ArmInvalidateDataCacheEntryBySetWay)
- dc isw, x0 // Invalidate this line
- ret
-
-
-ASM_FUNC(ArmCleanInvalidateDataCacheEntryBySetWay)
- dc cisw, x0 // Clean and Invalidate this line
- ret
-
-
-ASM_FUNC(ArmCleanDataCacheEntryBySetWay)
- dc csw, x0 // Clean this line
- ret
-
-
ASM_FUNC(ArmInvalidateInstructionCache)
ic iallu // Invalidate entire instruction cache
dsb sy
@@ -257,65 +241,6 @@ ASM_FUNC(ArmDisableBranchPrediction)
ret
-ASM_FUNC(AArch64AllDataCachesOperation)
-// We can use regs 0-7 and 9-15 without having to save/restore.
-// Save our link register on the stack. - The stack must always be quad-word aligned
- stp x29, x30, [sp, #-16]!
- mov x29, sp
- mov x1, x0 // Save Function call in x1
- mrs x6, clidr_el1 // Read EL1 CLIDR
- and x3, x6, #0x7000000 // Mask out all but Level of Coherency (LoC)
- lsr x3, x3, #23 // Left align cache level value - the level is shifted by 1 to the
- // right to ease the access to CSSELR and the Set/Way operation.
- cbz x3, L_Finished // No need to clean if LoC is 0
- mov x10, #0 // Start clean at cache level 0
-
-Loop1:
- add x2, x10, x10, lsr #1 // Work out 3x cachelevel for cache info
- lsr x12, x6, x2 // bottom 3 bits are the Cache type for this level
- and x12, x12, #7 // get those 3 bits alone
- cmp x12, #2 // what cache at this level?
- b.lt L_Skip // no cache or only instruction cache at this level
- msr csselr_el1, x10 // write the Cache Size selection register with current level (CSSELR)
- isb // isb to sync the change to the CacheSizeID reg
- mrs x12, ccsidr_el1 // reads current Cache Size ID register (CCSIDR)
- and x2, x12, #0x7 // extract the line length field
- add x2, x2, #4 // add 4 for the line length offset (log2 16 bytes)
- mov x4, #0x400
- sub x4, x4, #1
- and x4, x4, x12, lsr #3 // x4 is the max number on the way size (right aligned)
- clz w5, w4 // w5 is the bit position of the way size increment
- mov x7, #0x00008000
- sub x7, x7, #1
- and x7, x7, x12, lsr #13 // x7 is the max number of the index size (right aligned)
-
-Loop2:
- mov x9, x4 // x9 working copy of the max way size (right aligned)
-
-Loop3:
- lsl x11, x9, x5
- orr x0, x10, x11 // factor in the way number and cache number
- lsl x11, x7, x2
- orr x0, x0, x11 // factor in the index number
-
- blr x1 // Goto requested cache operation
-
- subs x9, x9, #1 // decrement the way number
- b.ge Loop3
- subs x7, x7, #1 // decrement the index
- b.ge Loop2
-L_Skip:
- add x10, x10, #2 // increment the cache number
- cmp x3, x10
- b.gt Loop1
-
-L_Finished:
- dsb sy
- isb
- ldp x29, x30, [sp], #0x10
- ret
-
-
ASM_FUNC(ArmDataMemoryBarrier)
dmb sy
ret
diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S
index ec34200..d357307 100644
--- a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S
+++ b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S
@@ -8,7 +8,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
.set DAIF_RD_FIQ_BIT, (1 << 6)
.set DAIF_RD_IRQ_BIT, (1 << 7)
diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
index 0ae75e4..1459805 100644
--- a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
+++ b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupportV8.S
@@ -8,7 +8,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
.set MPIDR_U_BIT, (30)
.set MPIDR_U_MASK, (1 << MPIDR_U_BIT)
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S
index 7e032dd..86635cc 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S
+++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S
@@ -8,7 +8,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(ArmReadMidr)
mrc p15,0,R0,c0,c0,0
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
index d843f91..d207876 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
+++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S
@@ -8,7 +8,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(ArmIsMpCore)
mrc p15,0,R0,c0,c0,5
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S b/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S
index 7abaa79..2ad9b48 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7ArchTimerSupport.S
@@ -7,7 +7,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(ArmReadCntFrq)
mrc p15, 0, r0, c14, c0, 0 @ Read CNTFRQ
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
index 6acc4d3..dd1e8c5 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c
@@ -18,61 +18,6 @@
#include "ArmV7Lib.h"
#include "ArmLibPrivate.h"
-VOID
-ArmV7DataCacheOperation (
- IN ARM_V7_CACHE_OPERATION DataCacheOperation
- )
-{
- UINTN SavedInterruptState;
-
- SavedInterruptState = ArmGetInterruptState ();
- ArmDisableInterrupts ();
-
- ArmV7AllDataCachesOperation (DataCacheOperation);
-
- ArmDataSynchronizationBarrier ();
-
- if (SavedInterruptState) {
- ArmEnableInterrupts ();
- }
-}
-
-VOID
-EFIAPI
-ArmInvalidateDataCache (
- VOID
- )
-{
- ASSERT (!ArmMmuEnabled ());
-
- ArmDataSynchronizationBarrier ();
- ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
-}
-
-VOID
-EFIAPI
-ArmCleanInvalidateDataCache (
- VOID
- )
-{
- ASSERT (!ArmMmuEnabled ());
-
- ArmDataSynchronizationBarrier ();
- ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
-}
-
-VOID
-EFIAPI
-ArmCleanDataCache (
- VOID
- )
-{
- ASSERT (!ArmMmuEnabled ());
-
- ArmDataSynchronizationBarrier ();
- ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
-}
-
/**
Check whether the CPU supports the GIC system register interface (any version)
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h
index 404ff92..548be5c 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h
@@ -23,33 +23,6 @@
#define ID_MMFR0_SHR_IMP_HW_COHERENT 1
#define ID_MMFR0_SHR_IGNORED 0xf
-typedef VOID (*ARM_V7_CACHE_OPERATION)(
- UINT32
- );
-
-VOID
-ArmV7AllDataCachesOperation (
- IN ARM_V7_CACHE_OPERATION DataCacheOperation
- );
-
-VOID
-EFIAPI
-ArmInvalidateDataCacheEntryBySetWay (
- IN UINTN SetWayFormat
- );
-
-VOID
-EFIAPI
-ArmCleanDataCacheEntryBySetWay (
- IN UINTN SetWayFormat
- );
-
-VOID
-EFIAPI
-ArmCleanInvalidateDataCacheEntryBySetWay (
- IN UINTN SetWayFormat
- );
-
/** Reads the ID_MMFR4 register.
@return The contents of the ID_MMFR4 register.
diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S b/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S
index 1f396ad..0bfb5f1 100644
--- a/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S
+++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Support.S
@@ -8,7 +8,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
.set DC_ON, (0x1<<2)
.set IC_ON, (0x1<<12)
@@ -42,20 +42,6 @@ ASM_FUNC(ArmCleanInvalidateDataCacheEntryByMVA)
bx lr
-ASM_FUNC(ArmInvalidateDataCacheEntryBySetWay)
- mcr p15, 0, r0, c7, c6, 2 @ Invalidate this line
- bx lr
-
-
-ASM_FUNC(ArmCleanInvalidateDataCacheEntryBySetWay)
- mcr p15, 0, r0, c7, c14, 2 @ Clean and Invalidate this line
- bx lr
-
-
-ASM_FUNC(ArmCleanDataCacheEntryBySetWay)
- mcr p15, 0, r0, c7, c10, 2 @ Clean this line
- bx lr
-
ASM_FUNC(ArmInvalidateInstructionCache)
mcr p15,0,R0,c7,c5,0 @Invalidate entire instruction cache
dsb
@@ -171,59 +157,6 @@ ASM_FUNC(ArmSetHighVectors)
isb
bx LR
-ASM_FUNC(ArmV7AllDataCachesOperation)
- stmfd SP!,{r4-r12, LR}
- mov R1, R0 @ Save Function call in R1
- mrc p15, 1, R6, c0, c0, 1 @ Read CLIDR
- ands R3, R6, #0x7000000 @ Mask out all but Level of Coherency (LoC)
- mov R3, R3, LSR #23 @ Cache level value (naturally aligned)
- beq L_Finished
- mov R10, #0
-
-Loop1:
- add R2, R10, R10, LSR #1 @ Work out 3xcachelevel
- mov R12, R6, LSR R2 @ bottom 3 bits are the Cache type for this level
- and R12, R12, #7 @ get those 3 bits alone
- cmp R12, #2
- blt L_Skip @ no cache or only instruction cache at this level
- mcr p15, 2, R10, c0, c0, 0 @ write the Cache Size selection register (CSSELR) // OR in 1 for Instruction
- isb @ isb to sync the change to the CacheSizeID reg
- mrc p15, 1, R12, c0, c0, 0 @ reads current Cache Size ID register (CCSIDR)
- and R2, R12, #0x7 @ extract the line length field
- add R2, R2, #4 @ add 4 for the line length offset (log2 16 bytes)
-@ ldr R4, =0x3FF
- mov R4, #0x400
- sub R4, R4, #1
- ands R4, R4, R12, LSR #3 @ R4 is the max number on the way size (right aligned)
- clz R5, R4 @ R5 is the bit position of the way size increment
-@ ldr R7, =0x00007FFF
- mov R7, #0x00008000
- sub R7, R7, #1
- ands R7, R7, R12, LSR #13 @ R7 is the max number of the index size (right aligned)
-
-Loop2:
- mov R9, R4 @ R9 working copy of the max way size (right aligned)
-
-Loop3:
- orr R0, R10, R9, LSL R5 @ factor in the way number and cache number into R11
- orr R0, R0, R7, LSL R2 @ factor in the index number
-
- blx R1
-
- subs R9, R9, #1 @ decrement the way number
- bge Loop3
- subs R7, R7, #1 @ decrement the index
- bge Loop2
-L_Skip:
- add R10, R10, #2 @ increment the cache number
- cmp R3, R10
- bgt Loop1
-
-L_Finished:
- dsb
- ldmfd SP!, {r4-r12, lr}
- bx LR
-
ASM_FUNC(ArmDataMemoryBarrier)
dmb
bx LR
diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
index 6a1f3f9..b83373d 100644
--- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
+++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
@@ -382,6 +382,13 @@ UpdateRegionMapping (
UINTN T0SZ;
if (((RegionStart | RegionLength) & EFI_PAGE_MASK) != 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a RegionStart: 0x%llx or RegionLength: 0x%llx are not page aligned!\n",
+ __func__,
+ RegionStart,
+ RegionLength
+ ));
return EFI_INVALID_PARAMETER;
}
diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S
index 0332cf7..9720414 100644
--- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S
+++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibReplaceEntry.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
.set CTRL_M_BIT, (1 << 0)
diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c
index 5e751cd..b8b8a70 100644
--- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c
+++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c
@@ -377,6 +377,13 @@ SetMemoryAttributes (
BOOLEAN FlushTlbs;
if (BaseAddress > (UINT64)MAX_ADDRESS) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a BaseAddress: 0x%llx is greater than MAX_ADDRESS: 0x%llx, fail to apply attributes!\n",
+ __func__,
+ BaseAddress,
+ (UINT64)MAX_ADDRESS
+ ));
return EFI_UNSUPPORTED;
}
@@ -437,6 +444,14 @@ SetMemoryAttributes (
}
if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a failed to update attributes with status %r for BaseAddress 0x%llx of length 0x%llx\n",
+ __func__,
+ Status,
+ BaseAddress,
+ ChunkLength
+ ));
break;
}
diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S
index a97e3fa..05f553a 100644
--- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S
+++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibV7Support.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
.text
.align 2
diff --git a/ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S b/ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S
new file mode 100644
index 0000000..6ca1be5
--- /dev/null
+++ b/ArmPkg/Library/ArmMonitorLib/AArch64/ArmMonitorLib.S
@@ -0,0 +1,79 @@
+//
+// Copyright (c) 2024, Google Llc. All rights reserved.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroLib.h>
+
+/** Monitor call.
+
+ An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued
+ depending on the default conduit. PcdMonitorConduitHvc determines the type
+ of the call: if true, do an HVC.
+
+ @param [in,out] Args Arguments for the HVC/SMC.
+**/
+ASM_FUNC(ArmMonitorCall)
+ // Create a stack frame
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+
+ // Preserve X0 for later use
+ mov x30, x0
+
+ // Load the SMCCC arguments values into the appropriate registers
+ ldp x0, x1, [x30, #0]
+ ldp x2, x3, [x30, #16]
+ ldp x4, x5, [x30, #32]
+ ldp x6, x7, [x30, #48]
+ ldp x8, x9, [x30, #64]
+ ldp x10, x11, [x30, #80]
+ ldp x12, x13, [x30, #96]
+ ldp x14, x15, [x30, #112]
+ ldp x16, x17, [x30, #128]
+
+#if !defined(_PCD_VALUE_PcdMonitorConduitHvc)
+#error
+#elif _PCD_VALUE_PcdMonitorConduitHvc == 0
+ smc #0
+#elif _PCD_VALUE_PcdMonitorConduitHvc == 1
+ hvc #0
+#else
+#error
+#endif
+
+ // A SMCCC SMC64/HVC64 call can return up to 18 values.
+ stp x0, x1, [x30, #0]
+ stp x2, x3, [x30, #16]
+ stp x4, x5, [x30, #32]
+ stp x6, x7, [x30, #48]
+ stp x8, x9, [x30, #64]
+ stp x10, x11, [x30, #80]
+ stp x12, x13, [x30, #96]
+ stp x14, x15, [x30, #112]
+ stp x16, x17, [x30, #128]
+
+ // Clear return values from registers
+ mov x0, xzr
+ mov x1, xzr
+ mov x2, xzr
+ mov x3, xzr
+ mov x4, xzr
+ mov x5, xzr
+ mov x6, xzr
+ mov x7, xzr
+ mov x8, xzr
+ mov x9, xzr
+ mov x10, xzr
+ mov x11, xzr
+ mov x12, xzr
+ mov x13, xzr
+ mov x14, xzr
+ mov x15, xzr
+ mov x16, xzr
+ mov x17, xzr
+
+ ldp x29, x30, [sp], #16
+ ret
diff --git a/ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S b/ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S
new file mode 100644
index 0000000..f3605cb
--- /dev/null
+++ b/ArmPkg/Library/ArmMonitorLib/Arm/ArmMonitorLib.S
@@ -0,0 +1,49 @@
+//
+// Copyright (c) 2024, Google Llc. All rights reserved.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroLib.h>
+
+/** Monitor call.
+
+ An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued
+ depending on the default conduit. PcdMonitorConduitHvc determines the type
+ of the call: if true, do an HVC.
+
+ @param [in,out] Args Arguments for the HVC/SMC.
+**/
+ASM_FUNC(ArmMonitorCall)
+ push {r4-r7}
+
+ // Preserve R0 for later use
+ mov ip, r0
+
+ // Load the SMCCC arguments values into the appropriate registers
+ ldm r0, {r0-r7}
+
+#if !defined(_PCD_VALUE_PcdMonitorConduitHvc)
+#error
+#elif _PCD_VALUE_PcdMonitorConduitHvc == 0
+ .arch_extension sec
+ smc #0
+#elif _PCD_VALUE_PcdMonitorConduitHvc == 1
+ .arch_extension virt
+ hvc #0
+#else
+#error
+#endif
+
+ // A SMCCC SMC32/HVC32 call can return up to 8 values.
+ stm ip, {r0-r7}
+
+ // Clear return values from registers
+ mov r0, #0
+ mov r1, #0
+ mov r2, #0
+ mov r3, #0
+
+ pop {r4-r7}
+ bx lr
diff --git a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c
deleted file mode 100644
index 617e88f..0000000
--- a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/** @file
- Arm Monitor Library.
-
- Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Library/ArmHvcLib.h>
-#include <Library/ArmMonitorLib.h>
-#include <Library/ArmSmcLib.h>
-#include <Library/PcdLib.h>
-
-/** Monitor call.
-
- An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued
- depending on the default conduit. PcdMonitorConduitHvc determines the type
- of the call: if true, do an HVC.
-
- @param [in,out] Args Arguments for the HVC/SMC.
-**/
-VOID
-EFIAPI
-ArmMonitorCall (
- IN OUT ARM_MONITOR_ARGS *Args
- )
-{
- if (FeaturePcdGet (PcdMonitorConduitHvc)) {
- ArmCallHvc ((ARM_HVC_ARGS *)Args);
- } else {
- ArmCallSmc ((ARM_SMC_ARGS *)Args);
- }
-}
diff --git a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
index f504cb8..06fbab2 100644
--- a/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
+++ b/ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
@@ -14,16 +14,15 @@
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmMonitorLib
-[Sources]
- ArmMonitorLib.c
+[Sources.ARM]
+ Arm/ArmMonitorLib.S
+
+[Sources.AARCH64]
+ AArch64/ArmMonitorLib.S
[Packages]
ArmPkg/ArmPkg.dec
MdePkg/MdePkg.dec
-[LibraryClasses]
- ArmHvcLib
- ArmSmcLib
-
[Pcd]
gArmTokenSpaceGuid.PcdMonitorConduitHvc
diff --git a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c
index 02b0c27..4134c8b 100644
--- a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c
+++ b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.c
@@ -1,13 +1,11 @@
/** @file
Support ResetSystem Runtime call using PSCI calls
- Note: A similar library is implemented in
- ArmVirtPkg/Library/ArmVirtualizationPsciResetSystemLib
- So similar issues might exist in this implementation too.
-
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2013-2015, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2024, Google Llc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -15,76 +13,164 @@
#include <PiDxe.h>
+#include <IndustryStandard/ArmStdSmc.h>
+
+#include <Library/ArmMonitorLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
-#include <Library/EfiResetSystemLib.h>
-#include <Library/ArmSmcLib.h>
+#include <Library/ResetSystemLib.h>
+#include <Library/UefiBootServicesTableLib.h>
-#include <IndustryStandard/ArmStdSmc.h>
+/**
+ Library constructor. This function does nothing, but this library may depend
+ on other libraries that do have a non-trivial constructor, which the
+ BaseToools fail to account for if a library has no constructor at all.
+ **/
+RETURN_STATUS
+EFIAPI
+ArmPsciResetSystemLibConstructor (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
/**
- Resets the entire platform.
+ This function causes a system-wide reset (cold reset), in which
+ all circuitry within the system returns to its initial state. This type of reset
+ is asynchronous to system operation and operates without regard to
+ cycle boundaries.
+
+ If this function returns, it means that the system does not support cold reset.
+**/
+VOID
+EFIAPI
+ResetCold (
+ VOID
+ )
+{
+ ARM_MONITOR_ARGS Args;
- @param ResetType The type of reset to perform.
- @param ResetStatus The status code for the reset.
- @param DataSize The size, in bytes, of WatchdogData.
- @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
- EfiResetShutdown the data buffer starts with a Null-terminated
- Unicode string, optionally followed by additional binary data.
+ // Send a PSCI 0.2 SYSTEM_RESET command
+ Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;
+
+ ArmMonitorCall (&Args);
+}
+/**
+ This function causes a system-wide initialization (warm reset), in which all processors
+ are set to their initial state. Pending cycles are not corrupted.
+
+ If this function returns, it means that the system does not support warm reset.
**/
-EFI_STATUS
+VOID
EFIAPI
-LibResetSystem (
- IN EFI_RESET_TYPE ResetType,
- IN EFI_STATUS ResetStatus,
- IN UINTN DataSize,
- IN CHAR16 *ResetData OPTIONAL
+ResetWarm (
+ VOID
)
{
- ARM_SMC_ARGS ArmSmcArgs;
+ ARM_MONITOR_ARGS Args;
- switch (ResetType) {
- case EfiResetPlatformSpecific:
- // Map the platform specific reset as reboot
- case EfiResetWarm:
- // Map a warm reset into a cold reset
- case EfiResetCold:
- // Send a PSCI 0.2 SYSTEM_RESET command
- ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;
- break;
- case EfiResetShutdown:
- // Send a PSCI 0.2 SYSTEM_OFF command
- ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;
- break;
- default:
- ASSERT (FALSE);
- return EFI_UNSUPPORTED;
- }
+ Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET2_AARCH64;
- ArmCallSmc (&ArmSmcArgs);
+ // Is SYSTEM_RESET2 supported?
+ ArmMonitorCall (&Args);
+ if (Args.Arg0 == ARM_SMC_PSCI_RET_SUCCESS) {
+ // Send PSCI SYSTEM_RESET2 command
+ Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET2_AARCH64;
- // We should never be here
- DEBUG ((DEBUG_ERROR, "%a: PSCI Reset failed\n", __func__));
- CpuDeadLoop ();
- return EFI_UNSUPPORTED;
+ ArmMonitorCall (&Args);
+ } else {
+ // Map a warm reset into a cold reset
+ DEBUG ((
+ DEBUG_INFO,
+ "Warm reboot not supported by platform, issuing cold reboot\n"
+ ));
+ ResetCold ();
+ }
}
/**
- Initialize any infrastructure required for LibResetSystem () to function.
+ This function causes the system to enter a power state equivalent
+ to the ACPI G2/S5 or G3 states.
+
+ If this function returns, it means that the system does not support shutdown reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+ VOID
+ )
+{
+ ARM_MONITOR_ARGS Args;
- @param ImageHandle The firmware allocated handle for the EFI image.
- @param SystemTable A pointer to the EFI System Table.
+ // Send a PSCI 0.2 SYSTEM_RESET command
+ Args.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;
- @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+ ArmMonitorCall (&Args);
+}
+/**
+ This function causes a systemwide reset. The exact type of the reset is
+ defined by the EFI_GUID that follows the Null-terminated Unicode string passed
+ into ResetData. If the platform does not recognize the EFI_GUID in ResetData
+ the platform must pick a supported reset type to perform.The platform may
+ optionally log the parameters from any non-normal reset that occurs.
+
+ @param[in] DataSize The size, in bytes, of ResetData.
+ @param[in] ResetData The data buffer starts with a Null-terminated string,
+ followed by the EFI_GUID.
**/
-EFI_STATUS
+VOID
EFIAPI
-LibInitializeResetSystem (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
+ResetPlatformSpecific (
+ IN UINTN DataSize,
+ IN VOID *ResetData
)
{
- return EFI_SUCCESS;
+ // Map the platform specific reset as reboot
+ ResetCold ();
+}
+
+/**
+ The ResetSystem function resets the entire platform.
+
+ @param[in] ResetType The type of reset to perform.
+ @param[in] ResetStatus The status code for the reset.
+ @param[in] DataSize The size, in bytes, of ResetData.
+ @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
+ the data buffer starts with a Null-terminated string, optionally
+ followed by additional binary data. The string is a description
+ that the caller may use to further indicate the reason for the
+ system reset.
+**/
+VOID
+EFIAPI
+ResetSystem (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN VOID *ResetData OPTIONAL
+ )
+{
+ switch (ResetType) {
+ case EfiResetWarm:
+ ResetWarm ();
+ break;
+
+ case EfiResetCold:
+ ResetCold ();
+ break;
+
+ case EfiResetShutdown:
+ ResetShutdown ();
+ return;
+
+ case EfiResetPlatformSpecific:
+ ResetPlatformSpecific (DataSize, ResetData);
+ return;
+
+ default:
+ return;
+ }
}
diff --git a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
index 3d05de4..c98f60d 100644
--- a/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
+++ b/ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
@@ -1,32 +1,32 @@
-#/** @file
-# Reset System lib using PSCI hypervisor or secure monitor calls
+## @file
+# Reset System lib using PSCI hypervisor or secure monitor calls
#
-# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
-# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
-# Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
+# Copyright (c) 2024, Google Llc. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
-#
-#**/
+##
[Defines]
- INF_VERSION = 0x00010005
+ INF_VERSION = 1.29
BASE_NAME = ArmPsciResetSystemLib
- FILE_GUID = A8F59B69-A105-41C7-8F5A-2C60DD7FD7AA
+ FILE_GUID = 31db596f-cc80-47fd-849f-e6be5e9f7560
MODULE_TYPE = BASE
VERSION_STRING = 1.0
- LIBRARY_CLASS = EfiResetSystemLib
+ LIBRARY_CLASS = ResetSystemLib
+ CONSTRUCTOR = ArmPsciResetSystemLibConstructor
[Sources]
ArmPsciResetSystemLib.c
[Packages]
ArmPkg/ArmPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
- EmbeddedPkg/EmbeddedPkg.dec
[LibraryClasses]
- DebugLib
+ ArmMonitorLib
BaseLib
- ArmSmcLib
+ DebugLib
diff --git a/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S b/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
index 4a8c2a8..a4443a4 100644
--- a/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
+++ b/ArmPkg/Library/ArmSmcLib/AArch64/ArmSmc.S
@@ -5,7 +5,7 @@
//
//
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
ASM_FUNC(ArmCallSmc)
// Push x0 on the stack - The stack must always be quad-word aligned
diff --git a/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S b/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
index d218e7e..4b3d0db 100644
--- a/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
+++ b/ArmPkg/Library/ArmSmcLib/Arm/ArmSmc.S
@@ -5,7 +5,7 @@
//
//
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
.arch_extension sec
diff --git a/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c b/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c
deleted file mode 100644
index dc7b9fd..0000000
--- a/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/** @file
- ResetSystemLib implementation using PSCI calls
-
- Copyright (c) 2017 - 2018, Linaro Ltd. All rights reserved.<BR>
- Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <PiDxe.h>
-
-#include <Library/ArmSmcLib.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/ResetSystemLib.h>
-
-#include <IndustryStandard/ArmStdSmc.h>
-
-/**
- This function causes a system-wide reset (cold reset), in which
- all circuitry within the system returns to its initial state. This type of reset
- is asynchronous to system operation and operates without regard to
- cycle boundaries.
-
- If this function returns, it means that the system does not support cold reset.
-**/
-VOID
-EFIAPI
-ResetCold (
- VOID
- )
-{
- // Send a PSCI 0.2 SYSTEM_RESET command
- ArmCallSmc0 (ARM_SMC_ID_PSCI_SYSTEM_RESET, NULL, NULL, NULL);
-}
-
-/**
- This function causes a system-wide initialization (warm reset), in which all processors
- are set to their initial state. Pending cycles are not corrupted.
-
- If this function returns, it means that the system does not support warm reset.
-**/
-VOID
-EFIAPI
-ResetWarm (
- VOID
- )
-{
- UINTN Arg1;
- UINTN Ret;
-
- Arg1 = ARM_SMC_ID_PSCI_SYSTEM_RESET2_AARCH64;
-
- // Is SYSTEM_RESET2 supported?
- Ret = ArmCallSmc0 (ARM_SMC_ID_PSCI_FEATURES, &Arg1, NULL, NULL);
- if (Ret == ARM_SMC_PSCI_RET_SUCCESS) {
- // Send PSCI SYSTEM_RESET2 command
- ArmCallSmc0 (Arg1, NULL, NULL, NULL);
- } else {
- // Map a warm reset into a cold reset
- DEBUG ((
- DEBUG_INFO,
- "Warm reboot not supported by platform, issuing cold reboot\n"
- ));
- ResetCold ();
- }
-}
-
-/**
- This function causes the system to enter a power state equivalent
- to the ACPI G2/S5 or G3 states.
-
- If this function returns, it means that the system does not support shutdown reset.
-**/
-VOID
-EFIAPI
-ResetShutdown (
- VOID
- )
-{
- // Send a PSCI 0.2 SYSTEM_OFF command
- ArmCallSmc0 (ARM_SMC_ID_PSCI_SYSTEM_OFF, NULL, NULL, NULL);
-}
-
-/**
- This function causes a systemwide reset. The exact type of the reset is
- defined by the EFI_GUID that follows the Null-terminated Unicode string passed
- into ResetData. If the platform does not recognize the EFI_GUID in ResetData
- the platform must pick a supported reset type to perform.The platform may
- optionally log the parameters from any non-normal reset that occurs.
-
- @param[in] DataSize The size, in bytes, of ResetData.
- @param[in] ResetData The data buffer starts with a Null-terminated string,
- followed by the EFI_GUID.
-**/
-VOID
-EFIAPI
-ResetPlatformSpecific (
- IN UINTN DataSize,
- IN VOID *ResetData
- )
-{
- // Map the platform specific reset as reboot
- ResetCold ();
-}
-
-/**
- The ResetSystem function resets the entire platform.
-
- @param[in] ResetType The type of reset to perform.
- @param[in] ResetStatus The status code for the reset.
- @param[in] DataSize The size, in bytes, of ResetData.
- @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
- the data buffer starts with a Null-terminated string, optionally
- followed by additional binary data. The string is a description
- that the caller may use to further indicate the reason for the
- system reset.
-**/
-VOID
-EFIAPI
-ResetSystem (
- IN EFI_RESET_TYPE ResetType,
- IN EFI_STATUS ResetStatus,
- IN UINTN DataSize,
- IN VOID *ResetData OPTIONAL
- )
-{
- switch (ResetType) {
- case EfiResetWarm:
- ResetWarm ();
- break;
-
- case EfiResetCold:
- ResetCold ();
- break;
-
- case EfiResetShutdown:
- ResetShutdown ();
- return;
-
- case EfiResetPlatformSpecific:
- ResetPlatformSpecific (DataSize, ResetData);
- return;
-
- default:
- return;
- }
-}
diff --git a/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf b/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
deleted file mode 100644
index c17b28c..0000000
--- a/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
+++ /dev/null
@@ -1,29 +0,0 @@
-#/** @file
-# ResetSystemLib implementation using PSCI calls
-#
-# Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#**/
-
-[Defines]
- INF_VERSION = 0x00010019
- BASE_NAME = ArmSmcPsciResetSystemLib
- FILE_GUID = 18B12C83-7718-4D83-ADA4-87F2FE698DD4
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = ResetSystemLib
-
-[Sources]
- ArmSmcPsciResetSystemLib.c
-
-[Packages]
- ArmPkg/ArmPkg.dec
- MdeModulePkg/MdeModulePkg.dec
- MdePkg/MdePkg.dec
-
-[LibraryClasses]
- ArmSmcLib
- BaseLib
- DebugLib
diff --git a/ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S b/ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S
index bdba9d7..6bcb10e 100644
--- a/ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S
+++ b/ArmPkg/Library/ArmSvcLib/AArch64/ArmSvc.S
@@ -5,7 +5,7 @@
//
//
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
.text
.align 3
diff --git a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c
index 992c14d..9ae83d9 100644
--- a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c
+++ b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c
@@ -32,7 +32,7 @@ PeCoffLoaderRelocateImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
-#ifdef __GNUC__
+ #ifdef __GNUC__
if (ImageContext->PdbPointer) {
DEBUG ((
DEBUG_LOAD | DEBUG_INFO,
@@ -42,7 +42,8 @@ PeCoffLoaderRelocateImageExtraAction (
));
return;
}
-#endif
+
+ #endif
DEBUG ((
DEBUG_LOAD | DEBUG_INFO,
@@ -68,7 +69,7 @@ PeCoffLoaderUnloadImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
-#ifdef __GNUC__
+ #ifdef __GNUC__
if (ImageContext->PdbPointer) {
DEBUG ((
DEBUG_LOAD | DEBUG_INFO,
@@ -78,7 +79,8 @@ PeCoffLoaderUnloadImageExtraAction (
));
return;
}
-#endif
+
+ #endif
DEBUG ((
DEBUG_LOAD | DEBUG_INFO,
diff --git a/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S b/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S
index a443075..10ecbca 100644
--- a/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S
+++ b/ArmPkg/Library/SemihostLib/AArch64/GccSemihost.S
@@ -7,7 +7,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
ASM_FUNC(GccSemihostCall)
hlt #0xf000
diff --git a/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S b/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S
index d6f81ec..da02a1f 100644
--- a/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S
+++ b/ArmPkg/Library/SemihostLib/Arm/GccSemihost.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
/*
Semihosting operation request mechanism
diff --git a/ArmPlatformPkg/ArmPlatformPkg.ci.yaml b/ArmPlatformPkg/ArmPlatformPkg.ci.yaml
index 03632e7..9c384a3 100644
--- a/ArmPlatformPkg/ArmPlatformPkg.ci.yaml
+++ b/ArmPlatformPkg/ArmPlatformPkg.ci.yaml
@@ -5,6 +5,9 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "ArmPlatformPkg.dsc",
+ },
## options defined .pytool/Plugin/LicenseCheck
"LicenseCheck": {
"IgnoreFiles": []
diff --git a/ArmPlatformPkg/ArmPlatformPkg.dec b/ArmPlatformPkg/ArmPlatformPkg.dec
index 7b5d7e6..e8be550 100644
--- a/ArmPlatformPkg/ArmPlatformPkg.dec
+++ b/ArmPlatformPkg/ArmPlatformPkg.dec
@@ -50,8 +50,6 @@
gArmPlatformTokenSpaceGuid = { 0x9c0aaed4, 0x74c5, 0x4043, { 0xb4, 0x17, 0xa3, 0x22, 0x38, 0x14, 0xce, 0x76 } }
[PcdsFeatureFlag.common]
- gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores|FALSE|BOOLEAN|0x00000004
-
# Disable the GOP controller on ExitBootServices(). By default the value is FALSE,
# we assume the OS will handle the FrameBuffer from the UEFI GOP information.
gArmPlatformTokenSpaceGuid.PcdGopDisableOnExitBootServices|FALSE|BOOLEAN|0x0000003D
@@ -63,7 +61,6 @@
# Stack for CPU Cores in Non Secure Mode
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0|UINT64|0x00000009
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x10000|UINT32|0x00000037
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize|0x1000|UINT32|0x0000000A
# Size of the region used by UEFI in permanent memory (Reserved 128MB by default)
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x08000000|UINT32|0x00000015
diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc
index ddd128f..bfe1b99 100644
--- a/ArmPlatformPkg/ArmPlatformPkg.dsc
+++ b/ArmPlatformPkg/ArmPlatformPkg.dsc
@@ -40,7 +40,6 @@
ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
- ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
@@ -52,7 +51,6 @@
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
LcdHwLib|ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.inf
LcdPlatformLib|ArmPlatformPkg/Library/LcdPlatformNullLib/LcdPlatformNullLib.inf
- LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
@@ -75,9 +73,6 @@
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
[LibraryClasses.common.PEIM]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
@@ -91,6 +86,9 @@
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+ # ARM platforms have SEC modules with standard entry points, so we can generically link StackCheckLib
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.AARCH64.MM_STANDALONE]
HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
@@ -103,7 +101,6 @@
ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf
- ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
ArmPlatformPkg/Library/HdLcd/HdLcd.inf
ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.inf
ArmPlatformPkg/Library/LcdPlatformNullLib/LcdPlatformNullLib.inf
@@ -120,10 +117,7 @@
ArmPlatformPkg/PlatformPei/PlatformPeim.inf
ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf
- ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
- ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
-
- ArmPlatformPkg/PrePi/PeiMPCore.inf
- ArmPlatformPkg/PrePi/PeiUniCore.inf
+ ArmPlatformPkg/Sec/Sec.inf
+ ArmPlatformPkg/PeilessSec/PeilessSec.inf
ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.inf
diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c
index d87ab3d..fc06220 100644
--- a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c
+++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c
@@ -177,13 +177,16 @@ Get (
EFI_STATUS Status;
UINTN Index, Offset, RegisterBase;
- Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase);
- ASSERT_EFI_ERROR (Status);
-
if (Value == NULL) {
return EFI_INVALID_PARAMETER;
}
+ Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
if (PL061GetPins (RegisterBase, GPIO_PIN_MASK (Offset)) != 0) {
*Value = 1;
} else {
@@ -223,7 +226,10 @@ Set (
UINTN Index, Offset, RegisterBase;
Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
switch (Mode) {
case GPIO_MODE_INPUT:
@@ -285,14 +291,17 @@ GetMode (
EFI_STATUS Status;
UINTN Index, Offset, RegisterBase;
- Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase);
- ASSERT_EFI_ERROR (Status);
-
// Check for errors
if (Mode == NULL) {
return EFI_INVALID_PARAMETER;
}
+ Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
// Check if it is input or output
if (MmioRead8 (RegisterBase + PL061_GPIO_DIR_REG) & GPIO_PIN_MASK (Offset)) {
// Pin set to output
diff --git a/ArmPlatformPkg/Include/Library/ArmPlatformLib.h b/ArmPlatformPkg/Include/Library/ArmPlatformLib.h
index cd87743..38e7bda 100644
--- a/ArmPlatformPkg/Include/Library/ArmPlatformLib.h
+++ b/ArmPlatformPkg/Include/Library/ArmPlatformLib.h
@@ -22,49 +22,6 @@
#include <Library/ArmLib.h>
/**
- Return the core position from the value of its MpId register
-
- This function returns the core position from the position 0 in the processor.
- This function might be called from assembler before any stack is set.
-
- @return Return the core position
-
-**/
-UINTN
-ArmPlatformGetCorePosition (
- IN UINTN MpId
- );
-
-/**
- Return a non-zero value if the callee is the primary core
-
- This function returns a non-zero value if the callee is the primary core.
- The primary core is the core responsible to initialize the hardware and run UEFI.
- This function might be called from assembler before any stack is set.
-
- @return Return a non-zero value if the callee is the primary core.
-
-**/
-UINTN
-ArmPlatformIsPrimaryCore (
- IN UINTN MpId
- );
-
-/**
- Return the MpId of the primary core
-
- This function returns the MpId of the primary core.
- This function might be called from assembler before any stack is set.
-
- @return Return the MpId of the primary core
-
-**/
-UINTN
-ArmPlatformGetPrimaryCoreMpId (
- VOID
- );
-
-/**
Return the current Boot Mode
This function returns the boot reason on the platform
diff --git a/ArmPlatformPkg/Include/Library/LcdPlatformLib.h b/ArmPlatformPkg/Include/Library/LcdPlatformLib.h
index b5628ec..2049e5e 100644
--- a/ArmPlatformPkg/Include/Library/LcdPlatformLib.h
+++ b/ArmPlatformPkg/Include/Library/LcdPlatformLib.h
@@ -220,7 +220,7 @@ typedef struct {
@param[in] Handle Handle to the LCD device instance.
- @retval EFI_SUCCESS Plaform library initialized successfully.
+ @retval EFI_SUCCESS Platform library initialized successfully.
@retval !(EFI_SUCCESS) Other errors.
**/
EFI_STATUS
diff --git a/ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.c b/ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.c
index d01c910..cea7ce2 100644
--- a/ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.c
+++ b/ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.c
@@ -287,7 +287,7 @@ LcdInitialize (
return EFI_SUCCESS;
}
-/** Set ARM Mali DP in cofiguration mode.
+/** Set ARM Mali DP in configuration mode.
The ARM Mali DP must be in the configuration mode for
configuration of the H_INTERVALS, V_INTERVALS, SYNC_CONTROL
diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S b/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S
index b7c6dbd..8737293 100644
--- a/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S
+++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S
@@ -5,41 +5,8 @@
//
//
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
#include <Library/ArmLib.h>
ASM_FUNC(ArmPlatformPeiBootAction)
ret
-
-//UINTN
-//ArmPlatformGetCorePosition (
-// IN UINTN MpId
-// );
-// With this function: CorePos = (ClusterId * 4) + CoreId
-ASM_FUNC(ArmPlatformGetCorePosition)
- and x1, x0, #ARM_CORE_MASK
- and x0, x0, #ARM_CLUSTER_MASK
- add x0, x1, x0, LSR #6
- ret
-
-//UINTN
-//ArmPlatformGetPrimaryCoreMpId (
-// VOID
-// );
-ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
- MOV32 (w0, FixedPcdGet32 (PcdArmPrimaryCore))
- ret
-
-//UINTN
-//ArmPlatformIsPrimaryCore (
-// IN UINTN MpId
-// );
-ASM_FUNC(ArmPlatformIsPrimaryCore)
- MOV32 (w1, FixedPcdGet32 (PcdArmPrimaryCoreMask))
- and x0, x0, x1
- MOV32 (w1, FixedPcdGet32 (PcdArmPrimaryCore))
- cmp w0, w1
- mov x0, #1
- mov x1, #0
- csel x0, x0, x1, eq
- ret
diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S b/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S
index aedae55..0e11c34 100644
--- a/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S
+++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/Arm/ArmPlatformHelper.S
@@ -5,39 +5,8 @@
//
//
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
#include <Library/ArmLib.h>
ASM_FUNC(ArmPlatformPeiBootAction)
bx lr
-
-//UINTN
-//ArmPlatformGetCorePosition (
-// IN UINTN MpId
-// );
-ASM_FUNC(ArmPlatformGetCorePosition)
- and r1, r0, #ARM_CORE_MASK
- and r0, r0, #ARM_CLUSTER_MASK
- add r0, r1, r0, LSR #7
- bx lr
-
-//UINTN
-//ArmPlatformGetPrimaryCoreMpId (
-// VOID
-// );
-ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
- MOV32 (r0, FixedPcdGet32 (PcdArmPrimaryCore))
- bx lr
-
-//UINTN
-//ArmPlatformIsPrimaryCore (
-// IN UINTN MpId
-// );
-ASM_FUNC(ArmPlatformIsPrimaryCore)
- MOV32 (r1, FixedPcdGet32 (PcdArmPrimaryCoreMask))
- and r0, r0, r1
- MOV32 (r1, FixedPcdGet32 (PcdArmPrimaryCore))
- cmp r0, r1
- moveq r0, #1
- movne r0, #0
- bx lr
diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c
index 852275f..83c7d16 100644
--- a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c
+++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.c
@@ -90,10 +90,6 @@ ArmPlatformInitialize (
IN UINTN MpId
)
{
- if (!ArmPlatformIsPrimaryCore (MpId)) {
- return RETURN_SUCCESS;
- }
-
// TODO: Implement me
return RETURN_SUCCESS;
diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S b/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S
deleted file mode 100644
index db0912c..0000000
--- a/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S
+++ /dev/null
@@ -1,99 +0,0 @@
-//
-// Copyright (c) 2012-2014, ARM Limited. All rights reserved.
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-//
-
-#include <AsmMacroIoLibV8.h>
-
-//VOID
-//ArmPlatformStackSet (
-// IN UINTN StackBase,
-// IN UINTN MpId,
-// IN UINTN PrimaryStackSize,
-// IN UINTN SecondaryStackSize
-// );
-ASM_FUNC(ArmPlatformStackSet)
- // Save parameters
- mov x26, x3
- mov x25, x2
- mov x24, x1
- mov x23, x0
-
- // Save the Link register
- mov x27, x30
-
- // Identify Stack
- mov x0, x1
- bl ASM_PFX(ArmPlatformIsPrimaryCore)
- cmp x0, #1
-
- // Restore parameters
- mov x0, x23
- mov x1, x24
- mov x2, x25
- mov x3, x26
-
- // Restore the Link register
- mov x30, x27
-
- b.ne 0f
-
- b ASM_PFX(ArmPlatformStackSetPrimary)
-0:b ASM_PFX(ArmPlatformStackSetSecondary)
-
-//VOID
-//ArmPlatformStackSetPrimary (
-// IN UINTN StackBase,
-// IN UINTN MpId,
-// IN UINTN PrimaryStackSize,
-// IN UINTN SecondaryStackSize
-// );
-ASM_FUNC(ArmPlatformStackSetPrimary)
- // Add size of primary stack to StackBase
- add x0, x0, x2
-
- // Compute SecondaryCoresCount * SecondaryCoreStackSize
- MOV32 (w1, FixedPcdGet32(PcdCoreCount) - 1)
- mul x3, x3, x1
-
- // Set Primary Stack ((StackBase + PrimaryStackSize) + (SecondaryCoresCount * SecondaryCoreStackSize))
- add sp, x0, x3
-
- ret
-
-//VOID
-//ArmPlatformStackSetSecondary (
-// IN UINTN StackBase,
-// IN UINTN MpId,
-// IN UINTN PrimaryStackSize,
-// IN UINTN SecondaryStackSize
-// );
-ASM_FUNC(ArmPlatformStackSetSecondary)
- // Save the Link register
- mov x24, x30
- mov sp, x0
-
- // Get Core Position
- mov x0, x1
- bl ASM_PFX(ArmPlatformGetCorePosition)
- mov x25, x0
-
- // Get Primary Core Position
- bl ASM_PFX(ArmPlatformGetPrimaryCoreMpId)
- bl ASM_PFX(ArmPlatformGetCorePosition)
-
- // Get Secondary Core Position. We should get consecutive secondary stack number from 1...(CoreCount-1)
- cmp x25, x0
-
- // Decrement the position if after the primary core
- cinc x25, x25, ls
-
- // Compute top of the secondary stack
- mul x3, x3, x25
-
- // Set stack
- add sp, sp, x3
-
- ret x24
diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S b/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S
deleted file mode 100644
index 0e47032..0000000
--- a/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// Copyright (c) 2012-2013, ARM Limited. All rights reserved.
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-//
-
-#include <AsmMacroIoLib.h>
-
-//VOID
-//ArmPlatformStackSet (
-// IN UINTN StackBase,
-// IN UINTN MpId,
-// IN UINTN PrimaryStackSize,
-// IN UINTN SecondaryStackSize
-// );
-ASM_FUNC(ArmPlatformStackSet)
- // Save parameters
- mov r6, r3
- mov r5, r2
- mov r4, r1
- mov r3, r0
-
- // Save the Link register
- mov r7, lr
-
- // Identify Stack
- mov r0, r1
- bl ASM_PFX(ArmPlatformIsPrimaryCore)
- cmp r0, #1
-
- // Restore parameters
- mov r0, r3
- mov r1, r4
- mov r2, r5
- mov r3, r6
-
- // Restore the Link register
- mov lr, r7
-
- beq ASM_PFX(ArmPlatformStackSetPrimary)
- bne ASM_PFX(ArmPlatformStackSetSecondary)
-
-//VOID
-//ArmPlatformStackSetPrimary (
-// IN UINTN StackBase,
-// IN UINTN MpId,
-// IN UINTN PrimaryStackSize,
-// IN UINTN SecondaryStackSize
-// );
-ASM_FUNC(ArmPlatformStackSetPrimary)
- mov r4, lr
-
- // Add stack of primary stack to StackBase
- add r0, r0, r2
-
- // Compute SecondaryCoresCount * SecondaryCoreStackSize
- MOV32 (r1, FixedPcdGet32(PcdCoreCount) - 1)
- mul r3, r3, r1
-
- // Set Primary Stack ((StackBase + PrimaryStackSize) + (SecondaryCoresCount * SecondaryCoreStackSize))
- add sp, r0, r3
-
- bx r4
-
-//VOID
-//ArmPlatformStackSetSecondary (
-// IN UINTN StackBase,
-// IN UINTN MpId,
-// IN UINTN PrimaryStackSize,
-// IN UINTN SecondaryStackSize
-// );
-ASM_FUNC(ArmPlatformStackSetSecondary)
- mov r4, lr
- mov sp, r0
-
- // Get Core Position
- mov r0, r1
- bl ASM_PFX(ArmPlatformGetCorePosition)
- mov r5, r0
-
- // Get Primary Core Position
- bl ASM_PFX(ArmPlatformGetPrimaryCoreMpId)
- bl ASM_PFX(ArmPlatformGetCorePosition)
-
- // Get Secondary Core Position. We should get consecutive secondary stack number from 1...(CoreCount-1)
- cmp r5, r0
- subhi r5, r5, #1
- add r5, r5, #1
-
- // Compute top of the secondary stack
- mul r3, r3, r5
-
- // Set stack
- add sp, sp, r3
-
- bx r4
-
diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf b/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
deleted file mode 100644
index dfa0e7b..0000000
--- a/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
+++ /dev/null
@@ -1,33 +0,0 @@
-#/* @file
-#
-# Copyright (c) 2012, ARM Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#*/
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = ArmPlatformStackLib
- FILE_GUID = 5e2e44af-53c1-44c2-a801-9c149f3d6ba0
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = ArmPlatformStackLib
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- ArmPkg/ArmPkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
-
-[Sources.ARM]
- Arm/ArmPlatformStackLib.S | GCC
-
-[Sources.AARCH64]
- AArch64/ArmPlatformStackLib.S
-
-[LibraryClasses]
- ArmPlatformLib
-
-[FixedPcd]
- gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.c b/ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.c
index ca48871..8044730 100644
--- a/ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.c
+++ b/ArmPlatformPkg/Library/LcdHwNullLib/LcdHwNullLib.c
@@ -23,7 +23,7 @@ LcdIdentify (
VOID
)
{
- return EFI_SUCCESS;
+ return EFI_NOT_FOUND;
}
/**
diff --git a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
index 6ab3e99..fb353cf 100644
--- a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
+++ b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
@@ -331,13 +331,13 @@ LibRtcInitialize (
EfiGcdMemoryTypeMemoryMappedIo,
mPL031RtcBase,
SIZE_4KB,
- EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP
);
if (EFI_ERROR (Status)) {
return Status;
}
- Status = gDS->SetMemorySpaceAttributes (mPL031RtcBase, SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
+ Status = gDS->SetMemorySpaceAttributes (mPL031RtcBase, SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP);
if (EFI_ERROR (Status)) {
return Status;
}
diff --git a/ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.c b/ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.c
index 07f9b0f..b0b0cd8 100644
--- a/ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.c
+++ b/ArmPlatformPkg/Library/PL111Lcd/PL111Lcd.c
@@ -19,7 +19,7 @@
@retval EFI_SUCCESS Returns success if platform implements a
PL111 controller.
- @retval EFI_NOT_FOUND PL111 display controller not found the plaform.
+ @retval EFI_NOT_FOUND PL111 display controller not found the platform.
**/
EFI_STATUS
LcdIdentify (
@@ -71,9 +71,9 @@ LcdInitialize (
/** Set requested mode of the display.
- @param[in] ModeNumbe Display mode number.
+ @param[in] ModeNumber Display mode number.
- @retval EFI_SUCCESS Display mode set successfuly.
+ @retval EFI_SUCCESS Display mode set successfully.
@retval !(EFI_SUCCESS) Other errors.
**/
EFI_STATUS
diff --git a/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c b/ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c
index 27a8504..ccc9cde 100644
--- a/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c
+++ b/ArmPlatformPkg/PeilessSec/AArch64/ArchPeilessSec.c
@@ -6,10 +6,13 @@
**/
-#include "PrePi.h"
+#include "PeilessSec.h"
#include <AArch64/AArch64.h>
+/**
+ Architecture specific initialization routine.
+**/
VOID
ArchInitialize (
VOID
diff --git a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S
index e3aa546..7263ee9 100644
--- a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
+++ b/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S
@@ -5,17 +5,12 @@
//
//
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
ASM_FUNC(_ModuleEntryPoint)
// Do early platform specific actions
bl ASM_PFX(ArmPlatformPeiBootAction)
- // Get ID of this CPU in multi-core system
- bl ASM_PFX(ArmReadMpidr)
- // Keep a copy of the MpId register value
- mov x10, x0
-
_SetSVCMode:
// Check if we can install the stack at the top of the System Memory or if we need
// to install the stacks at the bottom of the Firmware Device (case the FD is located
@@ -41,7 +36,7 @@ _SetupStackPosition:
// Calculate how much space there is between the top of the Firmware and the Top of the System Memory
subs x0, x1, x3 // x0 = SystemMemoryTop - FdTop
- b.mi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
+ b.mi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when SEC is in XIP memory outside of the DRAM
cmp x0, x4
b.ge _SetupStack
@@ -68,36 +63,15 @@ _SetupOverflowStack:
_GetBaseUefiMemory:
// Calculate the Base of the UEFI Memory
- sub x11, x1, x4
+ sub x0, x1, x4
_GetStackBase:
- // r1 = The top of the Mpcore Stacks
- // Stack for the primary core = PrimaryCoreStack
- MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
- sub x12, x1, x2
-
- // Stack for the secondary core = Number of Cores - 1
- MOV32 (x1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
- sub x12, x12, x1
+ // r1 = The top of the stack
+ mov sp, x1
- // x12 = The base of the MpCore Stacks (primary stack & secondary stacks)
- mov x0, x12
- mov x1, x10
- //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
+ // Stack for the primary core = PrimaryCoreStack
MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
- MOV32 (x3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
- bl ASM_PFX(ArmPlatformStackSet)
-
- // Is it the Primary Core ?
- mov x0, x10
- bl ASM_PFX(ArmPlatformIsPrimaryCore)
- cmp x0, #1
- bne _PrepareArguments
-
-_PrepareArguments:
- mov x0, x10
- mov x1, x11
- mov x2, x12
+ sub x1, x1, x2
// Move sec startup address into a data register
// Ensure we're jumping to FV version of the code (not boot remapped alias)
@@ -106,10 +80,9 @@ _PrepareArguments:
// Set the frame pointer to NULL so any backtraces terminate here
mov x29, xzr
- // Jump to PrePiCore C code
- // x0 = MpId
- // x1 = UefiMemoryBase
- // x2 = StacksBase
+ // Jump to SEC C code
+ // x0 = UefiMemoryBase
+ // x1 = StacksBase
blr x4
_NeverReturn:
diff --git a/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c b/ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c
index ac8abe5..3c3cef6 100644
--- a/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c
+++ b/ArmPlatformPkg/PeilessSec/Arm/ArchPeilessSec.c
@@ -6,8 +6,11 @@
**/
-#include "PrePi.h"
+#include "PeilessSec.h"
+/**
+ Architecture specific initialization routine.
+**/
VOID
ArchInitialize (
VOID
diff --git a/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S b/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S
index 60e530e..fc28939 100644
--- a/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S
+++ b/ArmPlatformPkg/PeilessSec/Arm/ModuleEntryPoint.S
@@ -5,7 +5,7 @@
//
//
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
#include <Arm/AArch32.h>
@@ -13,11 +13,6 @@ ASM_FUNC(_ModuleEntryPoint)
// Do early platform specific actions
bl ASM_PFX(ArmPlatformPeiBootAction)
- // Get ID of this CPU in multi-core system
- bl ASM_PFX(ArmReadMpidr)
- // Keep a copy of the MpId register value
- mov r8, r0
-
_SetSVCMode:
// Enter SVC mode, Disable FIQ and IRQ
mov r1, #(CPSR_MODE_SVC | CPSR_IRQ | CPSR_FIQ)
@@ -50,7 +45,7 @@ _SetupStackPosition:
// Calculate how much space there is between the top of the Firmware and the Top of the System Memory
subs r0, r1, r3 // r0 = SystemMemoryTop - FdTop
- bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
+ bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when SEC is in XIP memory outside of the DRAM
cmp r0, r4
bge _SetupStack
@@ -78,46 +73,23 @@ _SetupOverflowStack:
_GetBaseUefiMemory:
// Calculate the Base of the UEFI Memory
- sub r9, r1, r4
+ sub r0, r1, r4
_GetStackBase:
- // r1 = The top of the Mpcore Stacks
- // Stack for the primary core = PrimaryCoreStack
- MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
- sub r10, r1, r2
-
- // Stack for the secondary core = Number of Cores - 1
- MOV32 (r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
- sub r10, r10, r1
+ // r1 = The top of the stack
+ mov sp, r1
- // r10 = The base of the MpCore Stacks (primary stack & secondary stacks)
- mov r0, r10
- mov r1, r8
- //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
+ // Stack for the primary core = PrimaryCoreStack
MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
- MOV32 (r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
- bl ASM_PFX(ArmPlatformStackSet)
-
- // Is it the Primary Core ?
- mov r0, r8
- bl ASM_PFX(ArmPlatformIsPrimaryCore)
- cmp r0, #1
- bne _PrepareArguments
-
-_PrepareArguments:
- mov r0, r8
- mov r1, r9
- mov r2, r10
- mov r3, sp
+ sub r1, r1, r2
// Move sec startup address into a data register
// Ensure we're jumping to FV version of the code (not boot remapped alias)
ldr r4, =ASM_PFX(CEntryPoint)
- // Jump to PrePiCore C code
- // r0 = MpId
- // r1 = UefiMemoryBase
- // r2 = StacksBase
+ // Jump to SEC C code
+ // r0 = UefiMemoryBase
+ // r1 = StacksBase
blx r4
_NeverReturn:
diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PeilessSec/PeilessSec.c
index 9b127b9..639c374 100644
--- a/ArmPlatformPkg/PrePi/PrePi.c
+++ b/ArmPlatformPkg/PeilessSec/PeilessSec.c
@@ -6,21 +6,7 @@
**/
-#include <PiPei.h>
-
-#include <Library/CacheMaintenanceLib.h>
-#include <Library/DebugAgentLib.h>
-#include <Library/PrePiLib.h>
-#include <Library/PrintLib.h>
-#include <Library/PrePiHobListPointerLib.h>
-#include <Library/TimerLib.h>
-#include <Library/PerformanceLib.h>
-
-#include <Ppi/GuidedSectionExtraction.h>
-#include <Ppi/ArmMpCoreInfo.h>
-#include <Ppi/SecPerformance.h>
-
-#include "PrePi.h"
+#include "PeilessSec.h"
#define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) ||\
((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= FixedPcdGet64 (PcdSystemMemoryBase)))
@@ -28,6 +14,15 @@
UINT64 mSystemMemoryEnd = FixedPcdGet64 (PcdSystemMemoryBase) +
FixedPcdGet64 (PcdSystemMemorySize) - 1;
+/**
+ Obtain a PPI from the list of PPIs provided by the platform code.
+
+ @param[in] PpiGuid GUID of the PPI to obtain
+ @param[out] Ppi Address of GUID pointer to return the PPI
+
+ @return Whether the PPI was obtained successfully
+**/
+STATIC
EFI_STATUS
GetPlatformPpi (
IN EFI_GUID *PpiGuid,
@@ -52,10 +47,18 @@ GetPlatformPpi (
return EFI_NOT_FOUND;
}
+/**
+ SEC main routine.
+
+ @param[in] UefiMemoryBase Start of the PI/UEFI memory region
+ @param[in] StackBase Start of the stack
+ @param[in] StartTimeStamp Timer value at start of execution
+**/
+STATIC
VOID
-PrePiMain (
+SecMain (
IN UINTN UefiMemoryBase,
- IN UINTN StacksBase,
+ IN UINTN StackBase,
IN UINT64 StartTimeStamp
)
{
@@ -100,7 +103,7 @@ PrePiMain (
(VOID *)UefiMemoryBase,
FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
(VOID *)UefiMemoryBase,
- (VOID *)StacksBase // The top of the UEFI Memory is reserved for the stacks
+ (VOID *)StackBase // The top of the UEFI Memory is reserved for the stack
);
PrePeiSetHobList (HobList);
@@ -108,15 +111,9 @@ PrePiMain (
Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
ASSERT_EFI_ERROR (Status);
- // Create the Stacks HOB (reserve the memory for all stacks)
- if (ArmIsMpCore ()) {
- StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) +
- ((FixedPcdGet32 (PcdCoreCount) - 1) * FixedPcdGet32 (PcdCPUCoreSecondaryStackSize));
- } else {
- StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
- }
-
- BuildStackHob (StacksBase, StacksSize);
+ // Create the Stacks HOB
+ StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
+ BuildStackHob (StackBase, StacksSize);
// TODO: Call CpuPei as a library
BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize));
@@ -165,21 +162,24 @@ PrePiMain (
ASSERT_EFI_ERROR (Status);
}
+/**
+ C entrypoint into the SEC driver.
+
+ @param[in] UefiMemoryBase Start of the PI/UEFI memory region
+ @param[in] StackBase Start of the stack
+**/
VOID
CEntryPoint (
- IN UINTN MpId,
IN UINTN UefiMemoryBase,
- IN UINTN StacksBase
+ IN UINTN StackBase
)
{
UINT64 StartTimeStamp;
// Initialize the platform specific controllers
- ArmPlatformInitialize (MpId);
+ ArmPlatformInitialize (ArmReadMpidr ());
- if (ArmPlatformIsPrimaryCore (MpId) && PerformanceMeasurementEnabled ()) {
- // Initialize the Timer Library to setup the Timer HW controller
- TimerConstructor ();
+ if (PerformanceMeasurementEnabled ()) {
// We cannot call yet the PerformanceLib because the HOB List has not been initialized
StartTimeStamp = GetPerformanceCounter ();
} else {
@@ -193,31 +193,12 @@ CEntryPoint (
// Enable Instruction Caches on all cores.
ArmEnableInstructionCache ();
- // Define the Global Variable region when we are not running in XIP
- if (!IS_XIP ()) {
- if (ArmPlatformIsPrimaryCore (MpId)) {
- if (ArmIsMpCore ()) {
- // Signal the Global Variable Region is defined (event: ARM_CPU_EVENT_DEFAULT)
- ArmCallSEV ();
- }
- } else {
- // Wait the Primary core has defined the address of the Global Variable region (event: ARM_CPU_EVENT_DEFAULT)
- ArmCallWFE ();
- }
- }
-
- // If not primary Jump to Secondary Main
- if (ArmPlatformIsPrimaryCore (MpId)) {
- InvalidateDataCacheRange (
- (VOID *)UefiMemoryBase,
- FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)
- );
+ InvalidateDataCacheRange (
+ (VOID *)UefiMemoryBase,
+ FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)
+ );
- // Goto primary Main.
- PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp);
- } else {
- SecondaryMain (MpId);
- }
+ SecMain (UefiMemoryBase, StackBase, StartTimeStamp);
// DXE Core should always load and never return
ASSERT (FALSE);
diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.h b/ArmPlatformPkg/PeilessSec/PeilessSec.h
new file mode 100644
index 0000000..70d78ca
--- /dev/null
+++ b/ArmPlatformPkg/PeilessSec/PeilessSec.h
@@ -0,0 +1,76 @@
+/** @file
+
+ Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PEILESSSEC_H_
+#define PEILESSSEC_H_
+
+#include <PiPei.h>
+
+#include <Library/ArmLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Library/PrePiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/TimerLib.h>
+
+#include <Ppi/ArmMpCoreInfo.h>
+#include <Ppi/GuidedSectionExtraction.h>
+#include <Ppi/SecPerformance.h>
+
+extern UINT64 mSystemMemoryEnd;
+
+/**
+ Entrypoint of the memory PEIM driver.
+
+ @param[in] UefiMemoryBase The base of the PI/UEFI memory region
+ @param[in[ UefiMemorySize The size of the PI/UEFI memory region
+
+ @return Whether the memory PEIM driver executed successfully
+**/
+EFI_STATUS
+EFIAPI
+MemoryPeim (
+ IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
+ IN UINT64 UefiMemorySize
+ );
+
+/**
+ Entrypoint of platform PEIM driver.
+
+ @return Whether the platform PEIM driver executed successfully
+**/
+EFI_STATUS
+EFIAPI
+PlatformPeim (
+ VOID
+ );
+
+/**
+ Populate and install the memory type information HOB.
+**/
+VOID
+BuildMemoryTypeInformationHob (
+ VOID
+ );
+
+/**
+ Architecture specific initialization routine.
+**/
+VOID
+ArchInitialize (
+ VOID
+ );
+
+#endif /* PEILESSSEC_H_ */
diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PeilessSec/PeilessSec.inf
index 2e23717..7ceeb74 100644
--- a/ArmPlatformPkg/PrePi/PeiUniCore.inf
+++ b/ArmPlatformPkg/PeilessSec/PeilessSec.inf
@@ -1,60 +1,56 @@
-#/** @file
+## @file
+# SEC driver for PEI-less ARM platforms.
#
-# (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
+# Copyright (C) 2015 Hewlett-Packard Development Company, L.P.<BR>
# Copyright (c) 2011-2017, ARM Ltd. All rights reserved.<BR>
# Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
-#**/
+##
[Defines]
INF_VERSION = 1.30
- BASE_NAME = ArmPlatformPrePiUniCore
- FILE_GUID = 3e401783-cc94-4fcd-97bc-bd35ac369d2f
+ BASE_NAME = PeilessSec
+ FILE_GUID = d90b03a8-2df5-4174-9ec1-c6e5b12b334b
MODULE_TYPE = SEC
VERSION_STRING = 1.0
[Sources]
- PrePi.h
- PrePi.c
- MainUniCore.c
+ PeilessSec.h
+ PeilessSec.c
[Sources.ARM]
- Arm/ArchPrePi.c
- Arm/ModuleEntryPoint.S | GCC
+ Arm/ArchPeilessSec.c
+ Arm/ModuleEntryPoint.S
[Sources.AArch64]
- AArch64/ArchPrePi.c
+ AArch64/ArchPeilessSec.c
AArch64/ModuleEntryPoint.S
[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- EmbeddedPkg/EmbeddedPkg.dec
- ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
+ ArmPkg/ArmPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
[LibraryClasses]
- BaseLib
- CacheMaintenanceLib
- DebugLib
- DebugAgentLib
ArmLib
- IoLib
- TimerLib
- SerialPortLib
- ExtractGuidedSectionLib
- LzmaDecompressLib
- DebugAgentLib
- PrePiLib
ArmPlatformLib
- ArmPlatformStackLib
- MemoryAllocationLib
+ BaseMemoryLib
+ CacheMaintenanceLib
+ DebugAgentLib
+ DebugLib
HobLib
- PrePiHobListPointerLib
- PlatformPeiLib
MemoryInitPeiLib
+ PerformanceLib
+ PlatformPeiLib
+ PrePiHobListPointerLib
+ PrePiLib
+ PrintLib
+ SerialPortLib
+ TimerLib
[Ppis]
gArmMpCoreInfoPpiGuid
@@ -65,39 +61,18 @@
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
- gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
-
-[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
[FixedPcd]
- gArmTokenSpaceGuid.PcdVFPEnabled
-
+ gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
gArmTokenSpaceGuid.PcdFdBaseAddress
gArmTokenSpaceGuid.PcdFdSize
-
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdFvSize
-
- gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
-
- gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
-
- gArmPlatformTokenSpaceGuid.PcdCoreCount
-
+ gArmTokenSpaceGuid.PcdVFPEnabled
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
-
[Pcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
diff --git a/ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S b/ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S
deleted file mode 100644
index 1c9d1b5..0000000
--- a/ArmPlatformPkg/PrePeiCore/Arm/PrePeiCoreEntryPoint.S
+++ /dev/null
@@ -1,73 +0,0 @@
-//
-// Copyright (c) 2011-2013, ARM Limited. All rights reserved.
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-//
-
-#include <AsmMacroIoLib.h>
-
-ASM_FUNC(_ModuleEntryPoint)
- // Do early platform specific actions
- bl ASM_PFX(ArmPlatformPeiBootAction)
-
- // Identify CPU ID
- bl ASM_PFX(ArmReadMpidr)
- // Keep a copy of the MpId register value
- mov r5, r0
-
- // Is it the Primary Core ?
- bl ASM_PFX(ArmPlatformIsPrimaryCore)
-
- // Get the top of the primary stacks (and the base of the secondary stacks)
- MOV32 (r1, FixedPcdGet64(PcdCPUCoresStackBase) + FixedPcdGet32(PcdCPUCorePrimaryStackSize))
-
- // r0 is equal to 1 if I am the primary core
- cmp r0, #1
- beq _SetupPrimaryCoreStack
-
-_SetupSecondaryCoreStack:
- // r1 contains the base of the secondary stacks
-
- // Get the Core Position
- mov r6, r1 // Save base of the secondary stacks
- mov r0, r5
- bl ASM_PFX(ArmPlatformGetCorePosition)
- // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack
- add r0, r0, #1
-
- // StackOffset = CorePos * StackSize
- MOV32 (r2, FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
- mul r0, r0, r2
- // SP = StackBase + StackOffset
- add sp, r6, r0
-
-_PrepareArguments:
- // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector
- MOV32 (r2, FixedPcdGet32(PcdFvBaseAddress))
- ldr r1, [r2, #4]
-
- // Move sec startup address into a data register
- // Ensure we're jumping to FV version of the code (not boot remapped alias)
- ldr r3, =ASM_PFX(CEntryPoint)
-
- // Jump to PrePeiCore C code
- // r0 = mp_id
- // r1 = pei_core_address
- mov r0, r5
- blx r3
-
-_SetupPrimaryCoreStack:
- mov sp, r1
- MOV32 (r8, FixedPcdGet64 (PcdCPUCoresStackBase))
- MOV32 (r9, FixedPcdGet32 (PcdInitValueInTempStack))
- mov r10, r9
- mov r11, r9
- mov r12, r9
-0:stm r8!, {r9-r12}
- cmp r8, r1
- blt 0b
- b _PrepareArguments
-
-_NeverReturn:
- b _NeverReturn
diff --git a/ArmPlatformPkg/PrePeiCore/MainMPCore.c b/ArmPlatformPkg/PrePeiCore/MainMPCore.c
deleted file mode 100644
index b5d0d3a..0000000
--- a/ArmPlatformPkg/PrePeiCore/MainMPCore.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/** @file
-
- Copyright (c) 2011-2014, ARM Limited. All rights reserved.
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Library/ArmGicLib.h>
-
-#include <Ppi/ArmMpCoreInfo.h>
-
-#include "PrePeiCore.h"
-
-/*
- * This is the main function for secondary cores. They loop around until a non Null value is written to
- * SYS_FLAGS register.The SYS_FLAGS register is platform specific.
- * Note:The secondary cores, while executing secondary_main, assumes that:
- * : SGI 0 is configured as Non-secure interrupt
- * : Priority Mask is configured to allow SGI 0
- * : Interrupt Distributor and CPU interfaces are enabled
- *
- */
-VOID
-EFIAPI
-SecondaryMain (
- IN UINTN MpId
- )
-{
- EFI_STATUS Status;
- UINTN PpiListSize;
- UINTN PpiListCount;
- EFI_PEI_PPI_DESCRIPTOR *PpiList;
- ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
- UINTN Index;
- UINTN ArmCoreCount;
- ARM_CORE_INFO *ArmCoreInfoTable;
- UINT32 ClusterId;
- UINT32 CoreId;
-
- VOID (*SecondaryStart)(
- VOID
- );
- UINTN SecondaryEntryAddr;
- UINTN AcknowledgeInterrupt;
- UINTN InterruptId;
-
- ClusterId = GET_CLUSTER_ID (MpId);
- CoreId = GET_CORE_ID (MpId);
-
- // Get the gArmMpCoreInfoPpiGuid
- PpiListSize = 0;
- ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList);
- PpiListCount = PpiListSize / sizeof (EFI_PEI_PPI_DESCRIPTOR);
- for (Index = 0; Index < PpiListCount; Index++, PpiList++) {
- if (CompareGuid (PpiList->Guid, &gArmMpCoreInfoPpiGuid) == TRUE) {
- break;
- }
- }
-
- // On MP Core Platform we must implement the ARM MP Core Info PPI
- ASSERT (Index != PpiListCount);
-
- ArmMpCoreInfoPpi = PpiList->Ppi;
- ArmCoreCount = 0;
- Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
- ASSERT_EFI_ERROR (Status);
-
- // Find the core in the ArmCoreTable
- for (Index = 0; Index < ArmCoreCount; Index++) {
- if ((GET_MPIDR_AFF1 (ArmCoreInfoTable[Index].Mpidr) == ClusterId) &&
- (GET_MPIDR_AFF0 (ArmCoreInfoTable[Index].Mpidr) == CoreId))
- {
- break;
- }
- }
-
- // The ARM Core Info Table must define every core
- ASSERT (Index != ArmCoreCount);
-
- // Clear Secondary cores MailBox
- MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue);
-
- do {
- ArmCallWFI ();
-
- // Read the Mailbox
- SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress);
-
- // Acknowledge the interrupt and send End of Interrupt signal.
- AcknowledgeInterrupt = ArmGicAcknowledgeInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), &InterruptId);
- // Check if it is a valid interrupt ID
- if (InterruptId < ArmGicGetMaxNumInterrupts (PcdGet64 (PcdGicDistributorBase))) {
- // Got a valid SGI number hence signal End of Interrupt
- ArmGicEndOfInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), AcknowledgeInterrupt);
- }
- } while (SecondaryEntryAddr == 0);
-
- // Jump to secondary core entry point.
- SecondaryStart = (VOID (*)()) SecondaryEntryAddr;
- SecondaryStart ();
-
- // The secondaries shouldn't reach here
- ASSERT (FALSE);
-}
-
-VOID
-EFIAPI
-PrimaryMain (
- IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
- )
-{
- EFI_SEC_PEI_HAND_OFF SecCoreData;
- UINTN PpiListSize;
- EFI_PEI_PPI_DESCRIPTOR *PpiList;
- UINTN TemporaryRamBase;
- UINTN TemporaryRamSize;
-
- CreatePpiList (&PpiListSize, &PpiList);
-
- // Enable the GIC Distributor
- ArmGicEnableDistributor (PcdGet64 (PcdGicDistributorBase));
-
- // If ArmVe has not been built as Standalone then we need to wake up the secondary cores
- if (FeaturePcdGet (PcdSendSgiToBringUpSecondaryCores)) {
- // Sending SGI to all the Secondary CPU interfaces
- ArmGicSendSgiTo (PcdGet64 (PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));
- }
-
- // Adjust the Temporary Ram as the new Ppi List (Common + Platform Ppi Lists) is created at
- // the base of the primary core stack
- PpiListSize = ALIGN_VALUE (PpiListSize, CPU_STACK_ALIGNMENT);
- TemporaryRamBase = (UINTN)PcdGet64 (PcdCPUCoresStackBase) + PpiListSize;
- TemporaryRamSize = (UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize) - PpiListSize;
-
- //
- // Bind this information into the SEC hand-off state
- // Note: this must be in sync with the stuff in the asm file
- // Note also: HOBs (pei temp ram) MUST be above stack
- //
- SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
- SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet64 (PcdFvBaseAddress);
- SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdFvSize);
- SecCoreData.TemporaryRamBase = (VOID *)TemporaryRamBase; // We run on the primary core (and so we use the first stack)
- SecCoreData.TemporaryRamSize = TemporaryRamSize;
- SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
- SecCoreData.PeiTemporaryRamSize = ALIGN_VALUE (SecCoreData.TemporaryRamSize / 2, CPU_STACK_ALIGNMENT);
- SecCoreData.StackBase = (VOID *)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize);
- SecCoreData.StackSize = (TemporaryRamBase + TemporaryRamSize) - (UINTN)SecCoreData.StackBase;
-
- // Jump to PEI core entry point
- PeiCoreEntryPoint (&SecCoreData, PpiList);
-}
diff --git a/ArmPlatformPkg/PrePeiCore/MainUniCore.c b/ArmPlatformPkg/PrePeiCore/MainUniCore.c
deleted file mode 100644
index 1c2580e..0000000
--- a/ArmPlatformPkg/PrePeiCore/MainUniCore.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/** @file
-
- Copyright (c) 2011-2012, ARM Limited. All rights reserved.
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "PrePeiCore.h"
-
-VOID
-EFIAPI
-SecondaryMain (
- IN UINTN MpId
- )
-{
- ASSERT (FALSE);
-}
-
-VOID
-EFIAPI
-PrimaryMain (
- IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
- )
-{
- EFI_SEC_PEI_HAND_OFF SecCoreData;
- UINTN PpiListSize;
- EFI_PEI_PPI_DESCRIPTOR *PpiList;
- UINTN TemporaryRamBase;
- UINTN TemporaryRamSize;
-
- CreatePpiList (&PpiListSize, &PpiList);
-
- // Adjust the Temporary Ram as the new Ppi List (Common + Platform Ppi Lists) is created at
- // the base of the primary core stack
- PpiListSize = ALIGN_VALUE (PpiListSize, CPU_STACK_ALIGNMENT);
- TemporaryRamBase = (UINTN)PcdGet64 (PcdCPUCoresStackBase) + PpiListSize;
- TemporaryRamSize = (UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize) - PpiListSize;
-
- //
- // Bind this information into the SEC hand-off state
- // Note: this must be in sync with the stuff in the asm file
- // Note also: HOBs (pei temp ram) MUST be above stack
- //
- SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
- SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet64 (PcdFvBaseAddress);
- SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdFvSize);
- SecCoreData.TemporaryRamBase = (VOID *)TemporaryRamBase; // We run on the primary core (and so we use the first stack)
- SecCoreData.TemporaryRamSize = TemporaryRamSize;
- SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
- SecCoreData.PeiTemporaryRamSize = ALIGN_VALUE (SecCoreData.TemporaryRamSize / 2, CPU_STACK_ALIGNMENT);
- SecCoreData.StackBase = (VOID *)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize);
- SecCoreData.StackSize = (TemporaryRamBase + TemporaryRamSize) - (UINTN)SecCoreData.StackBase;
-
- // Jump to PEI core entry point
- (PeiCoreEntryPoint)(&SecCoreData, PpiList);
-}
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
deleted file mode 100644
index 42a7ccc..0000000
--- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/** @file
- Main file supporting the transition to PEI Core in Normal World for Versatile Express
-
- Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Library/BaseLib.h>
-#include <Library/CacheMaintenanceLib.h>
-#include <Library/DebugAgentLib.h>
-#include <Library/ArmLib.h>
-#include <Library/PrintLib.h>
-#include <Library/SerialPortLib.h>
-
-#include "PrePeiCore.h"
-
-CONST EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = { PrePeiCoreTemporaryRamSupport };
-
-CONST EFI_PEI_PPI_DESCRIPTOR gCommonPpiTable[] = {
- {
- EFI_PEI_PPI_DESCRIPTOR_PPI,
- &gEfiTemporaryRamSupportPpiGuid,
- (VOID *)&mTemporaryRamSupportPpi
- }
-};
-
-VOID
-CreatePpiList (
- OUT UINTN *PpiListSize,
- OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
- )
-{
- EFI_PEI_PPI_DESCRIPTOR *PlatformPpiList;
- UINTN PlatformPpiListSize;
- UINTN ListBase;
- EFI_PEI_PPI_DESCRIPTOR *LastPpi;
-
- // Get the Platform PPIs
- PlatformPpiListSize = 0;
- ArmPlatformGetPlatformPpiList (&PlatformPpiListSize, &PlatformPpiList);
-
- // Copy the Common and Platform PPis in Temporary Memory
- ListBase = PcdGet64 (PcdCPUCoresStackBase);
- CopyMem ((VOID *)ListBase, gCommonPpiTable, sizeof (gCommonPpiTable));
- CopyMem ((VOID *)(ListBase + sizeof (gCommonPpiTable)), PlatformPpiList, PlatformPpiListSize);
-
- // Set the Terminate flag on the last PPI entry
- LastPpi = (EFI_PEI_PPI_DESCRIPTOR *)ListBase + ((sizeof (gCommonPpiTable) + PlatformPpiListSize) / sizeof (EFI_PEI_PPI_DESCRIPTOR)) - 1;
- LastPpi->Flags |= EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
-
- *PpiList = (EFI_PEI_PPI_DESCRIPTOR *)ListBase;
- *PpiListSize = sizeof (gCommonPpiTable) + PlatformPpiListSize;
-}
-
-/**
-
- Prints firmware version and build time to serial console.
-
-**/
-STATIC
-VOID
-PrintFirmwareVersion (
- VOID
- )
-{
- CHAR8 Buffer[100];
- UINTN CharCount;
-
- CharCount = AsciiSPrint (
- Buffer,
- sizeof (Buffer),
- "UEFI firmware (version %s built at %a on %a)\n\r",
- (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString),
- __TIME__,
- __DATE__
- );
- SerialPortWrite ((UINT8 *)Buffer, CharCount);
-}
-
-VOID
-CEntryPoint (
- IN UINTN MpId,
- IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
- )
-{
- if (!ArmMmuEnabled ()) {
- // Data Cache enabled on Primary core when MMU is enabled.
- ArmDisableDataCache ();
- // Invalidate instruction cache
- ArmInvalidateInstructionCache ();
- // Enable Instruction Caches on all cores.
- ArmEnableInstructionCache ();
-
- InvalidateDataCacheRange (
- (VOID *)(UINTN)PcdGet64 (PcdCPUCoresStackBase),
- PcdGet32 (PcdCPUCorePrimaryStackSize)
- );
- }
-
- //
- // Note: Doesn't have to Enable CPU interface in non-secure world,
- // as Non-secure interface is already enabled in Secure world.
- //
-
- // Write VBAR - The Exception Vector table must be aligned to its requirement
- // Note: The AArch64 Vector table must be 2k-byte aligned - if this assertion fails ensure
- // 'Align=4K' is defined into your FDF for this module.
- ASSERT (((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
- ArmWriteVBar ((UINTN)PeiVectorTable);
-
- // Enable Floating Point
- if (FixedPcdGet32 (PcdVFPEnabled)) {
- ArmEnableVFP ();
- }
-
- // Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on.
-
- // If not primary Jump to Secondary Main
- if (ArmPlatformIsPrimaryCore (MpId)) {
- // Invoke "ProcessLibraryConstructorList" to have all library constructors
- // called.
- ProcessLibraryConstructorList ();
-
- PrintFirmwareVersion ();
-
- // Initialize the Debug Agent for Source Level Debugging
- InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
- SaveAndSetDebugTimerInterrupt (TRUE);
-
- // Initialize the platform specific controllers
- ArmPlatformInitialize (MpId);
-
- // Goto primary Main.
- PrimaryMain (PeiCoreEntryPoint);
- } else {
- SecondaryMain (MpId);
- }
-
- // PEI Core should always load and never return
- ASSERT (FALSE);
-}
-
-EFI_STATUS
-EFIAPI
-PrePeiCoreTemporaryRamSupport (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
- IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
- IN UINTN CopySize
- )
-{
- VOID *OldHeap;
- VOID *NewHeap;
- VOID *OldStack;
- VOID *NewStack;
- UINTN HeapSize;
-
- HeapSize = ALIGN_VALUE (CopySize / 2, CPU_STACK_ALIGNMENT);
-
- OldHeap = (VOID *)(UINTN)TemporaryMemoryBase;
- NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize - HeapSize));
-
- OldStack = (VOID *)((UINTN)TemporaryMemoryBase + HeapSize);
- NewStack = (VOID *)(UINTN)PermanentMemoryBase;
-
- //
- // Migrate the temporary memory stack to permanent memory stack.
- //
- CopyMem (NewStack, OldStack, CopySize - HeapSize);
-
- //
- // Migrate the temporary memory heap to permanent memory heap.
- //
- CopyMem (NewHeap, OldHeap, HeapSize);
-
- SecSwitchStack ((UINTN)NewStack - (UINTN)OldStack);
-
- return EFI_SUCCESS;
-}
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.h b/ArmPlatformPkg/PrePeiCore/PrePeiCore.h
deleted file mode 100644
index fbf6207..0000000
--- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/** @file
- Main file supporting the transition to PEI Core in Normal World for Versatile Express
-
- Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __PREPEICORE_H_
-#define __PREPEICORE_H_
-
-#include <Library/ArmLib.h>
-#include <Library/ArmPlatformLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/IoLib.h>
-#include <Library/PcdLib.h>
-
-#include <PiPei.h>
-#include <Ppi/TemporaryRamSupport.h>
-
-VOID
-CreatePpiList (
- OUT UINTN *PpiListSize,
- OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
- );
-
-EFI_STATUS
-EFIAPI
-PrePeiCoreTemporaryRamSupport (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
- IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
- IN UINTN CopySize
- );
-
-VOID
-SecSwitchStack (
- INTN StackDelta
- );
-
-// Vector Table for Pei Phase
-VOID
-PeiVectorTable (
- VOID
- );
-
-VOID
-EFIAPI
-PrimaryMain (
- IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
- );
-
-/*
- * This is the main function for secondary cores. They loop around until a non Null value is written to
- * SYS_FLAGS register.The SYS_FLAGS register is platform specific.
- * Note:The secondary cores, while executing secondary_main, assumes that:
- * : SGI 0 is configured as Non-secure interrupt
- * : Priority Mask is configured to allow SGI 0
- * : Interrupt Distributor and CPU interfaces are enabled
- *
- */
-VOID
-EFIAPI
-SecondaryMain (
- IN UINTN MpId
- );
-
-VOID
-PeiCommonExceptionEntry (
- IN UINT32 Entry,
- IN UINTN LR
- );
-
-#endif
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
deleted file mode 100644
index c5cad7e..0000000
--- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+++ /dev/null
@@ -1,76 +0,0 @@
-#/** @file
-# Pre PeiCore - Hand-off to PEI Core in Normal World
-#
-# Copyright (c) 2011-2014, ARM Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#**/
-
-[Defines]
- INF_VERSION = 1.30
- BASE_NAME = ArmPlatformPrePeiCore
- FILE_GUID = b78d02bb-d0b5-4389-bc7f-b39ee846c784
- MODULE_TYPE = SEC
- VERSION_STRING = 1.0
-
-[Sources.common]
- MainMPCore.c
- PrePeiCore.h
- PrePeiCore.c
-
-[Sources.ARM]
- Arm/ArchPrePeiCore.c
- Arm/PrePeiCoreEntryPoint.S | GCC
- Arm/SwitchStack.S | GCC
- Arm/Exception.S | GCC
-
-[Sources.AARCH64]
- AArch64/ArchPrePeiCore.c
- AArch64/PrePeiCoreEntryPoint.S
- AArch64/SwitchStack.S
- AArch64/Exception.S
- AArch64/Helper.S
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- ArmPkg/ArmPkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
-
-[LibraryClasses]
- ArmLib
- ArmPlatformLib
- CacheMaintenanceLib
- BaseLib
- DebugLib
- DebugAgentLib
- IoLib
- ArmGicLib
- PrintLib
- SerialPortLib
-
-[Ppis]
- gEfiTemporaryRamSupportPpiGuid
- gArmMpCoreInfoPpiGuid
-
-[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
-
-[FeaturePcd]
- gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
-
-[FixedPcd]
- gArmTokenSpaceGuid.PcdFvBaseAddress
- gArmTokenSpaceGuid.PcdFvSize
- gArmTokenSpaceGuid.PcdVFPEnabled
-
- gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase
- gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
-
- gArmTokenSpaceGuid.PcdGicDistributorBase
- gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
- gArmTokenSpaceGuid.PcdGicSgiIntId
-
- gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack
diff --git a/ArmPlatformPkg/PrePi/MainMPCore.c b/ArmPlatformPkg/PrePi/MainMPCore.c
deleted file mode 100644
index 68a7c13..0000000
--- a/ArmPlatformPkg/PrePi/MainMPCore.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/** @file
-
- Copyright (c) 2011-2014, ARM Limited. All rights reserved.
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "PrePi.h"
-
-#include <Library/ArmGicLib.h>
-
-#include <Ppi/ArmMpCoreInfo.h>
-
-VOID
-PrimaryMain (
- IN UINTN UefiMemoryBase,
- IN UINTN StacksBase,
- IN UINT64 StartTimeStamp
- )
-{
- // Enable the GIC Distributor
- ArmGicEnableDistributor (PcdGet64 (PcdGicDistributorBase));
-
- // In some cases, the secondary cores are waiting for an SGI from the next stage boot loader to resume their initialization
- if (!FixedPcdGet32 (PcdSendSgiToBringUpSecondaryCores)) {
- // Sending SGI to all the Secondary CPU interfaces
- ArmGicSendSgiTo (PcdGet64 (PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));
- }
-
- PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
-
- // We must never return
- ASSERT (FALSE);
-}
-
-VOID
-SecondaryMain (
- IN UINTN MpId
- )
-{
- EFI_STATUS Status;
- ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
- UINTN Index;
- UINTN ArmCoreCount;
- ARM_CORE_INFO *ArmCoreInfoTable;
- UINT32 ClusterId;
- UINT32 CoreId;
-
- VOID (*SecondaryStart)(
- VOID
- );
- UINTN SecondaryEntryAddr;
- UINTN AcknowledgeInterrupt;
- UINTN InterruptId;
-
- ClusterId = GET_CLUSTER_ID (MpId);
- CoreId = GET_CORE_ID (MpId);
-
- // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
- Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID **)&ArmMpCoreInfoPpi);
- ASSERT_EFI_ERROR (Status);
-
- ArmCoreCount = 0;
- Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
- ASSERT_EFI_ERROR (Status);
-
- // Find the core in the ArmCoreTable
- for (Index = 0; Index < ArmCoreCount; Index++) {
- if ((GET_MPIDR_AFF1 (ArmCoreInfoTable[Index].Mpidr) == ClusterId) &&
- (GET_MPIDR_AFF0 (ArmCoreInfoTable[Index].Mpidr) == CoreId))
- {
- break;
- }
- }
-
- // The ARM Core Info Table must define every core
- ASSERT (Index != ArmCoreCount);
-
- // Clear Secondary cores MailBox
- MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue);
-
- do {
- ArmCallWFI ();
-
- // Read the Mailbox
- SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress);
-
- // Acknowledge the interrupt and send End of Interrupt signal.
- AcknowledgeInterrupt = ArmGicAcknowledgeInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), &InterruptId);
- // Check if it is a valid interrupt ID
- if (InterruptId < ArmGicGetMaxNumInterrupts (PcdGet64 (PcdGicDistributorBase))) {
- // Got a valid SGI number hence signal End of Interrupt
- ArmGicEndOfInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), AcknowledgeInterrupt);
- }
- } while (SecondaryEntryAddr == 0);
-
- // Jump to secondary core entry point.
- SecondaryStart = (VOID (*)()) SecondaryEntryAddr;
- SecondaryStart ();
-
- // The secondaries shouldn't reach here
- ASSERT (FALSE);
-}
diff --git a/ArmPlatformPkg/PrePi/MainUniCore.c b/ArmPlatformPkg/PrePi/MainUniCore.c
deleted file mode 100644
index 6162d12..0000000
--- a/ArmPlatformPkg/PrePi/MainUniCore.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/** @file
-
- Copyright (c) 2011, ARM Limited. All rights reserved.
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "PrePi.h"
-
-VOID
-PrimaryMain (
- IN UINTN UefiMemoryBase,
- IN UINTN StacksBase,
- IN UINT64 StartTimeStamp
- )
-{
- PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
-
- // We must never return
- ASSERT (FALSE);
-}
-
-VOID
-SecondaryMain (
- IN UINTN MpId
- )
-{
- // We must never get into this function on UniCore system
- ASSERT (FALSE);
-}
diff --git a/ArmPlatformPkg/PrePi/PeiMPCore.inf b/ArmPlatformPkg/PrePi/PeiMPCore.inf
deleted file mode 100644
index 0b13b72..0000000
--- a/ArmPlatformPkg/PrePi/PeiMPCore.inf
+++ /dev/null
@@ -1,106 +0,0 @@
-#/** @file
-#
-# (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
-# Copyright (c) 2011-2017, ARM Ltd. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#**/
-
-[Defines]
- INF_VERSION = 1.30
- BASE_NAME = ArmPlatformPrePiMPCore
- FILE_GUID = d959e387-7b91-452c-90e0-a1dbac90ddb8
- MODULE_TYPE = SEC
- VERSION_STRING = 1.0
-
-[Sources]
- PrePi.h
- PrePi.c
- MainMPCore.c
-
-[Sources.ARM]
- Arm/ArchPrePi.c
- Arm/ModuleEntryPoint.S | GCC
-
-[Sources.AArch64]
- AArch64/ArchPrePi.c
- AArch64/ModuleEntryPoint.S
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- EmbeddedPkg/EmbeddedPkg.dec
- ArmPkg/ArmPkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
-
-[LibraryClasses]
- BaseLib
- CacheMaintenanceLib
- DebugLib
- DebugAgentLib
- ArmLib
- ArmGicLib
- IoLib
- TimerLib
- SerialPortLib
- ExtractGuidedSectionLib
- LzmaDecompressLib
- DebugAgentLib
- PrePiLib
- ArmPlatformLib
- ArmPlatformStackLib
- MemoryAllocationLib
- HobLib
- PrePiHobListPointerLib
- PlatformPeiLib
- MemoryInitPeiLib
-
-[Ppis]
- gArmMpCoreInfoPpiGuid
-
-[Guids]
- gArmMpCoreInfoGuid
- gEfiFirmwarePerformanceGuid
-
-[FeaturePcd]
- gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
- gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
-
-[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
-
-[FixedPcd]
- gArmTokenSpaceGuid.PcdVFPEnabled
-
- gArmTokenSpaceGuid.PcdFdBaseAddress
- gArmTokenSpaceGuid.PcdFdSize
-
- gArmTokenSpaceGuid.PcdFvBaseAddress
- gArmTokenSpaceGuid.PcdFvSize
-
- gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
-
- gArmTokenSpaceGuid.PcdGicDistributorBase
- gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
- gArmTokenSpaceGuid.PcdGicSgiIntId
-
- gArmTokenSpaceGuid.PcdSystemMemoryBase
- gArmTokenSpaceGuid.PcdSystemMemorySize
- gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
-
- gArmPlatformTokenSpaceGuid.PcdCoreCount
-
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
-
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
-
diff --git a/ArmPlatformPkg/PrePi/PrePi.h b/ArmPlatformPkg/PrePi/PrePi.h
deleted file mode 100644
index 1d47ba2..0000000
--- a/ArmPlatformPkg/PrePi/PrePi.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/** @file
-
- Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _PREPI_H_
-#define _PREPI_H_
-
-#include <PiPei.h>
-
-#include <Library/PcdLib.h>
-#include <Library/ArmLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/IoLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/HobLib.h>
-#include <Library/SerialPortLib.h>
-#include <Library/ArmPlatformLib.h>
-
-extern UINT64 mSystemMemoryEnd;
-
-RETURN_STATUS
-EFIAPI
-TimerConstructor (
- VOID
- );
-
-VOID
-PrePiMain (
- IN UINTN UefiMemoryBase,
- IN UINTN StacksBase,
- IN UINT64 StartTimeStamp
- );
-
-EFI_STATUS
-EFIAPI
-MemoryPeim (
- IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
- IN UINT64 UefiMemorySize
- );
-
-EFI_STATUS
-EFIAPI
-PlatformPeim (
- VOID
- );
-
-VOID
-PrimaryMain (
- IN UINTN UefiMemoryBase,
- IN UINTN StacksBase,
- IN UINT64 StartTimeStamp
- );
-
-VOID
-SecondaryMain (
- IN UINTN MpId
- );
-
-// Either implemented by PrePiLib or by MemoryInitPei
-VOID
-BuildMemoryTypeInformationHob (
- VOID
- );
-
-EFI_STATUS
-GetPlatformPpi (
- IN EFI_GUID *PpiGuid,
- OUT VOID **Ppi
- );
-
-// Initialize the Architecture specific controllers
-VOID
-ArchInitialize (
- VOID
- );
-
-#endif /* _PREPI_H_ */
diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c b/ArmPlatformPkg/Sec/AArch64/ArchSec.c
index 2dc77f4..371f2b9 100644
--- a/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c
+++ b/ArmPlatformPkg/Sec/AArch64/ArchSec.c
@@ -1,5 +1,5 @@
/** @file
- Main file supporting the transition to PEI Core in Normal World for Versatile Express
+ Architecture specific handling of CPU exceptions taken while running in PEI.
Copyright (c) 2012-2013, ARM Limited. All rights reserved.
@@ -7,11 +7,14 @@
**/
-#include <Library/PrintLib.h>
-#include <Library/SerialPortLib.h>
+#include "Sec.h"
-#include "PrePeiCore.h"
+/**
+ Minimal high level handling of exceptions occurring in PEI.
+ @param[in] Entry Type of exception
+ @param[in] LR Address of instruction where the exception was taken
+**/
VOID
PeiCommonExceptionEntry (
IN UINT32 Entry,
diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S b/ArmPlatformPkg/Sec/AArch64/Exception.S
index d0d6bc4..433761e 100644
--- a/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S
+++ b/ArmPlatformPkg/Sec/AArch64/Exception.S
@@ -6,7 +6,7 @@
#
#include <AArch64/AArch64.h>
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
#include <Base.h>
#include <AutoGen.h>
diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S b/ArmPlatformPkg/Sec/AArch64/Helper.S
index 9b81b96..c784c4a 100644
--- a/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S
+++ b/ArmPlatformPkg/Sec/AArch64/Helper.S
@@ -5,7 +5,7 @@
#
#=======================================================================================
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
#include <AArch64/AArch64.h>
// Setup EL1 while in EL1
diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S b/ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S
index 8ecec23..154be11 100644
--- a/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S
+++ b/ArmPlatformPkg/Sec/AArch64/ModuleEntryPoint.S
@@ -5,7 +5,7 @@
//
//
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
ASM_FUNC(_ModuleEntryPoint)
// Do early platform specific actions
@@ -30,41 +30,23 @@ ASM_FUNC(_ModuleEntryPoint)
b ASM_PFX(MainEntryPoint)
ASM_PFX(MainEntryPoint):
- // Identify CPU ID
- bl ASM_PFX(ArmReadMpidr)
- // Keep a copy of the MpId register value
- mov x5, x0
-
- // Is it the Primary Core ?
- bl ASM_PFX(ArmPlatformIsPrimaryCore)
-
// Get the top of the primary stacks (and the base of the secondary stacks)
MOV64 (x1, FixedPcdGet64(PcdCPUCoresStackBase) + FixedPcdGet32(PcdCPUCorePrimaryStackSize))
- // x0 is equal to 1 if I am the primary core
- cmp x0, #1
- b.eq _SetupPrimaryCoreStack
-
-_SetupSecondaryCoreStack:
- // x1 contains the base of the secondary stacks
-
- // Get the Core Position
- mov x6, x1 // Save base of the secondary stacks
- mov x0, x5
- bl ASM_PFX(ArmPlatformGetCorePosition)
- // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack
- add x0, x0, #1
+ // Set up the stack pointer
+ mov sp, x1
- // StackOffset = CorePos * StackSize
- MOV32 (x2, FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
- mul x0, x0, x2
- // SP = StackBase + StackOffset
- add sp, x6, x0
+ // Apply the init value to the entire stack
+ MOV64 (x8, FixedPcdGet64 (PcdCPUCoresStackBase))
+ MOV64 (x9, FixedPcdGet32 (PcdInitValueInTempStack) |\
+ FixedPcdGet32 (PcdInitValueInTempStack) << 32)
+0:stp x9, x9, [x8], #16
+ cmp x8, x1
+ b.lt 0b
-_PrepareArguments:
// The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector
MOV64 (x2, FixedPcdGet64(PcdFvBaseAddress))
- ldr x1, [x2, #8]
+ ldr x0, [x2, #8]
// Move sec startup address into a data register
// Ensure we're jumping to FV version of the code (not boot remapped alias)
@@ -74,17 +56,5 @@ _PrepareArguments:
mov x29, xzr
// Jump to PrePeiCore C code
- // x0 = mp_id
- // x1 = pei_core_address
- mov x0, x5
+ // x0 = pei_core_address
blr x3
-
-_SetupPrimaryCoreStack:
- mov sp, x1
- MOV64 (x8, FixedPcdGet64 (PcdCPUCoresStackBase))
- MOV64 (x9, FixedPcdGet32 (PcdInitValueInTempStack) |\
- FixedPcdGet32 (PcdInitValueInTempStack) << 32)
-0:stp x9, x9, [x8], #16
- cmp x8, x1
- b.lt 0b
- b _PrepareArguments
diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S b/ArmPlatformPkg/Sec/AArch64/SwitchStack.S
index 308b876..7074040 100644
--- a/ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S
+++ b/ArmPlatformPkg/Sec/AArch64/SwitchStack.S
@@ -8,7 +8,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
#/**
# This allows the caller to switch the stack and return
diff --git a/ArmPlatformPkg/PrePeiCore/Arm/ArchPrePeiCore.c b/ArmPlatformPkg/Sec/Arm/ArchSec.c
index debf328..0c1e499 100644
--- a/ArmPlatformPkg/PrePeiCore/Arm/ArchPrePeiCore.c
+++ b/ArmPlatformPkg/Sec/Arm/ArchSec.c
@@ -1,5 +1,5 @@
/** @file
- Main file supporting the transition to PEI Core in Normal World for Versatile Express
+ Architecture specific handling of CPU exceptions taken while running in PEI.
Copyright (c) 2012, ARM Limited. All rights reserved.
@@ -7,11 +7,14 @@
**/
-#include <Library/PrintLib.h>
-#include <Library/SerialPortLib.h>
+#include "Sec.h"
-#include "PrePeiCore.h"
+/**
+ Minimal high level handling of exceptions occurring in PEI.
+ @param[in] Entry Type of exception
+ @param[in] LR Address of instruction where the exception was taken
+**/
VOID
PeiCommonExceptionEntry (
IN UINT32 Entry,
diff --git a/ArmPlatformPkg/PrePeiCore/Arm/Exception.S b/ArmPlatformPkg/Sec/Arm/Exception.S
index 956ae84..364b512 100644
--- a/ArmPlatformPkg/PrePeiCore/Arm/Exception.S
+++ b/ArmPlatformPkg/Sec/Arm/Exception.S
@@ -5,7 +5,7 @@
#
#
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
#include <Base.h>
#include <AutoGen.h>
diff --git a/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S b/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S
new file mode 100644
index 0000000..1207497
--- /dev/null
+++ b/ArmPlatformPkg/Sec/Arm/ModuleEntryPoint.S
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroLib.h>
+
+ASM_FUNC(_ModuleEntryPoint)
+ // Do early platform specific actions
+ bl ASM_PFX(ArmPlatformPeiBootAction)
+
+ // Get the top of the primary stacks (and the base of the secondary stacks)
+ MOV32 (r1, FixedPcdGet64(PcdCPUCoresStackBase) + FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+
+ // Set up the stack pointer
+ mov sp, r1
+
+ // Apply the init value to the entire stack
+ MOV32 (r8, FixedPcdGet64 (PcdCPUCoresStackBase))
+ MOV32 (r9, FixedPcdGet32 (PcdInitValueInTempStack))
+ mov r10, r9
+ mov r11, r9
+ mov r12, r9
+0:stm r8!, {r9-r12}
+ cmp r8, r1
+ blt 0b
+
+ // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector
+ MOV32 (r2, FixedPcdGet32(PcdFvBaseAddress))
+ ldr r0, [r2, #4]
+
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
+ ldr r3, =ASM_PFX(CEntryPoint)
+
+ // Jump to PrePeiCore C code
+ // r0 = pei_core_address
+ blx r3
diff --git a/ArmPlatformPkg/PrePeiCore/Arm/SwitchStack.S b/ArmPlatformPkg/Sec/Arm/SwitchStack.S
index d64772b..028ee26 100644
--- a/ArmPlatformPkg/PrePeiCore/Arm/SwitchStack.S
+++ b/ArmPlatformPkg/Sec/Arm/SwitchStack.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
#/**
# This allows the caller to switch the stack and return
diff --git a/ArmPlatformPkg/Sec/Sec.c b/ArmPlatformPkg/Sec/Sec.c
new file mode 100644
index 0000000..9a700e5
--- /dev/null
+++ b/ArmPlatformPkg/Sec/Sec.c
@@ -0,0 +1,249 @@
+/** @file
+ Generic SEC driver for ARM platforms
+
+ Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Sec.h"
+
+/**
+ This service of the EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI that migrates temporary
+ RAM into permanent memory.
+
+ @param PeiServices Pointer to the PEI Services Table.
+ @param TemporaryMemoryBase Source Address in temporary memory from which
+ the SEC or PEIM will copy the Temporary RAM
+ contents.
+ @param PermanentMemoryBase Destination Address in permanent memory into
+ which the SEC or PEIM will copy the Temporary
+ RAM contents.
+ @param CopySize Amount of memory to migrate from temporary to
+ permanent memory.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize >
+ TemporaryMemoryBase when TemporaryMemoryBase >
+ PermanentMemoryBase.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupport (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ )
+{
+ VOID *OldHeap;
+ VOID *NewHeap;
+ VOID *OldStack;
+ VOID *NewStack;
+ UINTN HeapSize;
+
+ HeapSize = ALIGN_VALUE (CopySize / 2, CPU_STACK_ALIGNMENT);
+
+ OldHeap = (VOID *)(UINTN)TemporaryMemoryBase;
+ NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize - HeapSize));
+
+ OldStack = (VOID *)((UINTN)TemporaryMemoryBase + HeapSize);
+ NewStack = (VOID *)(UINTN)PermanentMemoryBase;
+
+ //
+ // Migrate the temporary memory stack to permanent memory stack.
+ //
+ CopyMem (NewStack, OldStack, CopySize - HeapSize);
+
+ //
+ // Migrate the temporary memory heap to permanent memory heap.
+ //
+ CopyMem (NewHeap, OldHeap, HeapSize);
+
+ SecSwitchStack ((UINTN)NewStack - (UINTN)OldStack);
+
+ return EFI_SUCCESS;
+}
+
+STATIC CONST EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
+ SecTemporaryRamSupport
+};
+
+STATIC CONST EFI_PEI_PPI_DESCRIPTOR gCommonPpiTable[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gEfiTemporaryRamSupportPpiGuid,
+ (VOID *)&mTemporaryRamSupportPpi
+ }
+};
+
+/**
+ Construct a PPI list from the PPIs provided in this file and the ones
+ provided by the platform code.
+
+ @param[out] PpiListSize Size of the PPI list in bytes
+ @param[out] PpiList Pointer to the constructed PPI list
+**/
+STATIC
+VOID
+CreatePpiList (
+ OUT UINTN *PpiListSize,
+ OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
+ )
+{
+ EFI_PEI_PPI_DESCRIPTOR *PlatformPpiList;
+ UINTN PlatformPpiListSize;
+ UINTN ListBase;
+ EFI_PEI_PPI_DESCRIPTOR *LastPpi;
+
+ // Get the Platform PPIs
+ PlatformPpiListSize = 0;
+ ArmPlatformGetPlatformPpiList (&PlatformPpiListSize, &PlatformPpiList);
+
+ // Copy the Common and Platform PPis in Temporary Memory
+ ListBase = PcdGet64 (PcdCPUCoresStackBase);
+ CopyMem ((VOID *)ListBase, gCommonPpiTable, sizeof (gCommonPpiTable));
+ CopyMem ((VOID *)(ListBase + sizeof (gCommonPpiTable)), PlatformPpiList, PlatformPpiListSize);
+
+ // Set the Terminate flag on the last PPI entry
+ LastPpi = (EFI_PEI_PPI_DESCRIPTOR *)ListBase +
+ ((sizeof (gCommonPpiTable) + PlatformPpiListSize) / sizeof (EFI_PEI_PPI_DESCRIPTOR)) - 1;
+ LastPpi->Flags |= EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+
+ *PpiList = (EFI_PEI_PPI_DESCRIPTOR *)ListBase;
+ *PpiListSize = sizeof (gCommonPpiTable) + PlatformPpiListSize;
+}
+
+/**
+
+ Prints firmware version and build time to serial console.
+
+**/
+STATIC
+VOID
+PrintFirmwareVersion (
+ VOID
+ )
+{
+ CHAR8 Buffer[100];
+ UINTN CharCount;
+
+ CharCount = AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "UEFI firmware (version %s built at %a on %a)\n\r",
+ (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString),
+ __TIME__,
+ __DATE__
+ );
+
+ // Because we are directly bit banging the serial port instead of going through the DebugLib, we need to make sure
+ // the serial port is initialized before we write to it
+ SerialPortInitialize ();
+ SerialPortWrite ((UINT8 *)Buffer, CharCount);
+}
+
+/**
+ SEC main routine.
+
+ @param[in] PeiCoreEntryPoint Address in ram of the entrypoint of the PEI
+ core
+**/
+STATIC
+VOID
+EFIAPI
+SecMain (
+ IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
+ )
+{
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+ UINTN PpiListSize;
+ EFI_PEI_PPI_DESCRIPTOR *PpiList;
+ UINTN TemporaryRamBase;
+ UINTN TemporaryRamSize;
+
+ CreatePpiList (&PpiListSize, &PpiList);
+
+ // Adjust the Temporary Ram as the new Ppi List (Common + Platform Ppi Lists) is created at
+ // the base of the primary core stack
+ PpiListSize = ALIGN_VALUE (PpiListSize, CPU_STACK_ALIGNMENT);
+ TemporaryRamBase = (UINTN)PcdGet64 (PcdCPUCoresStackBase) + PpiListSize;
+ TemporaryRamSize = (UINTN)PcdGet32 (PcdCPUCorePrimaryStackSize) - PpiListSize;
+
+ //
+ // Bind this information into the SEC hand-off state
+ // Note: this must be in sync with the stuff in the asm file
+ // Note also: HOBs (pei temp ram) MUST be above stack
+ //
+ SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
+ SecCoreData.BootFirmwareVolumeBase = (VOID *)(UINTN)PcdGet64 (PcdFvBaseAddress);
+ SecCoreData.BootFirmwareVolumeSize = PcdGet32 (PcdFvSize);
+ SecCoreData.TemporaryRamBase = (VOID *)TemporaryRamBase; // We run on the primary core (and so we use the first stack)
+ SecCoreData.TemporaryRamSize = TemporaryRamSize;
+ SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.PeiTemporaryRamSize = ALIGN_VALUE (SecCoreData.TemporaryRamSize / 2, CPU_STACK_ALIGNMENT);
+ SecCoreData.StackBase = (VOID *)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize);
+ SecCoreData.StackSize = (TemporaryRamBase + TemporaryRamSize) - (UINTN)SecCoreData.StackBase;
+
+ // Jump to PEI core entry point
+ (PeiCoreEntryPoint)(&SecCoreData, PpiList);
+}
+
+/**
+ Module C entrypoint.
+
+ @param[in] PeiCoreEntryPoint Address in ram of the entrypoint of the PEI
+ core
+**/
+VOID
+CEntryPoint (
+ IN EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
+ )
+{
+ if (!ArmMmuEnabled ()) {
+ // Data Cache enabled on Primary core when MMU is enabled.
+ ArmDisableDataCache ();
+ // Invalidate instruction cache
+ ArmInvalidateInstructionCache ();
+ // Enable Instruction Caches on all cores.
+ ArmEnableInstructionCache ();
+
+ InvalidateDataCacheRange (
+ (VOID *)(UINTN)PcdGet64 (PcdCPUCoresStackBase),
+ PcdGet32 (PcdCPUCorePrimaryStackSize)
+ );
+ }
+
+ // Write VBAR - The Exception Vector table must be aligned to its requirement
+ // Note: The AArch64 Vector table must be 2k-byte aligned - if this assertion fails ensure
+ // 'Align=4K' is defined into your FDF for this module.
+ ASSERT (((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0);
+ ArmWriteVBar ((UINTN)PeiVectorTable);
+
+ // Enable Floating Point
+ if (FixedPcdGet32 (PcdVFPEnabled)) {
+ ArmEnableVFP ();
+ }
+
+ // Invoke "ProcessLibraryConstructorList" to have all library constructors
+ // called.
+ ProcessLibraryConstructorList ();
+
+ PrintFirmwareVersion ();
+
+ // Initialize the Debug Agent for Source Level Debugging
+ InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
+ SaveAndSetDebugTimerInterrupt (TRUE);
+
+ // Initialize the platform specific controllers
+ ArmPlatformInitialize (ArmReadMpidr ());
+
+ // Goto primary Main.
+ SecMain (PeiCoreEntryPoint);
+
+ // PEI Core should always load and never return
+ ASSERT (FALSE);
+}
diff --git a/ArmPlatformPkg/Sec/Sec.h b/ArmPlatformPkg/Sec/Sec.h
new file mode 100644
index 0000000..56d9f35
--- /dev/null
+++ b/ArmPlatformPkg/Sec/Sec.h
@@ -0,0 +1,54 @@
+/** @file
+ Generic SEC driver for ARM platforms
+
+ Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SEC_H_
+#define SEC_H_
+
+#include <PiPei.h>
+
+#include <Library/ArmLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include <Library/SerialPortLib.h>
+
+#include <Ppi/TemporaryRamSupport.h>
+
+/**
+ Helper function to switch to a different stack. Implemented in assembler as
+ this cannot be done from C code.
+**/
+VOID
+SecSwitchStack (
+ INTN StackDelta
+ );
+
+/**
+ Vector Table for the PEI Phase. This is executable code but not a callable
+ function. Implemented in assembler.
+**/
+VOID
+PeiVectorTable (
+ VOID
+ );
+
+/**
+ Minimal high level handling of exceptions occurring in PEI.
+**/
+VOID
+PeiCommonExceptionEntry (
+ IN UINT32 Entry,
+ IN UINTN LR
+ );
+
+#endif
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf b/ArmPlatformPkg/Sec/Sec.inf
index 1d50b4d..58a566f 100644
--- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
+++ b/ArmPlatformPkg/Sec/Sec.inf
@@ -1,51 +1,50 @@
-#/** @file
-# Pre PeiCore - Hand-off to PEI Core in Normal World
+## @file
+# Generic SEC driver for ARM platforms
#
# Copyright (c) 2011, ARM Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
-#**/
+##
[Defines]
INF_VERSION = 1.30
- BASE_NAME = ArmPlatformPrePeiCore
- FILE_GUID = 469fc080-aec1-11df-927c-0002a5d5c51b
+ BASE_NAME = Sec
+ FILE_GUID = 4c97830a-8e18-4aa6-9fd0-837b089910e2
MODULE_TYPE = SEC
VERSION_STRING = 1.0
[Sources.common]
- PrePeiCore.h
- PrePeiCore.c
- MainUniCore.c
+ Sec.h
+ Sec.c
[Sources.ARM]
- Arm/ArchPrePeiCore.c
- Arm/PrePeiCoreEntryPoint.S | GCC
- Arm/SwitchStack.S | GCC
- Arm/Exception.S | GCC
+ Arm/ArchSec.c
+ Arm/Exception.S
+ Arm/ModuleEntryPoint.S
+ Arm/SwitchStack.S
[Sources.AARCH64]
- AArch64/ArchPrePeiCore.c
- AArch64/PrePeiCoreEntryPoint.S
- AArch64/SwitchStack.S
+ AArch64/ArchSec.c
AArch64/Exception.S
AArch64/Helper.S
+ AArch64/ModuleEntryPoint.S
+ AArch64/SwitchStack.S
[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
+ ArmPkg/ArmPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
[LibraryClasses]
ArmLib
ArmPlatformLib
- CacheMaintenanceLib
BaseLib
- DebugLib
+ BaseMemoryLib
+ CacheMaintenanceLib
DebugAgentLib
- IoLib
+ DebugLib
PrintLib
SerialPortLib
@@ -55,9 +54,6 @@
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
-[FeaturePcd]
- gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
-
[FixedPcd]
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdFvSize
@@ -65,6 +61,5 @@
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack
diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index 0389315..6dd6ce6 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -87,19 +87,6 @@
# Networking Requirements
!include NetworkPkg/NetworkLibs.dsc.inc
-!if $(NETWORK_TLS_ENABLE) == TRUE
- TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
-!endif
-
-
- #
- # It is not possible to prevent the ARM compiler from inserting calls to intrinsic functions.
- # This library provides the instrinsic functions such a compiler may generate calls to.
- #
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- # Add support for GCC stack protector
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
# ARM Architectural Libraries
CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
@@ -114,7 +101,7 @@
PlatformPeiLib|ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
MemoryInitPeiLib|ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.inf
- ResetSystemLib|ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.inf
+ ResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
# ARM PL031 RTC Driver
RealTimeClockLib|ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
@@ -155,7 +142,6 @@
!else
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
!endif
- BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
ArmTrngLib|ArmPkg/Library/ArmTrngLib/ArmTrngLib.inf
ArmMonitorLib|ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
@@ -196,6 +182,9 @@
DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf
!endif
+ # ARM platforms have SEC modules with standard entry points, so we can generically link StackCheckLib
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.PEI_CORE]
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
@@ -232,6 +221,10 @@
DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf
!endif
+[LibraryClasses.common.UEFI_DRIVER]
+ # resolve RngLib via RngDxe's EFI_RNG_PROTOCOL for UEFI_DRIVER type drivers such as TlsDxe
+ RngLib|MdePkg/Library/DxeRngLib/DxeRngLib.inf
+
[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
@@ -262,12 +255,20 @@
!endif
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
-!if $(SECURE_BOOT_ENABLE) == TRUE
+[LibraryClasses.AARCH64.DXE_RUNTIME_DRIVER]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
-!endif
+
+[LibraryClasses.ARM.DXE_RUNTIME_DRIVER]
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf
+
+[LibraryClasses.AARCH64]
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
[LibraryClasses.ARM]
ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf
+ MbedTlsLib|CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
[BuildOptions]
@@ -289,8 +290,6 @@
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
- gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE
-
[PcdsFeatureFlag.AARCH64]
#
# Activate AcpiSdtProtocol
@@ -298,6 +297,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
[PcdsFixedAtBuild.common]
+ gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE
+
!ifdef $(FIRMWARE_VER)
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)"
!endif
@@ -380,8 +381,10 @@
#
# Enable NX memory protection for all non-code regions, including OEM and OS
- # reserved ones, with the exception of LoaderData regions, of which OS loaders
- # (i.e., GRUB) may assume that its contents are executable.
+ # reserved ones.
+ # By passing --pcd PcdDxeNxMemoryProtectionPolicy=0xC000000000007FD1 on the
+ # build command line you can allow code execution in EfiLoaderData. This is
+ # required when using some outdated GRUB versions.
#
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5
diff --git a/ArmVirtPkg/ArmVirtCloudHv.dsc b/ArmVirtPkg/ArmVirtCloudHv.dsc
index 5cb2a60..234a2b5 100644
--- a/ArmVirtPkg/ArmVirtCloudHv.dsc
+++ b/ArmVirtPkg/ArmVirtCloudHv.dsc
@@ -210,7 +210,7 @@
#
# PEI Phase modules
#
- ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
+ ArmPlatformPkg/Sec/Sec.inf
MdeModulePkg/Core/Pei/PeiMain.inf
MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
<LibraryClasses>
diff --git a/ArmVirtPkg/ArmVirtCloudHv.fdf b/ArmVirtPkg/ArmVirtCloudHv.fdf
index 8554efc..5556040 100644
--- a/ArmVirtPkg/ArmVirtCloudHv.fdf
+++ b/ArmVirtPkg/ArmVirtCloudHv.fdf
@@ -236,7 +236,7 @@ READ_STATUS = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
- INF ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
+ INF ArmPlatformPkg/Sec/Sec.inf
INF MdeModulePkg/Core/Pei/PeiMain.inf
INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
INF ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc
index 8688236..c5cf2a7 100644
--- a/ArmVirtPkg/ArmVirtKvmTool.dsc
+++ b/ArmVirtPkg/ArmVirtKvmTool.dsc
@@ -244,7 +244,7 @@
ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf {
<LibraryClasses>
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
- LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
index 6a0e99b..10e4541 100644
--- a/ArmVirtPkg/ArmVirtQemu.dsc
+++ b/ArmVirtPkg/ArmVirtQemu.dsc
@@ -102,15 +102,16 @@
[LibraryClasses.common.PEIM]
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf
-
-!if $(TPM2_ENABLE) == TRUE
- BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
- ResetSystemLib|MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf
+ ArmMonitorLib|ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.inf
+ FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf
-!endif
[LibraryClasses.AARCH64.PEIM]
ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+
+[LibraryClasses.ARM.PEIM]
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf
[LibraryClasses.common.DXE_DRIVER]
AcpiPlatformLib|OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf
@@ -150,10 +151,6 @@
gArmVirtTokenSpaceGuid.PcdTpm2SupportEnabled|$(TPM2_ENABLE)
[PcdsFixedAtBuild.common]
-!if $(ARCH) == AARCH64
- gArmTokenSpaceGuid.PcdVFPEnabled|1
-!endif
-
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress|0x00000000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|$(FD_SIZE)
@@ -244,6 +241,8 @@
# point only, for entry point versions >= 3.0.
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x2
+ gArmTokenSpaceGuid.PcdVFPEnabled|1
+
[PcdsDynamicDefault.common]
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
@@ -298,11 +297,13 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
+!if $(NETWORK_ENABLE) == TRUE
#
# IPv4 and IPv6 PXE Boot support.
#
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
+!endif
#
# TPM2 support
@@ -344,7 +345,7 @@
#
# PEI Phase modules
#
- ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
+ ArmPlatformPkg/Sec/Sec.inf
MdeModulePkg/Core/Pei/PeiMain.inf
ArmPlatformPkg/PlatformPei/PlatformPeim.inf
ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf
@@ -355,10 +356,7 @@
<LibraryClasses>
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
}
- MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf {
- <LibraryClasses>
- ResetSystemLib|ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf
- }
+ MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf
OvmfPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {
<LibraryClasses>
diff --git a/ArmVirtPkg/ArmVirtQemu.fdf b/ArmVirtPkg/ArmVirtQemu.fdf
index 764f652..ac2040a 100644
--- a/ArmVirtPkg/ArmVirtQemu.fdf
+++ b/ArmVirtPkg/ArmVirtQemu.fdf
@@ -104,7 +104,7 @@ READ_STATUS = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
- INF ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
+ INF ArmPlatformPkg/Sec/Sec.inf
INF MdeModulePkg/Core/Pei/PeiMain.inf
INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
INF ArmVirtPkg/MemoryInitPei/MemoryInitPeim.inf
diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc
index 4e8ed6c..c5fdcfd 100644
--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
@@ -260,11 +260,13 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
+!if $(NETWORK_ENABLE) == TRUE
#
# IPv4 and IPv6 PXE Boot support.
#
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
+!endif
################################################################################
#
@@ -278,7 +280,7 @@
ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf {
<LibraryClasses>
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
- LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc
index 6c1190d..fd4f887 100644
--- a/ArmVirtPkg/ArmVirtXen.dsc
+++ b/ArmVirtPkg/ArmVirtXen.dsc
@@ -144,7 +144,7 @@
ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf {
<LibraryClasses>
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
- LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
diff --git a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c
index 68b9d2b..96fbea3 100644
--- a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c
+++ b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.c
@@ -662,7 +662,9 @@ GetStandardNameSpaceObject (
//
Status = DynamicPlatRepoGetObject (
PlatformRepo->DynamicPlatformRepo,
- CREATE_CM_ARM_OBJECT_ID (EArmObjPciConfigSpaceInfo),
+ CREATE_CM_ARCH_COMMON_OBJECT_ID (
+ EArchCommonObjPciConfigSpaceInfo
+ ),
CM_NULL_TOKEN,
&CmObjDesc
);
@@ -723,7 +725,7 @@ GetStandardNameSpaceObject (
}
/**
- Return an ARM namespace object.
+ Return an ArchCommon namespace object.
@param [in] This Pointer to the Configuration Manager Protocol.
@param [in] CmObjectId The Configuration Manager Object ID.
@@ -738,7 +740,7 @@ GetStandardNameSpaceObject (
**/
EFI_STATUS
EFIAPI
-GetArmNameSpaceObject (
+GetArchCommonNameSpaceObject (
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
IN CONST CM_OBJECT_ID CmObjectId,
IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
@@ -761,7 +763,7 @@ GetArmNameSpaceObject (
// First check among the static objects.
//
switch (GET_CM_OBJECT_ID (CmObjectId)) {
- case EArmObjPowerManagementProfileInfo:
+ case EArchCommonObjPowerManagementProfileInfo:
Status = HandleCmObject (
CmObjectId,
&PlatformRepo->PmProfileInfo,
@@ -771,6 +773,73 @@ GetArmNameSpaceObject (
);
break;
+ default:
+ //
+ // No match found among the static objects.
+ // Check the dynamic objects.
+ //
+ Status = DynamicPlatRepoGetObject (
+ PlatformRepo->DynamicPlatformRepo,
+ CmObjectId,
+ Token,
+ CmObject
+ );
+ break;
+ } // switch
+
+ if (Status == EFI_NOT_FOUND) {
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: CmObjectId " FMT_CM_OBJECT_ID ". Status = %r\n",
+ CmObjectId,
+ Status
+ ));
+ } else {
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return Status;
+}
+
+/**
+ Return an ARM namespace object.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token An optional token identifying the object. If
+ unused this must be CM_NULL_TOKEN.
+ @param [in, out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+**/
+EFI_STATUS
+EFIAPI
+GetArmNameSpaceObject (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
+ IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject
+ )
+{
+ EFI_STATUS Status;
+ EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo;
+
+ if ((This == NULL) || (CmObject == NULL)) {
+ ASSERT (This != NULL);
+ ASSERT (CmObject != NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EFI_NOT_FOUND;
+ PlatformRepo = This->PlatRepoInfo;
+
+ //
+ // First check among the static objects.
+ //
+ switch (GET_CM_OBJECT_ID (CmObjectId)) {
case EArmObjItsGroup:
Status = HandleCmObject (
CmObjectId,
@@ -929,6 +998,9 @@ ArmKvmtoolPlatformGetObject (
case EObjNameSpaceStandard:
Status = GetStandardNameSpaceObject (This, CmObjectId, Token, CmObject);
break;
+ case EObjNameSpaceArchCommon:
+ Status = GetArchCommonNameSpaceObject (This, CmObjectId, Token, CmObject);
+ break;
case EObjNameSpaceArm:
Status = GetArmNameSpaceObject (This, CmObjectId, Token, CmObject);
break;
diff --git a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h
index 3373948..4fb12db 100644
--- a/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h
+++ b/ArmVirtPkg/KvmtoolCfgMgrDxe/ConfigurationManager.h
@@ -73,53 +73,53 @@ typedef struct PlatformRepositoryInfo {
///
/// Configuration Manager Information.
///
- CM_STD_OBJ_CONFIGURATION_MANAGER_INFO CmInfo;
+ CM_STD_OBJ_CONFIGURATION_MANAGER_INFO CmInfo;
///
/// List of ACPI tables
///
- CM_STD_OBJ_ACPI_TABLE_INFO CmAcpiTableList[PLAT_ACPI_TABLE_COUNT];
+ CM_STD_OBJ_ACPI_TABLE_INFO CmAcpiTableList[PLAT_ACPI_TABLE_COUNT];
///
/// Power management profile information
///
- CM_ARM_POWER_MANAGEMENT_PROFILE_INFO PmProfileInfo;
+ CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO PmProfileInfo;
///
/// ITS Group node
///
- CM_ARM_ITS_GROUP_NODE ItsGroupInfo;
+ CM_ARM_ITS_GROUP_NODE ItsGroupInfo;
///
/// ITS Identifier array
///
- CM_ARM_ITS_IDENTIFIER ItsIdentifierArray[1];
+ CM_ARM_ITS_IDENTIFIER ItsIdentifierArray[1];
///
/// PCI Root complex node
///
- CM_ARM_ROOT_COMPLEX_NODE RootComplexInfo;
+ CM_ARM_ROOT_COMPLEX_NODE RootComplexInfo;
///
/// Array of DeviceID mapping
///
- CM_ARM_ID_MAPPING DeviceIdMapping[1];
+ CM_ARM_ID_MAPPING DeviceIdMapping[1];
///
/// Dynamic platform repository.
/// CmObj created by parsing the Kvmtool device tree are stored here.
///
- DYNAMIC_PLATFORM_REPOSITORY_INFO *DynamicPlatformRepo;
+ DYNAMIC_PLATFORM_REPOSITORY_INFO *DynamicPlatformRepo;
///
/// Base address of the FDT.
///
- VOID *FdtBase;
+ VOID *FdtBase;
///
/// A handle to the FDT HwInfoParser.
///
- HW_INFO_PARSER_HANDLE FdtParserHandle;
+ HW_INFO_PARSER_HANDLE FdtParserHandle;
} EDKII_PLATFORM_REPOSITORY_INFO;
#endif // CONFIGURATION_MANAGER_H_
diff --git a/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S
index 5ac7c73..f20395c 100644
--- a/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S
+++ b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S
@@ -5,7 +5,7 @@
//
//
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
.macro mov_i, reg:req, imm:req
movz \reg, :abs_g1:\imm
@@ -101,28 +101,3 @@ ASM_FUNC(ArmPlatformPeiBootAction)
isb
0:b ArmEnableVFP // enable SIMD before entering C code
-
-//UINTN
-//ArmPlatformGetCorePosition (
-// IN UINTN MpId
-// );
-// With this function: CorePos = (ClusterId * 4) + CoreId
-ASM_FUNC(ArmPlatformGetCorePosition)
- mov x0, xzr
- ret
-
-//UINTN
-//ArmPlatformGetPrimaryCoreMpId (
-// VOID
-// );
-ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
- MOV32 (w0, FixedPcdGet32 (PcdArmPrimaryCore))
- ret
-
-//UINTN
-//ArmPlatformIsPrimaryCore (
-// IN UINTN MpId
-// );
-ASM_FUNC(ArmPlatformIsPrimaryCore)
- mov x0, #1
- ret
diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.c b/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.c
deleted file mode 100644
index 1f27b76..0000000
--- a/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/** @file
- Support ResetSystem Runtime call using PSCI calls
-
- Note: A similar library is implemented in
- ArmPkg/Library/ArmPsciResetSystemLib. Similar issues might
- exist in this implementation too.
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
- Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
- Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <PiDxe.h>
-
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/ResetSystemLib.h>
-#include <Library/ArmSmcLib.h>
-#include <Library/ArmHvcLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-
-#include <IndustryStandard/ArmStdSmc.h>
-
-#include <Protocol/FdtClient.h>
-
-STATIC UINT32 mArmPsciMethod;
-
-RETURN_STATUS
-EFIAPI
-ArmPsciResetSystemLibConstructor (
- VOID
- )
-{
- EFI_STATUS Status;
- FDT_CLIENT_PROTOCOL *FdtClient;
- CONST VOID *Prop;
-
- Status = gBS->LocateProtocol (
- &gFdtClientProtocolGuid,
- NULL,
- (VOID **)&FdtClient
- );
- ASSERT_EFI_ERROR (Status);
-
- Status = FdtClient->FindCompatibleNodeProperty (
- FdtClient,
- "arm,psci-0.2",
- "method",
- &Prop,
- NULL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {
- mArmPsciMethod = 1;
- } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) {
- mArmPsciMethod = 2;
- } else {
- DEBUG ((
- DEBUG_ERROR,
- "%a: Unknown PSCI method \"%a\"\n",
- __func__,
- Prop
- ));
- return EFI_NOT_FOUND;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- This function causes a system-wide reset (cold reset), in which
- all circuitry within the system returns to its initial state. This type of reset
- is asynchronous to system operation and operates without regard to
- cycle boundaries.
-
- If this function returns, it means that the system does not support cold reset.
-**/
-VOID
-EFIAPI
-ResetCold (
- VOID
- )
-{
- ARM_SMC_ARGS ArmSmcArgs;
- ARM_HVC_ARGS ArmHvcArgs;
-
- // Send a PSCI 0.2 SYSTEM_RESET command
- ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;
- ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_RESET;
-
- switch (mArmPsciMethod) {
- case 1:
- ArmCallHvc (&ArmHvcArgs);
- break;
-
- case 2:
- ArmCallSmc (&ArmSmcArgs);
- break;
-
- default:
- DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __func__));
- }
-}
-
-/**
- This function causes a system-wide initialization (warm reset), in which all processors
- are set to their initial state. Pending cycles are not corrupted.
-
- If this function returns, it means that the system does not support warm reset.
-**/
-VOID
-EFIAPI
-ResetWarm (
- VOID
- )
-{
- // Map a warm reset into a cold reset
- ResetCold ();
-}
-
-/**
- This function causes the system to enter a power state equivalent
- to the ACPI G2/S5 or G3 states.
-
- If this function returns, it means that the system does not support shutdown reset.
-**/
-VOID
-EFIAPI
-ResetShutdown (
- VOID
- )
-{
- ARM_SMC_ARGS ArmSmcArgs;
- ARM_HVC_ARGS ArmHvcArgs;
-
- // Send a PSCI 0.2 SYSTEM_OFF command
- ArmSmcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;
- ArmHvcArgs.Arg0 = ARM_SMC_ID_PSCI_SYSTEM_OFF;
-
- switch (mArmPsciMethod) {
- case 1:
- ArmCallHvc (&ArmHvcArgs);
- break;
-
- case 2:
- ArmCallSmc (&ArmSmcArgs);
- break;
-
- default:
- DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __func__));
- }
-}
-
-/**
- This function causes a systemwide reset. The exact type of the reset is
- defined by the EFI_GUID that follows the Null-terminated Unicode string passed
- into ResetData. If the platform does not recognize the EFI_GUID in ResetData
- the platform must pick a supported reset type to perform.The platform may
- optionally log the parameters from any non-normal reset that occurs.
-
- @param[in] DataSize The size, in bytes, of ResetData.
- @param[in] ResetData The data buffer starts with a Null-terminated string,
- followed by the EFI_GUID.
-**/
-VOID
-EFIAPI
-ResetPlatformSpecific (
- IN UINTN DataSize,
- IN VOID *ResetData
- )
-{
- // Map the platform specific reset as reboot
- ResetCold ();
-}
-
-/**
- The ResetSystem function resets the entire platform.
-
- @param[in] ResetType The type of reset to perform.
- @param[in] ResetStatus The status code for the reset.
- @param[in] DataSize The size, in bytes, of ResetData.
- @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
- the data buffer starts with a Null-terminated string, optionally
- followed by additional binary data. The string is a description
- that the caller may use to further indicate the reason for the
- system reset.
-**/
-VOID
-EFIAPI
-ResetSystem (
- IN EFI_RESET_TYPE ResetType,
- IN EFI_STATUS ResetStatus,
- IN UINTN DataSize,
- IN VOID *ResetData OPTIONAL
- )
-{
- switch (ResetType) {
- case EfiResetWarm:
- ResetWarm ();
- break;
-
- case EfiResetCold:
- ResetCold ();
- break;
-
- case EfiResetShutdown:
- ResetShutdown ();
- return;
-
- case EfiResetPlatformSpecific:
- ResetPlatformSpecific (DataSize, ResetData);
- return;
-
- default:
- return;
- }
-}
diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.inf b/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.inf
deleted file mode 100644
index 4fde5e4..0000000
--- a/ArmVirtPkg/Library/ArmVirtPsciResetSystemLib/ArmVirtPsciResetSystemLib.inf
+++ /dev/null
@@ -1,42 +0,0 @@
-#/** @file
-# Reset System lib using PSCI hypervisor or secure monitor calls
-#
-# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
-# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-#**/
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = ArmVirtPsciResetSystemLib
- FILE_GUID = c81d76ed-66fa-44a3-ac4a-f163120187a9
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = ResetSystemLib|DXE_DRIVER DXE_RUNTIME_DRIVER
- CONSTRUCTOR = ArmPsciResetSystemLibConstructor
-
-[Sources]
- ArmVirtPsciResetSystemLib.c
-
-[Packages]
- ArmPkg/ArmPkg.dec
- ArmVirtPkg/ArmVirtPkg.dec
- EmbeddedPkg/EmbeddedPkg.dec
- MdeModulePkg/MdeModulePkg.dec
- MdePkg/MdePkg.dec
-
-[LibraryClasses]
- ArmSmcLib
- ArmHvcLib
- BaseLib
- DebugLib
- UefiBootServicesTableLib
-
-[Protocols]
- gFdtClientProtocolGuid ## CONSUMES
-
-[Depex]
- gFdtClientProtocolGuid
diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c
deleted file mode 100644
index dffc1fb..0000000
--- a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/** @file
- Reset System lib using PSCI hypervisor or secure monitor calls
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
- Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.<BR>
- Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <PiPei.h>
-
-#include <libfdt.h>
-#include <Library/ArmHvcLib.h>
-#include <Library/ArmSmcLib.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/HobLib.h>
-#include <Library/ResetSystemLib.h>
-
-#include <IndustryStandard/ArmStdSmc.h>
-
-typedef enum {
- PsciMethodUnknown,
- PsciMethodSmc,
- PsciMethodHvc,
-} PSCI_METHOD;
-
-STATIC
-PSCI_METHOD
-DiscoverPsciMethod (
- VOID
- )
-{
- VOID *DeviceTreeBase;
- INT32 Node, Prev;
- INT32 Len;
- CONST CHAR8 *Compatible;
- CONST CHAR8 *CompatibleItem;
- CONST VOID *Prop;
-
- DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
- ASSERT (fdt_check_header (DeviceTreeBase) == 0);
-
- //
- // Enumerate all FDT nodes looking for the PSCI node and capture the method
- //
- for (Prev = 0; ; Prev = Node) {
- Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
- if (Node < 0) {
- break;
- }
-
- Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
- if (Compatible == NULL) {
- continue;
- }
-
- //
- // Iterate over the NULL-separated items in the compatible string
- //
- for (CompatibleItem = Compatible; CompatibleItem < Compatible + Len;
- CompatibleItem += 1 + AsciiStrLen (CompatibleItem))
- {
- if (AsciiStrCmp (CompatibleItem, "arm,psci-0.2") != 0) {
- continue;
- }
-
- Prop = fdt_getprop (DeviceTreeBase, Node, "method", NULL);
- if (!Prop) {
- DEBUG ((
- DEBUG_ERROR,
- "%a: Missing PSCI method property\n",
- __func__
- ));
- return PsciMethodUnknown;
- }
-
- if (AsciiStrnCmp (Prop, "hvc", 3) == 0) {
- return PsciMethodHvc;
- } else if (AsciiStrnCmp (Prop, "smc", 3) == 0) {
- return PsciMethodSmc;
- } else {
- DEBUG ((
- DEBUG_ERROR,
- "%a: Unknown PSCI method \"%a\"\n",
- __func__,
- Prop
- ));
- return PsciMethodUnknown;
- }
- }
- }
-
- return PsciMethodUnknown;
-}
-
-STATIC
-VOID
-PerformPsciAction (
- IN UINTN Arg0
- )
-{
- ARM_SMC_ARGS ArmSmcArgs;
- ARM_HVC_ARGS ArmHvcArgs;
-
- ArmSmcArgs.Arg0 = Arg0;
- ArmHvcArgs.Arg0 = Arg0;
-
- switch (DiscoverPsciMethod ()) {
- case PsciMethodHvc:
- ArmCallHvc (&ArmHvcArgs);
- break;
-
- case PsciMethodSmc:
- ArmCallSmc (&ArmSmcArgs);
- break;
-
- default:
- DEBUG ((DEBUG_ERROR, "%a: no PSCI method defined\n", __func__));
- ASSERT (FALSE);
- }
-}
-
-/**
- This function causes a system-wide reset (cold reset), in which
- all circuitry within the system returns to its initial state. This type of reset
- is asynchronous to system operation and operates without regard to
- cycle boundaries.
-
- If this function returns, it means that the system does not support cold reset.
-**/
-VOID
-EFIAPI
-ResetCold (
- VOID
- )
-{
- // Send a PSCI 0.2 SYSTEM_RESET command
- PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_RESET);
-}
-
-/**
- This function causes a system-wide initialization (warm reset), in which all processors
- are set to their initial state. Pending cycles are not corrupted.
-
- If this function returns, it means that the system does not support warm reset.
-**/
-VOID
-EFIAPI
-ResetWarm (
- VOID
- )
-{
- // Map a warm reset into a cold reset
- ResetCold ();
-}
-
-/**
- This function causes the system to enter a power state equivalent
- to the ACPI G2/S5 or G3 states.
-
- If this function returns, it means that the system does not support shutdown reset.
-**/
-VOID
-EFIAPI
-ResetShutdown (
- VOID
- )
-{
- // Send a PSCI 0.2 SYSTEM_OFF command
- PerformPsciAction (ARM_SMC_ID_PSCI_SYSTEM_OFF);
-}
-
-/**
- This function causes a systemwide reset. The exact type of the reset is
- defined by the EFI_GUID that follows the Null-terminated Unicode string passed
- into ResetData. If the platform does not recognize the EFI_GUID in ResetData
- the platform must pick a supported reset type to perform.The platform may
- optionally log the parameters from any non-normal reset that occurs.
-
- @param[in] DataSize The size, in bytes, of ResetData.
- @param[in] ResetData The data buffer starts with a Null-terminated string,
- followed by the EFI_GUID.
-**/
-VOID
-EFIAPI
-ResetPlatformSpecific (
- IN UINTN DataSize,
- IN VOID *ResetData
- )
-{
- // Map the platform specific reset as reboot
- ResetCold ();
-}
-
-/**
- The ResetSystem function resets the entire platform.
-
- @param[in] ResetType The type of reset to perform.
- @param[in] ResetStatus The status code for the reset.
- @param[in] DataSize The size, in bytes, of ResetData.
- @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
- the data buffer starts with a Null-terminated string, optionally
- followed by additional binary data. The string is a description
- that the caller may use to further indicate the reason for the
- system reset.
-**/
-VOID
-EFIAPI
-ResetSystem (
- IN EFI_RESET_TYPE ResetType,
- IN EFI_STATUS ResetStatus,
- IN UINTN DataSize,
- IN VOID *ResetData OPTIONAL
- )
-{
- switch (ResetType) {
- case EfiResetWarm:
- ResetWarm ();
- break;
-
- case EfiResetCold:
- ResetCold ();
- break;
-
- case EfiResetShutdown:
- ResetShutdown ();
- return;
-
- case EfiResetPlatformSpecific:
- ResetPlatformSpecific (DataSize, ResetData);
- return;
-
- default:
- return;
- }
-}
diff --git a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf b/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf
deleted file mode 100644
index 79217d2..0000000
--- a/ArmVirtPkg/Library/ArmVirtPsciResetSystemPeiLib/ArmVirtPsciResetSystemPeiLib.inf
+++ /dev/null
@@ -1,40 +0,0 @@
-#/** @file
-# Reset System lib using PSCI hypervisor or secure monitor calls
-#
-# Copyright (c) 2008, Apple Inc. All rights reserved.<BR>
-# Copyright (c) 2014-2020, Linaro Ltd. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-#**/
-
-[Defines]
- INF_VERSION = 1.27
- BASE_NAME = ArmVirtPsciResetSystemPeiLib
- FILE_GUID = 551cfb98-c185-41a3-86bf-8cdb7e2a530c
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = ResetSystemLib|PEIM
-
-[Sources]
- ArmVirtPsciResetSystemPeiLib.c
-
-[Packages]
- ArmPkg/ArmPkg.dec
- ArmVirtPkg/ArmVirtPkg.dec
- EmbeddedPkg/EmbeddedPkg.dec
- MdeModulePkg/MdeModulePkg.dec
- MdePkg/MdePkg.dec
- OvmfPkg/OvmfPkg.dec
-
-[LibraryClasses]
- ArmSmcLib
- ArmHvcLib
- BaseLib
- DebugLib
- FdtLib
- HobLib
-
-[Pcd]
- gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
diff --git a/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.c b/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.c
new file mode 100644
index 0000000..aa8d5d6
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.c
@@ -0,0 +1,128 @@
+/** @file
+ Arm Monitor Library that chooses the conduit based on the PSCI node in the
+ device tree provided by QEMU.
+
+ Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
+ Copyright (c) 2024, Google LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+
+#include <Library/ArmHvcLib.h>
+#include <Library/ArmMonitorLib.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FdtLib.h>
+
+typedef enum {
+ SmcccConduitUnknown,
+ SmcccConduitSmc,
+ SmcccConduitHvc,
+} SMCCC_CONDUIT;
+
+/**
+ Discover the SMCCC conduit by parsing the PSCI device tree node.
+
+ @return the discovered SMCCC conduit
+**/
+STATIC
+SMCCC_CONDUIT
+DiscoverSmcccConduit (
+ VOID
+ )
+{
+ VOID *DeviceTreeBase;
+ INT32 Node, Prev;
+ INT32 Len;
+ CONST FDT_PROPERTY *Compatible;
+ CONST CHAR8 *CompatibleItem;
+ CONST FDT_PROPERTY *Prop;
+
+ DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
+ ASSERT (FdtCheckHeader (DeviceTreeBase) == 0);
+
+ //
+ // Enumerate all FDT nodes looking for the PSCI node and capture the conduit
+ //
+ for (Prev = 0; ; Prev = Node) {
+ Node = FdtNextNode (DeviceTreeBase, Prev, NULL);
+ if (Node < 0) {
+ break;
+ }
+
+ Compatible = FdtGetProperty (DeviceTreeBase, Node, "compatible", &Len);
+ if (Compatible == NULL) {
+ continue;
+ }
+
+ //
+ // Iterate over the NULL-separated items in the compatible string
+ //
+ for (CompatibleItem = Compatible->Data; CompatibleItem < Compatible->Data + Len;
+ CompatibleItem += 1 + AsciiStrLen (CompatibleItem))
+ {
+ if (AsciiStrCmp (CompatibleItem, "arm,psci-0.2") != 0) {
+ continue;
+ }
+
+ Prop = FdtGetProperty (DeviceTreeBase, Node, "method", NULL);
+ if (Prop == NULL) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Missing PSCI method property\n",
+ __func__
+ ));
+
+ return SmcccConduitUnknown;
+ }
+
+ if (AsciiStrnCmp (Prop->Data, "hvc", 3) == 0) {
+ return SmcccConduitHvc;
+ } else if (AsciiStrnCmp (Prop->Data, "smc", 3) == 0) {
+ return SmcccConduitSmc;
+ } else {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Unknown PSCI method \"%a\"\n",
+ __func__,
+ Prop
+ ));
+
+ return SmcccConduitUnknown;
+ }
+ }
+ }
+
+ return SmcccConduitUnknown;
+}
+
+/** Monitor call.
+
+ An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued
+ depending on the default conduit.
+
+ @param [in,out] Args Arguments for the HVC/SMC.
+**/
+VOID
+EFIAPI
+ArmMonitorCall (
+ IN OUT ARM_MONITOR_ARGS *Args
+ )
+{
+ switch (DiscoverSmcccConduit ()) {
+ case SmcccConduitHvc:
+ ArmCallHvc ((ARM_HVC_ARGS *)Args);
+ break;
+
+ case SmcccConduitSmc:
+ ArmCallSmc ((ARM_SMC_ARGS *)Args);
+ break;
+
+ default:
+ ASSERT (FALSE);
+ }
+}
diff --git a/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.inf b/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.inf
new file mode 100644
index 0000000..cd850f3
--- /dev/null
+++ b/ArmVirtPkg/Library/ArmVirtQemuMonitorPeiLib/ArmVirtQemuMonitorPeiLib.inf
@@ -0,0 +1,35 @@
+## @file
+# Arm Monitor Library that chooses the conduit based on the PSCI node in the
+# device tree provided by QEMU.
+#
+# Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
+# Copyright (c) 2024, Google LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = ArmVirtQemuMonitorPeiLib
+ FILE_GUID = c610e0dc-dd7a-47c8-8fea-26c4710709ff
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmMonitorLib|PEIM
+
+[Sources]
+ ArmVirtQemuMonitorPeiLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ ArmHvcLib
+ ArmSmcLib
+ BaseLib
+ DebugLib
+ FdtLib
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c
index 0da84ba..83d52e9 100644
--- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c
+++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLib.c
@@ -182,8 +182,8 @@ DebugBPrint (
Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
- PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
- DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
+ PcdDebugPropertyMask is set then CpuBreakpoint() is called. Otherwise, if
+ DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugPropertyMask is set then
CpuDeadLoop() is called. If neither of these bits are set, then this function
returns immediately after the message is printed to the debug output device.
DebugAssert() must actively prevent recursion. If DebugAssert() is called while
@@ -264,10 +264,10 @@ DebugClearMemory (
Returns TRUE if ASSERT() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
@@ -283,10 +283,10 @@ DebugAssertEnabled (
Returns TRUE if DEBUG() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
@@ -302,10 +302,10 @@ DebugPrintEnabled (
Returns TRUE if DEBUG_CODE() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
@@ -321,10 +321,10 @@ DebugCodeEnabled (
Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
diff --git a/ArmVirtPkg/Library/KvmtoolRtcFdtClientLib/KvmtoolRtcFdtClientLib.c b/ArmVirtPkg/Library/KvmtoolRtcFdtClientLib/KvmtoolRtcFdtClientLib.c
index e8d3576..2afb56c 100644
--- a/ArmVirtPkg/Library/KvmtoolRtcFdtClientLib/KvmtoolRtcFdtClientLib.c
+++ b/ArmVirtPkg/Library/KvmtoolRtcFdtClientLib/KvmtoolRtcFdtClientLib.c
@@ -44,7 +44,7 @@ KvmtoolRtcMapMemory (
EfiGcdMemoryTypeMemoryMappedIo,
RtcPageBase,
EFI_PAGE_SIZE,
- EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP
);
if (EFI_ERROR (Status)) {
DEBUG ((
@@ -80,7 +80,7 @@ KvmtoolRtcMapMemory (
Status = gDS->SetMemorySpaceAttributes (
RtcPageBase,
EFI_PAGE_SIZE,
- EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME | EFI_MEMORY_XP
);
if (EFI_ERROR (Status)) {
DEBUG ((
diff --git a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c
index 62fa62e..d435d72 100644
--- a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c
+++ b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c
@@ -27,7 +27,7 @@
#define MACH_VIRT_PERIPH_SIZE SIZE_128MB
/**
- Default library constructur that obtains the memory size from a PCD.
+ Default library constructor that obtains the memory size from a PCD.
@return Always returns RETURN_SUCCESS
diff --git a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf
index 76c3c5d..091e37c 100644
--- a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf
+++ b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLib.inf
@@ -30,6 +30,7 @@
[LibraryClasses]
ArmLib
+ BaseLib
BaseMemoryLib
DebugLib
FdtLib
@@ -38,11 +39,13 @@
[Guids]
gArmVirtSystemMemorySizeGuid
+[Pcd]
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+
[FixedPcd]
gArmTokenSpaceGuid.PcdFdBaseAddress
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdSystemMemoryBase
- gArmTokenSpaceGuid.PcdSystemMemorySize
gArmTokenSpaceGuid.PcdFdSize
gArmTokenSpaceGuid.PcdFvSize
gUefiOvmfPkgTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
diff --git a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLibConstructor.c b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLibConstructor.c
index 1bcc2e2..f39df85 100644
--- a/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLibConstructor.c
+++ b/ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoPeiLibConstructor.c
@@ -8,6 +8,7 @@
#include <Uefi.h>
#include <Pi/PiMultiPhase.h>
+#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <libfdt.h>
diff --git a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
index fc06c28..06a0020 100644
--- a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
+++ b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
@@ -6,7 +6,7 @@
//
//
-#include <AsmMacroIoLibV8.h>
+#include <AsmMacroLib.h>
ASM_FUNC(_ModuleEntryPoint)
//
diff --git a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S
index f0536c6..cfb5de8 100644
--- a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S
+++ b/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S
@@ -6,7 +6,7 @@
//
//
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(_ModuleEntryPoint)
// Do early platform specific actions
diff --git a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
index 578ee37..ed8b89e 100755
--- a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
+++ b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
@@ -46,7 +46,6 @@
TimerLib
SerialPortLib
ExtractGuidedSectionLib
- LzmaDecompressLib
PeCoffLib
PrePiLib
MemoryAllocationLib
@@ -56,15 +55,11 @@
MemoryInitPeiLib
CacheMaintenanceLib
-[Ppis]
- gArmMpCoreInfoPpiGuid
-
[Guids]
gArmMpCoreInfoGuid
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
- gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
[FixedPcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
@@ -75,7 +70,6 @@
gArmTokenSpaceGuid.PcdFvSize
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
diff --git a/ArmVirtPkg/PrePi/PrePi.c b/ArmVirtPkg/PrePi/PrePi.c
index f27e0ad..9dbb5af 100755
--- a/ArmVirtPkg/PrePi/PrePi.c
+++ b/ArmVirtPkg/PrePi/PrePi.c
@@ -109,8 +109,6 @@ CEntryPoint (
UINT64 StartTimeStamp;
if (PerformanceMeasurementEnabled ()) {
- // Initialize the Timer Library to setup the Timer HW controller
- TimerConstructor ();
// We cannot call yet the PerformanceLib because the HOB List has not been initialized
StartTimeStamp = GetPerformanceCounter ();
} else {
diff --git a/ArmVirtPkg/PrePi/PrePi.h b/ArmVirtPkg/PrePi/PrePi.h
index 4bb9791..c00899b 100644
--- a/ArmVirtPkg/PrePi/PrePi.h
+++ b/ArmVirtPkg/PrePi/PrePi.h
@@ -22,12 +22,6 @@
#define SerialPrint(txt) SerialPortWrite (txt, AsciiStrLen(txt)+1);
-RETURN_STATUS
-EFIAPI
-TimerConstructor (
- VOID
- );
-
VOID
PrePiMain (
IN UINTN UefiMemoryBase,
diff --git a/ArmPkg/Library/GccLto/liblto-aarch64.a b/BaseTools/Bin/GccLto/liblto-aarch64.a
index 6ca3932..6ca3932 100644
--- a/ArmPkg/Library/GccLto/liblto-aarch64.a
+++ b/BaseTools/Bin/GccLto/liblto-aarch64.a
Binary files differ
diff --git a/ArmPkg/Library/GccLto/liblto-aarch64.s b/BaseTools/Bin/GccLto/liblto-aarch64.s
index 02a55ef..02a55ef 100644
--- a/ArmPkg/Library/GccLto/liblto-aarch64.s
+++ b/BaseTools/Bin/GccLto/liblto-aarch64.s
diff --git a/ArmPkg/Library/GccLto/liblto-arm.a b/BaseTools/Bin/GccLto/liblto-arm.a
index d811c09..d811c09 100644
--- a/ArmPkg/Library/GccLto/liblto-arm.a
+++ b/BaseTools/Bin/GccLto/liblto-arm.a
Binary files differ
diff --git a/ArmPkg/Library/GccLto/liblto-arm.s b/BaseTools/Bin/GccLto/liblto-arm.s
index f19fb45..f19fb45 100644
--- a/ArmPkg/Library/GccLto/liblto-arm.s
+++ b/BaseTools/Bin/GccLto/liblto-arm.s
diff --git a/ArmPkg/Library/GnuNoteBti.bin b/BaseTools/Bin/GnuNoteBti.bin
index 339567b..339567b 100644
--- a/ArmPkg/Library/GnuNoteBti.bin
+++ b/BaseTools/Bin/GnuNoteBti.bin
Binary files differ
diff --git a/BaseTools/BinPipWrappers/PosixLike/AmlToC b/BaseTools/BinPipWrappers/PosixLike/AmlToC
deleted file mode 100755
index 1dd28e9..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/AmlToC
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-exe=$(basename "$full_cmd")
-
-export PYTHONPATH="$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}"
-exec "${python_exe:-python}" "$dir/../../Source/Python/$exe/$exe.py" "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/BPDG b/BaseTools/BinPipWrappers/PosixLike/BPDG
deleted file mode 100755
index a08cbd8..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/BPDG
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.$cmd.EccMain "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/BrotliCompress b/BaseTools/BinPipWrappers/PosixLike/BrotliCompress
deleted file mode 100755
index 426f2a2..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/BrotliCompress
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env bash
-#
-# This script will exec Brotli tool with -e/-d options.
-#
-# Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-QLT="-q 9 -w 22"
-ARGS=
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-while test $# -gt 0
-do
- case $1 in
- -e)
- ;;
- -d)
- ARGS+="$1 "
- ;;
- -o|-g)
- ARGS+="$1 $2 "
- shift
- ;;
- -q)
- QLT="$1 $2 "
- shift
- ;;
- *)
- ARGS+="$1 "
- ;;
- esac
- shift
-done
-
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" $QLT $ARGS
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" $QLT $ARGS
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
diff --git a/BaseTools/BinPipWrappers/PosixLike/DevicePath b/BaseTools/BinPipWrappers/PosixLike/DevicePath
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/DevicePath
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/Ecc b/BaseTools/BinPipWrappers/PosixLike/Ecc
deleted file mode 100755
index 5987289..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/Ecc
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-export PYTHONPATH="$dir/../../Source/Python${PYTHONPATH:+:"$PYTHONPATH"}"
-exec "${python_exe:-python}" -m $cmd.EccMain "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/EfiRom b/BaseTools/BinPipWrappers/PosixLike/EfiRom
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/EfiRom
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/GenCrc32 b/BaseTools/BinPipWrappers/PosixLike/GenCrc32
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/GenCrc32
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/GenDepex b/BaseTools/BinPipWrappers/PosixLike/GenDepex
deleted file mode 100755
index df75e43..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/GenDepex
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.AutoGen.$cmd "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/GenFds b/BaseTools/BinPipWrappers/PosixLike/GenFds
deleted file mode 100755
index b27e84e..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/GenFds
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.$cmd "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/GenFfs b/BaseTools/BinPipWrappers/PosixLike/GenFfs
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/GenFfs
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/GenFv b/BaseTools/BinPipWrappers/PosixLike/GenFv
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/GenFv
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/GenFw b/BaseTools/BinPipWrappers/PosixLike/GenFw
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/GenFw
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/GenPatchPcdTable b/BaseTools/BinPipWrappers/PosixLike/GenPatchPcdTable
deleted file mode 100755
index 9d143c7..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/GenPatchPcdTable
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/GenSec b/BaseTools/BinPipWrappers/PosixLike/GenSec
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/GenSec
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/GenerateCapsule b/BaseTools/BinPipWrappers/PosixLike/GenerateCapsule
deleted file mode 100755
index 366a268..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/GenerateCapsule
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.Capsule.$cmd "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/LzmaCompress b/BaseTools/BinPipWrappers/PosixLike/LzmaCompress
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/LzmaCompress
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/LzmaF86Compress b/BaseTools/BinPipWrappers/PosixLike/LzmaF86Compress
deleted file mode 100755
index b55352a..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/LzmaF86Compress
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env bash
-#
-# This script will exec LzmaCompress tool with --f86 option that enables converter for x86 code.
-#
-# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
-# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-for arg; do
- case $arg in
- -e|-d)
- set -- "$@" --f86
- break
- ;;
- esac
-done
-
-exec LzmaCompress "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/PatchPcdValue b/BaseTools/BinPipWrappers/PosixLike/PatchPcdValue
deleted file mode 100755
index 9d143c7..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/PatchPcdValue
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/Pkcs7Sign b/BaseTools/BinPipWrappers/PosixLike/Pkcs7Sign
deleted file mode 100755
index 9d143c7..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/Pkcs7Sign
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256GenerateKeys b/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256GenerateKeys
deleted file mode 100755
index aca2f3a..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256GenerateKeys
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.Rsa2048Sha256Sign.$cmd "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256Sign b/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256Sign
deleted file mode 100755
index ead26cb..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/Rsa2048Sha256Sign
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@" \ No newline at end of file
diff --git a/BaseTools/BinPipWrappers/PosixLike/Split b/BaseTools/BinPipWrappers/PosixLike/Split
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/Split
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/TargetTool b/BaseTools/BinPipWrappers/PosixLike/TargetTool
deleted file mode 100755
index 9d143c7..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/TargetTool
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/TianoCompress b/BaseTools/BinPipWrappers/PosixLike/TianoCompress
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/TianoCompress
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/Trim b/BaseTools/BinPipWrappers/PosixLike/Trim
deleted file mode 100755
index 0bd14ee..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/Trim
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=$(basename "$full_cmd")
-
-exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@"
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/UPT b/BaseTools/BinPipWrappers/PosixLike/UPT
deleted file mode 100755
index ead26cb..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/UPT
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@" \ No newline at end of file
diff --git a/BaseTools/BinPipWrappers/PosixLike/VfrCompile b/BaseTools/BinPipWrappers/PosixLike/VfrCompile
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/VfrCompile
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/VolInfo b/BaseTools/BinPipWrappers/PosixLike/VolInfo
deleted file mode 100755
index 0945d86..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/VolInfo
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-dir=$(dirname "$full_cmd")
-cmd=${full_cmd##*/}
-
-if [ -n "$WORKSPACE" ] && [ -e "$WORKSPACE/Conf/BaseToolsCBinaries" ]
-then
- exec "$WORKSPACE/Conf/BaseToolsCBinaries/$cmd"
-elif [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/Source/C" ]
-then
- if [ ! -e "$EDK_TOOLS_PATH/Source/C/bin/$cmd" ]
- then
- echo "BaseTools C Tool binary was not found ($cmd)"
- echo "You may need to run:"
- echo " make -C $EDK_TOOLS_PATH/Source/C"
- else
- exec "$EDK_TOOLS_PATH/Source/C/bin/$cmd" "$@"
- fi
-elif [ -e "$dir/../../Source/C/bin/$cmd" ]
-then
- exec "$dir/../../Source/C/bin/$cmd" "$@"
-else
- echo "Unable to find the real '$cmd' to run"
- echo "This message was printed by"
- echo " $0"
- exit 127
-fi
-
diff --git a/BaseTools/BinPipWrappers/PosixLike/build b/BaseTools/BinPipWrappers/PosixLike/build
deleted file mode 100755
index 9d143c7..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/build
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env bash
-#python `dirname $0`/RunToolFromSource.py `basename $0` $*
-
-# If a ${PYTHON_COMMAND} command is available, use it in preference to python
-if command -v ${PYTHON_COMMAND} >/dev/null 2>&1; then
- python_exe=${PYTHON_COMMAND}
-fi
-
-full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here
-cmd=${full_cmd##*/}
-
-exec "${python_exe:-python}" -m edk2basetools.$cmd.$cmd "$@"
diff --git a/BaseTools/BinPipWrappers/PosixLike/posix_path_env.yaml b/BaseTools/BinPipWrappers/PosixLike/posix_path_env.yaml
deleted file mode 100644
index eb1db9e..0000000
--- a/BaseTools/BinPipWrappers/PosixLike/posix_path_env.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-## @file
-# Set this folder on the path for all linux builds
-#
-# Copyright (c) Microsoft Corporation.
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-##
-{
- "scope": "pipbuild-unix",
- "override_id": "binwrappers",
- "flags": ["set_path"]
-}
diff --git a/BaseTools/BinPipWrappers/WindowsLike/AmlToC.bat b/BaseTools/BinPipWrappers/WindowsLike/AmlToC.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/AmlToC.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/BPDG.bat b/BaseTools/BinPipWrappers/WindowsLike/BPDG.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/BPDG.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/Ecc.bat b/BaseTools/BinPipWrappers/WindowsLike/Ecc.bat
deleted file mode 100644
index 16a0a79..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/Ecc.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.EccMain %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/GenDepex.bat b/BaseTools/BinPipWrappers/WindowsLike/GenDepex.bat
deleted file mode 100644
index 481b5ac..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/GenDepex.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.AutoGen.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/GenFds.bat b/BaseTools/BinPipWrappers/WindowsLike/GenFds.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/GenFds.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/GenPatchPcdTable.bat b/BaseTools/BinPipWrappers/WindowsLike/GenPatchPcdTable.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/GenPatchPcdTable.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/GenerateCapsule.bat b/BaseTools/BinPipWrappers/WindowsLike/GenerateCapsule.bat
deleted file mode 100644
index 34c43ac..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/GenerateCapsule.bat
+++ /dev/null
@@ -1 +0,0 @@
-@%PYTHON_COMMAND% -m edk2basetools.Capsule.GenerateCapsule %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/PatchPcdValue.bat b/BaseTools/BinPipWrappers/WindowsLike/PatchPcdValue.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/PatchPcdValue.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/Pkcs7Sign.bat b/BaseTools/BinPipWrappers/WindowsLike/Pkcs7Sign.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/Pkcs7Sign.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256GenerateKeys.bat b/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256GenerateKeys.bat
deleted file mode 100644
index cdc2e3e..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256GenerateKeys.bat
+++ /dev/null
@@ -1 +0,0 @@
-@%PYTHON_COMMAND% -m edk2basetools.Rsa2048Sha256Sign.Rsa2048Sha256GenerateKeys %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256Sign.bat b/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256Sign.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/Rsa2048Sha256Sign.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/Split.bat b/BaseTools/BinPipWrappers/WindowsLike/Split.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/Split.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/TargetTool.bat b/BaseTools/BinPipWrappers/WindowsLike/TargetTool.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/TargetTool.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/Trim.bat b/BaseTools/BinPipWrappers/WindowsLike/Trim.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/Trim.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/UPT.bat b/BaseTools/BinPipWrappers/WindowsLike/UPT.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/UPT.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/build.bat b/BaseTools/BinPipWrappers/WindowsLike/build.bat
deleted file mode 100644
index d347d64..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/build.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-@setlocal
-@set ToolName=%~n0%
-@%PYTHON_COMMAND% -m edk2basetools.%ToolName%.%ToolName% %*
diff --git a/BaseTools/BinPipWrappers/WindowsLike/win_build_tools_path_env.yaml b/BaseTools/BinPipWrappers/WindowsLike/win_build_tools_path_env.yaml
deleted file mode 100644
index 9fdbe1b..0000000
--- a/BaseTools/BinPipWrappers/WindowsLike/win_build_tools_path_env.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-## @file
-# Add this folder to the path on Windows
-#
-# Copyright (c) Microsoft Corporation.
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-##
-{
- "scope": "pipbuild-win",
- "override_id": "binwrappers",
- "flags": ["set_path"]
-}
diff --git a/BaseTools/BuildEnv b/BaseTools/BuildEnv
index bd6235d..1d9526b 100755
--- a/BaseTools/BuildEnv
+++ b/BaseTools/BuildEnv
@@ -198,16 +198,7 @@ AddEdkToolsToPath() {
EDK_TOOLS_PATH_BIN=`GetEdkToolsPathBinDirectory`
- # check if the edk2basetools pip package is available
- if $PYTHON_COMMAND -c "import edk2basetools" > /dev/null 2>&1; then
- # if it is, use the pip version of the wrappers
- echo "Using Pip Basetools"
- AddDirToStartOfPath $EDK_TOOLS_PATH/BinPipWrappers/PosixLike
- else
- echo "Using EDK2 in-source Basetools"
- AddDirToStartOfPath $EDK_TOOLS_PATH/BinWrappers/PosixLike
- fi
-
+ AddDirToStartOfPath $EDK_TOOLS_PATH/BinWrappers/PosixLike
AddDirToStartOfPath $EDK_TOOLS_PATH_BIN
diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index c34ecfd..0f110fb 100755
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -20,8 +20,10 @@
# - Remove VS2008, VS2010, VS2012, VS2013, CLANG35, CLANG38, EBC
# - Add GCC and GCCNOLTO
# - Deprecate GCC48, GCC49 and GCC5.
+# 3.01 - Add toolchain for VS2022
+# 3.02 - Enable stack cookies for IA32, X64, ARM, and AARCH64 builds for GCC and MSVC
#
-#!VERSION=3.00
+#!VERSION=3.02
IDENTIFIER = Default TOOL_CHAIN_CONF
@@ -50,6 +52,13 @@ DEFINE VS2019_BIN_X64 = DEF(VS2019_BIN)\HostDEF(VS_HOST)\x64
DEFINE VS2019_BIN_ARM = DEF(VS2019_BIN)\HostDEF(VS_HOST)\arm
DEFINE VS2019_BIN_AARCH64 = DEF(VS2019_BIN)\HostDEF(VS_HOST)\arm64
+DEFINE VS2022_BIN = ENV(VS2022_PREFIX)bin
+DEFINE VS2022_BIN_HOST = DEF(VS2022_BIN)\HostDEF(VS_HOST)\DEF(VS_HOST)
+DEFINE VS2022_BIN_IA32 = DEF(VS2022_BIN)\HostDEF(VS_HOST)\x86
+DEFINE VS2022_BIN_X64 = DEF(VS2022_BIN)\HostDEF(VS_HOST)\x64
+DEFINE VS2022_BIN_ARM = DEF(VS2022_BIN)\HostDEF(VS_HOST)\arm
+DEFINE VS2022_BIN_AARCH64 = DEF(VS2022_BIN)\HostDEF(VS_HOST)\arm64
+
#
# Resource compiler
#
@@ -59,10 +68,10 @@ DEFINE WINSDK_BIN = ENV(WINSDK_PREFIX)
DEFINE WINSDKx86_BIN = ENV(WINSDKx86_PREFIX)
# Microsoft Visual Studio 2015 Professional Edition
-DEFINE WINSDK81_BIN = ENV(WINSDK81_PREFIX)x86\
-DEFINE WINSDK81x86_BIN = ENV(WINSDK81x86_PREFIX)x64
+DEFINE WINSDK81_BIN = ENV(WINSDK81_PREFIX)x64
+DEFINE WINSDK81x86_BIN = ENV(WINSDK81x86_PREFIX)x86
-# Microsoft Visual Studio 2017/2019 Professional Edition
+# Microsoft Visual Studio 2017/2019/2022 Professional Edition
DEFINE WINSDK10_BIN = ENV(WINSDK10_PREFIX)DEF(VS_HOST)
# These defines are needed for certain Microsoft Visual Studio tools that
@@ -158,9 +167,11 @@ DEFINE DTC_BIN = ENV(DTC_PREFIX)dtc
# Required to build platforms or ACPI tables:
# Intel(r) ACPI Compiler (iasl.exe) from
# https://acpica.org/downloads
-# Note:
-# Building of XIP firmware images for ARM/ARM64 is not currently supported (only applications).
-# /FILEALIGN:4096 and other changes are needed for ARM firmware builds.
+# VS2022 -win32,win64- Requires:
+# Microsoft Visual Studio 2022 version 17.0 or later
+# Optional:
+# Required to build EBC drivers:
+# Intel(r) Compiler for Efi Byte Code (Intel(r) EBC Compiler)
# GCCNOLTO -Linux,Windows- Requires:
# GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi
# Optional:
@@ -625,9 +636,9 @@ NOOPT_VS2017_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF
*_VS2019_IA32_PP_PATH = DEF(VS2019_BIN_IA32)\cl.exe
*_VS2019_IA32_ASM_PATH = DEF(VS2019_BIN_IA32)\ml.exe
- DEBUG_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Gw
-RELEASE_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw
-NOOPT_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Od
+ DEBUG_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Gw
+RELEASE_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw
+NOOPT_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Od
DEBUG_VS2019_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi
RELEASE_VS2019_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd
@@ -655,9 +666,9 @@ NOOPT_VS2019_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /O
*_VS2019_X64_DLINK_PATH = DEF(VS2019_BIN_X64)\link.exe
*_VS2019_X64_ASLDLINK_PATH = DEF(VS2019_BIN_X64)\link.exe
- DEBUG_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw
-RELEASE_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw
-NOOPT_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od
+ DEBUG_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw /volatileMetadata-
+RELEASE_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw /volatileMetadata-
+NOOPT_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od /volatileMetadata-
DEBUG_VS2019_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi
RELEASE_VS2019_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd
@@ -685,9 +696,9 @@ NOOPT_VS2019_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:428
*_VS2019_ARM_ASLPP_PATH = DEF(VS2019_BIN_ARM)\cl.exe
*_VS2019_ARM_ASLDLINK_PATH = DEF(VS2019_BIN_ARM)\link.exe
- DEBUG_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi-
-RELEASE_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi-
-NOOPT_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi-
+ DEBUG_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi-
+RELEASE_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi-
+NOOPT_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi-
DEBUG_VS2019_ARM_ASM_FLAGS = /nologo /g
RELEASE_VS2019_ARM_ASM_FLAGS = /nologo
@@ -711,9 +722,9 @@ NOOPT_VS2019_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF
*_VS2019_AARCH64_ASLPP_PATH = DEF(VS2019_BIN_AARCH64)\cl.exe
*_VS2019_AARCH64_ASLDLINK_PATH = DEF(VS2019_BIN_AARCH64)\link.exe
- DEBUG_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi-
-RELEASE_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi-
-NOOPT_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi-
+ DEBUG_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi-
+RELEASE_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi-
+NOOPT_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi-
DEBUG_VS2019_AARCH64_ASM_FLAGS = /nologo /g
RELEASE_VS2019_AARCH64_ASM_FLAGS = /nologo
@@ -724,6 +735,151 @@ RELEASE_VS2019_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:
NOOPT_VS2019_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG
####################################################################################
+# VS2022 - Microsoft Visual Studio 2022 with Intel ASL
+# ASL - Intel ACPI Source Language Compiler (iasl.exe)
+####################################################################################
+# VS2022 - Microsoft Visual Studio 2022 with Intel ASL
+*_VS2022_*_*_FAMILY = MSFT
+*_VS2022_*_*_DLL = DEF(VS2022_BIN_HOST)
+
+*_VS2022_*_MAKE_PATH = DEF(VS2022_BIN_HOST)\nmake.exe
+*_VS2022_*_MAKE_FLAG = /nologo
+*_VS2022_*_RC_PATH = DEF(RC_PATH)
+
+*_VS2022_*_MAKE_FLAGS = /nologo
+*_VS2022_*_SLINK_FLAGS = /NOLOGO /LTCG
+*_VS2022_*_APP_FLAGS = /nologo /E /TC
+*_VS2022_*_PP_FLAGS = /nologo /E /TC /FIAutoGen.h
+*_VS2022_*_VFRPP_FLAGS = /nologo /E /TC /DVFRCOMPILE /FI$(MODULE_NAME)StrDefs.h
+# *_VS2022_*_DLINK2_FLAGS = /WHOLEARCHIVE # MU_CHANGE
+*_VS2022_*_ASM16_PATH = DEF(VS2022_BIN_IA32)\ml.exe
+*_VS2022_*_DEPS_FLAGS = DEF(MSFT_DEPS_FLAGS)
+##################
+# ASL definitions
+##################
+*_VS2022_*_ASL_PATH = DEF(WIN_IASL_BIN)
+*_VS2022_*_ASL_FLAGS = DEF(DEFAULT_WIN_ASL_FLAGS)
+*_VS2022_*_ASL_OUTFLAGS = DEF(DEFAULT_WIN_ASL_OUTFLAGS)
+*_VS2022_*_ASLCC_FLAGS = DEF(MSFT_ASLCC_FLAGS)
+*_VS2022_*_ASLPP_FLAGS = DEF(MSFT_ASLPP_FLAGS)
+*_VS2022_*_ASLDLINK_FLAGS = DEF(MSFT_ASLDLINK_FLAGS)
+
+##################
+# IA32 definitions
+##################
+*_VS2022_IA32_CC_PATH = DEF(VS2022_BIN_IA32)\cl.exe
+*_VS2022_IA32_VFRPP_PATH = DEF(VS2022_BIN_IA32)\cl.exe
+*_VS2022_IA32_ASLCC_PATH = DEF(VS2022_BIN_IA32)\cl.exe
+*_VS2022_IA32_ASLPP_PATH = DEF(VS2022_BIN_IA32)\cl.exe
+*_VS2022_IA32_SLINK_PATH = DEF(VS2022_BIN_IA32)\lib.exe
+*_VS2022_IA32_DLINK_PATH = DEF(VS2022_BIN_IA32)\link.exe
+*_VS2022_IA32_ASLDLINK_PATH= DEF(VS2022_BIN_IA32)\link.exe
+*_VS2022_IA32_APP_PATH = DEF(VS2022_BIN_IA32)\cl.exe
+*_VS2022_IA32_PP_PATH = DEF(VS2022_BIN_IA32)\cl.exe
+*_VS2022_IA32_ASM_PATH = DEF(VS2022_BIN_IA32)\ml.exe
+
+ *_VS2022_IA32_MAKE_FLAGS = /nologo
+ DEBUG_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Gw
+RELEASE_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw
+NOOPT_VS2022_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Z7 /Od
+
+ DEBUG_VS2022_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi
+RELEASE_VS2022_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd
+NOOPT_VS2022_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi
+
+ DEBUG_VS2022_IA32_NASM_FLAGS = -Ox -f win32 -g
+RELEASE_VS2022_IA32_NASM_FLAGS = -Ox -f win32
+NOOPT_VS2022_IA32_NASM_FLAGS = -O0 -f win32 -g
+
+ DEBUG_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+RELEASE_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data
+NOOPT_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+
+##################
+# X64 definitions
+##################
+*_VS2022_X64_CC_PATH = DEF(VS2022_BIN_X64)\cl.exe
+*_VS2022_X64_PP_PATH = DEF(VS2022_BIN_X64)\cl.exe
+*_VS2022_X64_APP_PATH = DEF(VS2022_BIN_X64)\cl.exe
+*_VS2022_X64_VFRPP_PATH = DEF(VS2022_BIN_X64)\cl.exe
+*_VS2022_X64_ASLCC_PATH = DEF(VS2022_BIN_X64)\cl.exe
+*_VS2022_X64_ASLPP_PATH = DEF(VS2022_BIN_X64)\cl.exe
+*_VS2022_X64_ASM_PATH = DEF(VS2022_BIN_X64)\ml64.exe
+*_VS2022_X64_SLINK_PATH = DEF(VS2022_BIN_X64)\lib.exe
+*_VS2022_X64_DLINK_PATH = DEF(VS2022_BIN_X64)\link.exe
+*_VS2022_X64_ASLDLINK_PATH = DEF(VS2022_BIN_X64)\link.exe
+
+ DEBUG_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Gw /volatileMetadata-
+RELEASE_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Gw /volatileMetadata-
+NOOPT_VS2022_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Z7 /Od /volatileMetadata-
+
+ DEBUG_VS2022_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi
+RELEASE_VS2022_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd
+NOOPT_VS2022_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi
+
+ DEBUG_VS2022_X64_NASM_FLAGS = -Ox -f win64 -g
+RELEASE_VS2022_X64_NASM_FLAGS = -Ox -f win64
+NOOPT_VS2022_X64_NASM_FLAGS = -O0 -f win64 -g
+
+ DEBUG_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /ALIGN:4096 /DLL
+RELEASE_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data /ALIGN:4096 /DLL
+NOOPT_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /ALIGN:4096 /DLL
+
+#################
+# ARM definitions
+#################
+*_VS2022_ARM_CC_PATH = DEF(VS2022_BIN_ARM)\cl.exe
+*_VS2022_ARM_VFRPP_PATH = DEF(VS2022_BIN_ARM)\cl.exe
+*_VS2022_ARM_SLINK_PATH = DEF(VS2022_BIN_ARM)\lib.exe
+*_VS2022_ARM_DLINK_PATH = DEF(VS2022_BIN_ARM)\link.exe
+*_VS2022_ARM_APP_PATH = DEF(VS2022_BIN_ARM)\cl.exe
+*_VS2022_ARM_PP_PATH = DEF(VS2022_BIN_ARM)\cl.exe
+*_VS2022_ARM_ASM_PATH = DEF(VS2022_BIN_ARM)\armasm.exe
+*_VS2022_ARM_ASLCC_PATH = DEF(VS2022_BIN_ARM)\cl.exe
+*_VS2022_ARM_ASLPP_PATH = DEF(VS2022_BIN_ARM)\cl.exe
+*_VS2022_ARM_ASLDLINK_PATH = DEF(VS2022_BIN_ARM)\link.exe
+
+ *_VS2022_ARM_MAKE_FLAGS = /nologo
+ DEBUG_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi-
+RELEASE_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi-
+NOOPT_VS2022_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi-
+
+ DEBUG_VS2022_ARM_ASM_FLAGS = /nologo /g
+RELEASE_VS2022_ARM_ASM_FLAGS = /nologo
+NOOPT_VS2022_ARM_ASM_FLAGS = /nologo
+
+ DEBUG_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+RELEASE_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data
+NOOPT_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG
+
+#####################
+# AARCH64 definitions
+#####################
+*_VS2022_AARCH64_CC_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe
+*_VS2022_AARCH64_VFRPP_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe
+*_VS2022_AARCH64_SLINK_PATH = DEF(VS2022_BIN_AARCH64)\lib.exe
+*_VS2022_AARCH64_DLINK_PATH = DEF(VS2022_BIN_AARCH64)\link.exe
+*_VS2022_AARCH64_APP_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe
+*_VS2022_AARCH64_PP_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe
+*_VS2022_AARCH64_ASM_PATH = DEF(VS2022_BIN_AARCH64)\armasm64.exe
+*_VS2022_AARCH64_ASLCC_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe
+*_VS2022_AARCH64_ASLPP_PATH = DEF(VS2022_BIN_AARCH64)\cl.exe
+*_VS2022_AARCH64_ASLDLINK_PATH = DEF(VS2022_BIN_AARCH64)\link.exe
+
+ *_VS2022_AARCH64_MAKE_FLAGS = /nologo
+ DEBUG_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Gw /Oi-
+RELEASE_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Gw /Oi-
+NOOPT_VS2022_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /FIAutoGen.h /EHs-c- /GR- /GF /Gy /Zi /Od /Oi-
+
+ DEBUG_VS2022_AARCH64_ASM_FLAGS = /nologo /g
+RELEASE_VS2022_AARCH64_ASM_FLAGS = /nologo
+NOOPT_VS2022_AARCH64_ASM_FLAGS = /nologo
+
+ DEBUG_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG
+RELEASE_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /MERGE:.rdata=.data
+NOOPT_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG
+
+####################################################################################
# GCC Common
####################################################################################
@@ -739,11 +895,13 @@ NOOPT_*_*_OBJCOPY_ADDDEBUGFLAG = --add-gnu-debuglink="$(DEBUG_DIR)/$(MODULE_
*_*_*_DTCPP_PATH = DEF(DTCPP_BIN)
*_*_*_DTC_PATH = DEF(DTC_BIN)
-DEFINE GCC_ALL_CC_FLAGS = -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common
-DEFINE GCC_ARM_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -mabi=aapcs -fno-short-enums -funsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -Wno-address -mthumb -fno-pic -fno-pie
-DEFINE GCC_LOONGARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mabi=lp64d -fno-asynchronous-unwind-tables -fno-plt -Wno-address -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections
+# All supported GCC archs except LOONGARCH64 support -mstack-protector-guard=global, so set that on everything except LOONGARCH64
+DEFINE GCC_ALL_CC_FLAGS = -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common -fstack-protector
+DEFINE GCC_IA32_X64_CC_FLAGS = -mstack-protector-guard=global
+DEFINE GCC_ARM_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -mabi=aapcs -fno-short-enums -funsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -Wno-address -mthumb -fno-pic -fno-pie -mstack-protector-guard=global
+DEFINE GCC_LOONGARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mabi=lp64d -fno-asynchronous-unwind-tables -Wno-address -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections
DEFINE GCC_ARM_CC_XIPFLAGS = -mno-unaligned-access
-DEFINE GCC_AARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -fno-short-enums -fverbose-asm -funsigned-char -ffunction-sections -fdata-sections -Wno-address -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -ffixed-x18
+DEFINE GCC_AARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -fno-short-enums -fverbose-asm -funsigned-char -ffunction-sections -fdata-sections -Wno-address -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -ffixed-x18 -mstack-protector-guard=global
DEFINE GCC_AARCH64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only
DEFINE GCC_RISCV64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only
DEFINE GCC_DLINK_FLAGS_COMMON = -nostdlib --pie
@@ -771,7 +929,7 @@ DEFINE GCC_IA32_RC_FLAGS = -I binary -O elf32-i386 -B i386
DEFINE GCC_X64_RC_FLAGS = -I binary -O elf64-x86-64 -B i386 --rename-section .data=.hii
DEFINE GCC_ARM_RC_FLAGS = -I binary -O elf32-littlearm -B arm --rename-section .data=.hii
DEFINE GCC_AARCH64_RC_FLAGS = -I binary -O elf64-littleaarch64 -B aarch64 --rename-section .data=.hii
-DEFINE GCC_AARCH64_RC_BTI_FLAGS = --add-section .note.gnu.property=$(WORKSPACE)/ArmPkg/Library/GnuNoteBti.bin --set-section-flags .note.gnu.property=alloc,readonly
+DEFINE GCC_AARCH64_RC_BTI_FLAGS = --add-section .note.gnu.property=$(WORKSPACE)/BaseTools/Bin/GnuNoteBti.bin --set-section-flags .note.gnu.property=alloc,readonly
DEFINE GCC_RISCV64_RC_FLAGS = -I binary -O elf64-littleriscv -B riscv --rename-section .data=.hii
DEFINE GCC_LOONGARCH64_RC_FLAGS = -I binary -O elf64-loongarch -B loongarch64 --rename-section .data=.hii
@@ -780,8 +938,8 @@ DEFINE GCC_DEPS_FLAGS = -MMD -MF $@.deps
DEFINE GCC48_ALL_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings
DEFINE GCC48_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x20
-DEFINE GCC48_IA32_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) -m32 -march=i586 -malign-double -fno-stack-protector -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer
-DEFINE GCC48_X64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer
+DEFINE GCC48_IA32_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m32 -march=i586 -malign-double -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer
+DEFINE GCC48_X64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer
DEFINE GCC48_IA32_X64_ASLDLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable
DEFINE GCC48_IA32_X64_DLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive
DEFINE GCC48_IA32_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x220 DEF(GCC_DLINK2_FLAGS_COMMON)
@@ -790,7 +948,7 @@ DEFINE GCC48_X64_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 DEF
DEFINE GCC48_ASM_FLAGS = DEF(GCC_ASM_FLAGS)
DEFINE GCC48_ARM_ASM_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_ASM_FLAGS) -mlittle-endian
DEFINE GCC48_AARCH64_ASM_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_ASM_FLAGS) -mlittle-endian
-DEFINE GCC48_ARM_CC_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_ARM_CC_FLAGS) -fstack-protector -mword-relocations
+DEFINE GCC48_ARM_CC_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_ARM_CC_FLAGS) -mword-relocations
DEFINE GCC48_ARM_CC_XIPFLAGS = DEF(GCC_ARM_CC_XIPFLAGS)
DEFINE GCC48_AARCH64_CC_FLAGS = $(PLATFORM_FLAGS) -mcmodel=large DEF(GCC_AARCH64_CC_FLAGS)
DEFINE GCC48_AARCH64_CC_XIPFLAGS = DEF(GCC_AARCH64_CC_XIPFLAGS)
@@ -1407,10 +1565,10 @@ RELEASE_GCC5_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os
*_GCC5_ARM_CC_XIPFLAGS = DEF(GCC5_ARM_CC_XIPFLAGS)
DEBUG_GCC5_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable
- DEBUG_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm
+ DEBUG_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm
RELEASE_GCC5_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable
-RELEASE_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm
+RELEASE_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm
NOOPT_GCC5_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0
NOOPT_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -O0
@@ -1441,11 +1599,11 @@ RELEASE_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKS
*_GCC5_AARCH64_CC_XIPFLAGS = DEF(GCC5_AARCH64_CC_XIPFLAGS)
DEBUG_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable
- DEBUG_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch
+ DEBUG_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch
DEBUG_GCC5_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20
RELEASE_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable
-RELEASE_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch
+RELEASE_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch
RELEASE_GCC5_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20
NOOPT_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0
@@ -1624,10 +1782,10 @@ RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os
*_GCC_ARM_CC_XIPFLAGS = DEF(GCC5_ARM_CC_XIPFLAGS)
DEBUG_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable
- DEBUG_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm
+ DEBUG_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm
RELEASE_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable
-RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm
+RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm
NOOPT_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0
NOOPT_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -O0
@@ -1658,11 +1816,11 @@ RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSP
*_GCC_AARCH64_CC_XIPFLAGS = DEF(GCC5_AARCH64_CC_XIPFLAGS)
DEBUG_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable
- DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch
+ DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch
DEBUG_GCC_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20
RELEASE_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable
-RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch
+RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch
RELEASE_GCC_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20
NOOPT_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0
@@ -1938,7 +2096,7 @@ NOOPT_CLANGDWARF_X64_DLINK2_FLAGS = DEF(CLANGDWARF_X64_DLINK2_FLAGS) -O0 -fu
# CLANGDWARF ARM definitions
##################
DEFINE CLANGDWARF_ARM_TARGET = -target arm-linux-gnueabi
-DEFINE CLANGDWARF_ARM_CC_FLAGS = DEF(GCC_ARM_CC_FLAGS) DEF(CLANGDWARF_ARM_TARGET) DEF(CLANGDWARF_WARNING_OVERRIDES) -mno-movt
+DEFINE CLANGDWARF_ARM_CC_FLAGS = DEF(GCC_ARM_CC_FLAGS) DEF(CLANGDWARF_ARM_TARGET) DEF(CLANGDWARF_WARNING_OVERRIDES) -mno-movt -fno-stack-protector
DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLINK_FLAGS)
*_CLANGDWARF_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS)
@@ -1972,11 +2130,11 @@ DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLI
*_CLANGDWARF_ARM_CC_XIPFLAGS = DEF(GCC_ARM_CC_XIPFLAGS)
DEBUG_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O1
- DEBUG_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax
+ DEBUG_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax
NOOPT_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -O0
NOOPT_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -fuse-ld=lld -Wl,--no-pie,--no-relax
-RELEASE_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O3
-RELEASE_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax
+RELEASE_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -flto -Oz
+RELEASE_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax
##################
# CLANGDWARF AARCH64 definitions
@@ -2018,11 +2176,11 @@ DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_
*_CLANGDWARF_AARCH64_CC_XIPFLAGS = -mstrict-align
DEBUG_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O1
- DEBUG_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax
+ DEBUG_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax
NOOPT_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -O0
NOOPT_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -fuse-ld=lld -Wl,--no-pie,--no-relax
-RELEASE_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O3
-RELEASE_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/ArmPkg/Library/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax
+RELEASE_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -Oz
+RELEASE_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax
##################
# CLANGDWARF RISCV64 definitions
@@ -2073,7 +2231,7 @@ DEFINE CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF
DEBUG_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -Wl,--no-pie,--no-relax
NOOPT_CLANGDWARF_RISCV64_CC_FLAGS = DEF(CLANGDWARF_RISCV64_CC_FLAGS) $(PLATFORM_FLAGS) -O0
NOOPT_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_DLINK_FLAGS) -fuse-ld=lld -Wl,--no-pie,--no-relax
-RELEASE_CLANGDWARF_RISCV64_CC_FLAGS = DEF(CLANGDWARF_RISCV64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O3
+RELEASE_CLANGDWARF_RISCV64_CC_FLAGS = DEF(CLANGDWARF_RISCV64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -Oz
RELEASE_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -Wl,--no-pie,--no-relax
#
diff --git a/BaseTools/Plugin/CodeQL/CodeQlQueries.qls b/BaseTools/Plugin/CodeQL/CodeQlQueries.qls
index 1a50983..0da9baf 100644
--- a/BaseTools/Plugin/CodeQL/CodeQlQueries.qls
+++ b/BaseTools/Plugin/CodeQL/CodeQlQueries.qls
@@ -2,7 +2,7 @@
- description: C++ queries
- queries: '.'
- from: codeql/cpp-queries
+ from: codeql/cpp-queries@1.1.0
##########################################################################################
# Queries
@@ -70,8 +70,6 @@
- include:
id: cpp/unused-local-variable
- include:
- id: cpp/unused-static-function
-- include:
id: cpp/unused-static-variable
# Note: Some queries above are not active by default with the below filter.
diff --git a/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml b/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml
index dbc9c2b..3be80cb 100644
--- a/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml
+++ b/BaseTools/Plugin/CodeQL/codeqlcli_ext_dep.yaml
@@ -8,6 +8,13 @@
# In an environment where a platform might build in different operating systems, it is recommended to set
# the scope for the appropriate CodeQL external dependency based on the host operating system being used.
#
+# ****VERSION UPDATE INSTRUCTIONS****
+#
+# When updating the CodeQL CLI used here, update the corresponding codeql/cpp-queries version in CodeQlQueries.qls.
+# Visit the `qlpack.yml` in the release branch for the CodeQL CLI to get the version to use there. For example, the
+# CodeQL CLI 2.18.1 file is https://github.com/github/codeql/blob/codeql-cli-2.18.1/cpp/ql/src/qlpack.yml and the
+# pack version there is 1.1.0.
+#
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
@@ -16,9 +23,9 @@
"scope": "codeql-ext-dep",
"type": "web",
"name": "codeql_cli",
- "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.17.3/codeql.zip",
- "version": "2.17.3",
- "sha256": "e5ac1d87ab38e405c9af5db234a338b10dffabc98a648903f1664dd2a566dfd5",
+ "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.18.1/codeql.zip",
+ "version": "2.18.1",
+ "sha256": "815f71c1a46e76f9dafdec26c2a4bab7ea4019a3773e91e39253e2d21cf792a2",
"compression_type": "zip",
"internal_path": "/codeql/",
"flags": ["set_shell_var", ],
diff --git a/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml b/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml
index 536322f..e3fd40c 100644
--- a/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml
+++ b/BaseTools/Plugin/CodeQL/codeqlcli_linux_ext_dep.yaml
@@ -6,6 +6,13 @@
# systems, it is recommended to set the scope for the appropriate CodeQL external dependency based on the
# host operating system being used.
#
+# ****VERSION UPDATE INSTRUCTIONS****
+#
+# When updating the CodeQL CLI used here, update the corresponding codeql/cpp-queries version in CodeQlQueries.qls.
+# Visit the `qlpack.yml` in the release branch for the CodeQL CLI to get the version to use there. For example, the
+# CodeQL CLI 2.18.1 file is https://github.com/github/codeql/blob/codeql-cli-2.18.1/cpp/ql/src/qlpack.yml and the
+# pack version there is 1.1.0.
+#
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
@@ -14,9 +21,9 @@
"scope": "codeql-linux-ext-dep",
"type": "web",
"name": "codeql_linux_cli",
- "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.17.3/codeql-linux64.zip",
- "version": "2.17.3",
- "sha256": "9fba000c4b821534d354bc16821aa066fdb1304446226ea449870e64a8ad3c7a",
+ "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.18.1/codeql-linux64.zip",
+ "version": "2.18.1",
+ "sha256": "1547f4a3b509474404daf2e4b821f71cd93462ec45322d9124c2b04e3d52c771",
"compression_type": "zip",
"internal_path": "/codeql/",
"flags": ["set_shell_var", ],
diff --git a/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml b/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml
index 93a81ff..5e6add8 100644
--- a/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml
+++ b/BaseTools/Plugin/CodeQL/codeqlcli_windows_ext_dep.yaml
@@ -6,6 +6,13 @@
# systems, it is recommended to set the scope for the appropriate CodeQL external dependency based on the
# host operating system being used.
#
+# ****VERSION UPDATE INSTRUCTIONS****
+#
+# When updating the CodeQL CLI used here, update the corresponding codeql/cpp-queries version in CodeQlQueries.qls.
+# Visit the `qlpack.yml` in the release branch for the CodeQL CLI to get the version to use there. For example, the
+# CodeQL CLI 2.18.1 file is https://github.com/github/codeql/blob/codeql-cli-2.18.1/cpp/ql/src/qlpack.yml and the
+# pack version there is 1.1.0.
+#
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
@@ -14,9 +21,9 @@
"scope": "codeql-windows-ext-dep",
"type": "web",
"name": "codeql_windows_cli",
- "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.17.3/codeql-win64.zip",
- "version": "2.17.3",
- "sha256": "4c6fbf2ea2eaf0f47bf0347eacf54c6b9d6bdf7acb6b63e17f9e6f2dd83b34e7",
+ "source": "https://github.com/github/codeql-cli-binaries/releases/download/v2.18.1/codeql-win64.zip",
+ "version": "2.18.1",
+ "sha256": "eb69c9ce40142904965ca3f2491c989f12747d74358385e2e94c427b4324201c",
"compression_type": "zip",
"internal_path": "/codeql/",
"flags": ["set_shell_var", ],
diff --git a/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py b/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py
index 2e5c462..31d13b2 100644
--- a/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py
+++ b/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py
@@ -110,6 +110,7 @@ class HostBasedUnitTestRunner(IUefiBuildPlugin):
if ret != 0:
logging.error("UnitTest Execution Error: " +
os.path.basename(test))
+ failure_count += 1
else:
logging.info("UnitTest Completed: " +
os.path.basename(test))
diff --git a/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py b/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py
deleted file mode 100644
index dab7a87..0000000
--- a/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# @file LinuxGcc5ToolChain.py
-# Plugin to configures paths for GCC5 ARM/AARCH64 Toolchain
-##
-# This plugin works in conjuncture with the tools_def
-#
-# Copyright (c) Microsoft Corporation
-# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
-# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-##
-import os
-import logging
-from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin
-from edk2toolext.environment import shell_environment
-
-
-class LinuxGcc5ToolChain(IUefiBuildPlugin):
-
- def do_post_build(self, thebuilder):
- return 0
-
- def do_pre_build(self, thebuilder):
- self.Logger = logging.getLogger("LinuxGcc5ToolChain")
-
- #
- # GCC5 - The ARM and AARCH64 compilers need their paths set if available
- if thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "GCC5":
-
- # Start with AARACH64 compiler
- ret = self._check_aarch64()
- if ret != 0:
- self.Logger.critical("Failed in check aarch64")
- return ret
-
- # Check arm compiler
- ret = self._check_arm()
- if ret != 0:
- self.Logger.critical("Failed in check arm")
- return ret
-
- # Check RISCV64 compiler
- ret = self._check_riscv64()
- if ret != 0:
- self.Logger.critical("Failed in check riscv64")
- return ret
-
- # Check LoongArch64 compiler
- ret = self._check_loongarch64()
- if ret != 0:
- self.Logger.critical("Failed in check loongarch64")
- return ret
-
- return 0
-
- def _check_arm(self):
- # check to see if full path already configured
- if shell_environment.GetEnvironment().get_shell_var("GCC5_ARM_PREFIX") is not None:
- self.Logger.info("GCC5_ARM_PREFIX is already set.")
-
- else:
- # now check for install dir. If set then set the Prefix
- install_path = shell_environment.GetEnvironment().get_shell_var("GCC5_ARM_INSTALL")
- if install_path is None:
- return 0
-
- # make GCC5_ARM_PREFIX to align with tools_def.txt
- prefix = os.path.join(install_path, "bin", "arm-none-linux-gnueabihf-")
- shell_environment.GetEnvironment().set_shell_var("GCC5_ARM_PREFIX", prefix)
-
- # now confirm it exists
- if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC5_ARM_PREFIX") + "gcc"):
- self.Logger.error("Path for GCC5_ARM_PREFIX toolchain is invalid")
- return -2
-
- return 0
-
- def _check_aarch64(self):
- # check to see if full path already configured
- if shell_environment.GetEnvironment().get_shell_var("GCC5_AARCH64_PREFIX") is not None:
- self.Logger.info("GCC5_AARCH64_PREFIX is already set.")
-
- else:
- # now check for install dir. If set then set the Prefix
- install_path = shell_environment.GetEnvironment(
- ).get_shell_var("GCC5_AARCH64_INSTALL")
- if install_path is None:
- return 0
-
- # make GCC5_AARCH64_PREFIX to align with tools_def.txt
- prefix = os.path.join(install_path, "bin", "aarch64-none-linux-gnu-")
- shell_environment.GetEnvironment().set_shell_var("GCC5_AARCH64_PREFIX", prefix)
-
- # now confirm it exists
- if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC5_AARCH64_PREFIX") + "gcc"):
- self.Logger.error(
- "Path for GCC5_AARCH64_PREFIX toolchain is invalid")
- return -2
-
- return 0
-
- def _check_riscv64(self):
- # now check for install dir.  If set then set the Prefix
- install_path = shell_environment.GetEnvironment(
- ).get_shell_var("GCC5_RISCV64_INSTALL")
- if install_path is None:
- return 0
-
- # check to see if full path already configured
- if shell_environment.GetEnvironment().get_shell_var("GCC5_RISCV64_PREFIX") is not None:
- self.Logger.info("GCC5_RISCV64_PREFIX is already set.")
-
- else:
- # make GCC5_RISCV64_PREFIX to align with tools_def.txt
- prefix = os.path.join(install_path, "bin", "riscv64-unknown-elf-")
- shell_environment.GetEnvironment().set_shell_var("GCC5_RISCV64_PREFIX", prefix)
-
- # now confirm it exists
- if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC5_RISCV64_PREFIX") + "gcc"):
- self.Logger.error(
- "Path for GCC5_RISCV64_PREFIX toolchain is invalid")
- return -2
-
- # Check if LD_LIBRARY_PATH is set for the libraries of RISC-V GCC toolchain
- if shell_environment.GetEnvironment().get_shell_var("LD_LIBRARY_PATH") is not None:
- self.Logger.info("LD_LIBRARY_PATH is already set.")
-
- prefix = os.path.join(install_path, "lib")
- shell_environment.GetEnvironment().set_shell_var("LD_LIBRARY_PATH", prefix)
-
- return 0
-
- def _check_loongarch64(self):
- # check to see if full path already configured
- if shell_environment.GetEnvironment().get_shell_var("GCC5_LOONGARCH64_PREFIX") is not None:
- self.Logger.info("GCC5_LOONGARCH64_PREFIX is already set.")
-
- else:
- # now check for install dir. If set then set the Prefix
- install_path = shell_environment.GetEnvironment(
- ).get_shell_var("GCC5_LOONGARCH64_INSTALL")
- if install_path is None:
- return 0
-
- # make GCC5_LOONGARCH64_PREFIX to align with tools_def.txt
- prefix = os.path.join(install_path, "bin", "loongarch64-unknown-linux-gnu-")
- shell_environment.GetEnvironment().set_shell_var("GCC5_LOONGARCH64_PREFIX", prefix)
-
- # now confirm it exists
- if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("GCC5_LOONGARCH64_PREFIX") + "gcc"):
- self.Logger.error(
- "Path for GCC5_LOONGARCH64_PREFIX toolchain is invalid")
- return -2
-
- return 0
diff --git a/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain_plug_in.yaml b/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain_plug_in.yaml
deleted file mode 100644
index 39c378a..0000000
--- a/BaseTools/Plugin/LinuxGcc5ToolChain/LinuxGcc5ToolChain_plug_in.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-## @file
-# Build Plugin used to set the path
-# for the GCC5 ARM/AARCH64 downloaded compilers
-#
-# Copyright (c) Microsoft Corporation.
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-##
-{
- "scope": "global-nix",
- "name": "Linux GCC5 Tool Chain Support",
- "module": "LinuxGcc5ToolChain"
-}
diff --git a/BaseTools/Plugin/LinuxGccToolChain/LinuxGccToolChain.py b/BaseTools/Plugin/LinuxGccToolChain/LinuxGccToolChain.py
new file mode 100644
index 0000000..e7ef3df
--- /dev/null
+++ b/BaseTools/Plugin/LinuxGccToolChain/LinuxGccToolChain.py
@@ -0,0 +1,165 @@
+# @file LinuxGccToolChain.py
+# Plugin to configures paths for GCC/GCC5 ARM/AARCH64/RISCV/LOONGARCH64 Toolchain
+##
+# This plugin sets environment variables used in tools_def.template to specify the GCC compiler
+# for the requested build architecture.
+#
+# Copyright (c) Microsoft Corporation
+# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+import os
+import logging
+from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin
+from edk2toolext.environment import shell_environment
+
+
+class LinuxGccToolChain(IUefiBuildPlugin):
+
+ def do_post_build(self, thebuilder):
+ return 0
+
+ def do_pre_build(self, thebuilder):
+ self.Logger = logging.getLogger("LinuxGccToolChain")
+
+ #
+ # In order to keep this plugin backwards compatible with the older GCC5 toolchain tag,
+ # we support setting either the GCC5 or GCC set of env variables required
+ #
+ toolchain = "GCC"
+
+ #
+ # GCC - The non-x86 compilers need their paths set if available. To make this more stable, check for
+ # any substring of GCC in the TOOL_CHAIN_TAG to get the right compiler
+ #
+ if "GCC" in thebuilder.env.GetValue("TOOL_CHAIN_TAG"):
+ if "GCC5" in thebuilder.env.GetValue("TOOL_CHAIN_TAG"):
+ toolchain = "GCC5"
+
+ # Start with AARACH64 compiler
+ ret = self._check_aarch64(toolchain)
+ if ret != 0:
+ self.Logger.critical("Failed in check aarch64")
+ return ret
+
+ # Check arm compiler
+ ret = self._check_arm(toolchain)
+ if ret != 0:
+ self.Logger.critical("Failed in check arm")
+ return ret
+
+ # Check RISCV64 compiler
+ ret = self._check_riscv64(toolchain)
+ if ret != 0:
+ self.Logger.critical("Failed in check riscv64")
+ return ret
+
+ # Check LoongArch64 compiler
+ ret = self._check_loongarch64(toolchain)
+ if ret != 0:
+ self.Logger.critical("Failed in check loongarch64")
+ return ret
+
+ return 0
+
+ def _check_arm(self, toolchain):
+ # check to see if full path already configured
+ if shell_environment.GetEnvironment().get_shell_var(toolchain + "_ARM_PREFIX") is not None:
+ self.Logger.info(toolchain + "_ARM_PREFIX is already set.")
+
+ else:
+ # now check for install dir. If set then set the Prefix
+ install_path = shell_environment.GetEnvironment().get_shell_var(toolchain + "_ARM_INSTALL")
+ if install_path is None:
+ return 0
+
+ # make the PREFIX to align with tools_def.txt
+ prefix = os.path.join(install_path, "bin", "arm-none-linux-gnueabihf-")
+ shell_environment.GetEnvironment().set_shell_var(toolchain + "_ARM_PREFIX", prefix)
+
+ # now confirm it exists
+ if not os.path.exists(shell_environment.GetEnvironment().get_shell_var(toolchain + "_ARM_PREFIX") + "gcc"):
+ self.Logger.error("Path for " + toolchain + "_ARM_PREFIX toolchain is invalid")
+ return -2
+
+ return 0
+
+ def _check_aarch64(self, toolchain):
+ # check to see if full path already configured
+ if shell_environment.GetEnvironment().get_shell_var(toolchain + "_AARCH64_PREFIX") is not None:
+ self.Logger.info(toolchain + "_AARCH64_PREFIX is already set.")
+
+ else:
+ # now check for install dir. If set then set the Prefix
+ install_path = shell_environment.GetEnvironment(
+ ).get_shell_var(toolchain + "_AARCH64_INSTALL")
+ if install_path is None:
+ return 0
+
+ # make PREFIX to align with tools_def.txt
+ prefix = os.path.join(install_path, "bin", "aarch64-none-linux-gnu-")
+ shell_environment.GetEnvironment().set_shell_var(toolchain + "_AARCH64_PREFIX", prefix)
+
+ # now confirm it exists
+ if not os.path.exists(shell_environment.GetEnvironment().get_shell_var(toolchain + "_AARCH64_PREFIX") + "gcc"):
+ self.Logger.error(
+ "Path for " + toolchain + "_AARCH64_PREFIX toolchain is invalid")
+ return -2
+
+ return 0
+
+ def _check_riscv64(self, toolchain):
+ # now check for install dir. If set then set the Prefix
+ install_path = shell_environment.GetEnvironment(
+ ).get_shell_var(toolchain + "_RISCV64_INSTALL")
+ if install_path is None:
+ return 0
+
+ # check to see if full path already configured
+ if shell_environment.GetEnvironment().get_shell_var(toolchain + "_RISCV64_PREFIX") is not None:
+ self.Logger.info(toolchain + "_RISCV64_PREFIX is already set.")
+
+ else:
+ # make PREFIX to align with tools_def.txt
+ prefix = os.path.join(install_path, "bin", "riscv64-unknown-elf-")
+ shell_environment.GetEnvironment().set_shell_var(toolchain + "_RISCV64_PREFIX", prefix)
+
+ # now confirm it exists
+ if not os.path.exists(shell_environment.GetEnvironment().get_shell_var(toolchain + "_RISCV64_PREFIX") + "gcc"):
+ self.Logger.error(
+ "Path for " + toolchain + "_RISCV64_PREFIX toolchain is invalid")
+ return -2
+
+ # Check if LD_LIBRARY_PATH is set for the libraries of RISC-V GCC toolchain
+ if shell_environment.GetEnvironment().get_shell_var("LD_LIBRARY_PATH") is not None:
+ self.Logger.info("LD_LIBRARY_PATH is already set.")
+
+ prefix = os.path.join(install_path, "lib")
+ shell_environment.GetEnvironment().set_shell_var("LD_LIBRARY_PATH", prefix)
+
+ return 0
+
+ def _check_loongarch64(self, toolchain):
+ # check to see if full path already configured
+ if shell_environment.GetEnvironment().get_shell_var(toolchain + "_LOONGARCH64_PREFIX") is not None:
+ self.Logger.info(toolchain + "_LOONGARCH64_PREFIX is already set.")
+
+ else:
+ # now check for install dir. If set then set the Prefix
+ install_path = shell_environment.GetEnvironment(
+ ).get_shell_var(toolchain + "_LOONGARCH64_INSTALL")
+ if install_path is None:
+ return 0
+
+ # make PREFIX to align with tools_def.txt
+ prefix = os.path.join(install_path, "bin", "loongarch64-unknown-linux-gnu-")
+ shell_environment.GetEnvironment().set_shell_var(toolchain + "_LOONGARCH64_PREFIX", prefix)
+
+ # now confirm it exists
+ if not os.path.exists(shell_environment.GetEnvironment().get_shell_var(toolchain + "_LOONGARCH64_PREFIX") + "gcc"):
+ self.Logger.error(
+ "Path for " + toolchain + "_LOONGARCH64_PREFIX toolchain is invalid")
+ return -2
+
+ return 0
diff --git a/BaseTools/Plugin/LinuxGccToolChain/LinuxGccToolChain_plug_in.yaml b/BaseTools/Plugin/LinuxGccToolChain/LinuxGccToolChain_plug_in.yaml
new file mode 100644
index 0000000..dd1e14c
--- /dev/null
+++ b/BaseTools/Plugin/LinuxGccToolChain/LinuxGccToolChain_plug_in.yaml
@@ -0,0 +1,12 @@
+## @file
+# This plugin sets environment variables used in tools_def.template to specify the GCC compiler
+# for the requested build architecture.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+ "scope": "global-nix",
+ "name": "Linux GCC Tool Chain Support",
+ "module": "LinuxGccToolChain"
+}
diff --git a/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py b/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py
index ec2f2d1..348e847 100644
--- a/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py
+++ b/BaseTools/Plugin/WindowsResourceCompiler/WinRcPath.py
@@ -6,24 +6,40 @@
# Copyright (c) Microsoft Corporation
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
-import os
+import logging
from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin
import edk2toollib.windows.locate_tools as locate_tools
from edk2toolext.environment import shell_environment
from edk2toolext.environment import version_aggregator
+from pathlib import Path
-class WinRcPath(IUefiBuildPlugin):
- def do_post_build(self, thebuilder):
- return 0
+class WinRcPath(IUefiBuildPlugin):
def do_pre_build(self, thebuilder):
- #get the locate tools module
+ # Check if the rc.exe path is already cached and still exists
+ cache_path = Path(thebuilder.ws, "Conf", ".rc_path")
+ if cache_path.exists():
+ with open(cache_path, "r") as f:
+ rc_path = Path(f.readline().strip()).absolute()
+ if (rc_path / "rc.exe").exists():
+ logging.debug(f"Found rc.exe folder in cache: {rc_path}")
+ self._set_path(rc_path)
+ return 0
+
+ # If it does not exist, try to find it with FindToolInWinSdk
path = locate_tools.FindToolInWinSdk("rc.exe")
if path is None:
- thebuilder.logging.warning("Failed to find rc.exe")
- else:
- p = os.path.abspath(os.path.dirname(path))
- shell_environment.GetEnvironment().set_shell_var("WINSDK_PATH_FOR_RC_EXE", p)
- version_aggregator.GetVersionAggregator().ReportVersion("WINSDK_PATH_FOR_RC_EXE", p, version_aggregator.VersionTypes.INFO)
+ logging.critical("Failed to find rc.exe")
+ return 1
+
+ path = Path(path).absolute().parent
+ self._set_path(path)
+ cache_path.unlink(missing_ok=True)
+ with cache_path.open("w") as f:
+ f.write(str(path))
return 0
+
+ def _set_path(self, path: Path):
+ shell_environment.GetEnvironment().set_shell_var("WINSDK_PATH_FOR_RC_EXE", str(path))
+ version_aggregator.GetVersionAggregator().ReportVersion("WINSDK_PATH_FOR_RC_EXE", str(path), version_aggregator.VersionTypes.INFO)
diff --git a/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py b/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py
index 615b5ed..04e59f1 100644
--- a/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py
+++ b/BaseTools/Plugin/WindowsVsToolChain/WindowsVsToolChain.py
@@ -1,5 +1,8 @@
# @file WindowsVsToolChain.py
-# Plugin to configures paths for the VS2017 and VS2019 tool chain
+# Plugin to configure the environment for the VS2017, VS2019, and VS2022 toolchains
+#
+# This plugin also runs for CLANGPDB toolchain on Windows as that toolchain
+# leverages nmake from VS and needs to the SDK paths for unit tests
##
# This plugin works in conjuncture with the tools_def
#
@@ -173,6 +176,159 @@ class WindowsVsToolChain(IUefiBuildPlugin):
self.Logger.error("Path for VS2019 toolchain is invalid")
return -2
+ #
+ # VS2022 - VS2022 allows a user to install many copies/versions of the tools.
+ # If a specific version is required then the user must set both env variables:
+ # VS170INSTALLPATH: base install path on system to VC install dir. Here you will find the VC folder, etc
+ # VS170TOOLVER: version number for the VC compiler tools
+ # VS2022_PREFIX: path to MSVC compiler folder with trailing slash (can be used instead of two vars above)
+ # VS2022_HOST: set the host architecture to use for host tools, and host libs, etc
+ elif thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "VS2022":
+
+ # check to see if host is configured
+ # HostType for VS2022 should be (defined in tools_def):
+ # x86 == 32bit Intel
+ # x64 == 64bit Intel
+ # arm == 32bit Arm
+ # arm64 == 64bit Arm
+ #
+ HostType = shell_environment.GetEnvironment().get_shell_var("VS2022_HOST")
+ if HostType is not None:
+ HostType = HostType.lower()
+ self.Logger.info(
+ f"HOST TYPE defined by environment. Host Type is {HostType}")
+ else:
+ HostInfo = GetHostInfo()
+ if HostInfo.arch == "x86":
+ if HostInfo.bit == "32":
+ HostType = "x86"
+ elif HostInfo.bit == "64":
+ HostType = "x64"
+ else:
+ raise NotImplementedError()
+
+ # VS2022_HOST options are not exactly the same as QueryVcVariables. This translates.
+ VC_HOST_ARCH_TRANSLATOR = {
+ "x86": "x86", "x64": "AMD64", "arm": "not supported", "arm64": "not supported"}
+
+ # check to see if full path already configured
+ if shell_environment.GetEnvironment().get_shell_var("VS2022_PREFIX") is not None:
+ self.Logger.debug("VS2022_PREFIX is already set.")
+
+ else:
+ install_path = self._get_vs_install_path(
+ "VS2022".lower(), "VS170INSTALLPATH")
+ vc_ver = self._get_vc_version(install_path, "VS170TOOLVER")
+
+ if install_path is None or vc_ver is None:
+ self.Logger.error(
+ "Failed to configure environment for VS2022")
+ return -1
+
+ version_aggregator.GetVersionAggregator().ReportVersion(
+ "Visual Studio Install Path", install_path, version_aggregator.VersionTypes.INFO)
+ version_aggregator.GetVersionAggregator().ReportVersion(
+ "VC Version", vc_ver, version_aggregator.VersionTypes.TOOL)
+
+ # make VS2022_PREFIX to align with tools_def.txt
+ prefix = os.path.join(install_path, "VC",
+ "Tools", "MSVC", vc_ver)
+ prefix = prefix + os.path.sep
+ shell_environment.GetEnvironment().set_shell_var("VS2022_PREFIX", prefix)
+ shell_environment.GetEnvironment().set_shell_var("VS2022_HOST", HostType)
+
+ shell_env = shell_environment.GetEnvironment()
+ # Use the tools lib to determine the correct values for the vars that interest us.
+ vs_vars = locate_tools.QueryVcVariables(
+ interesting_keys, VC_HOST_ARCH_TRANSLATOR[HostType], vs_version="VS2022")
+ for (k, v) in vs_vars.items():
+ shell_env.set_shell_var(k, v)
+
+ # now confirm it exists
+ if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("VS2022_PREFIX")):
+ self.Logger.error("Path for VS2022 toolchain is invalid")
+ return -2
+
+ #
+ # CLANGPDB on Windows uses nmake from
+ # the VS compiler toolchain. Find a version and set
+ # as the CLANG_HOST_BIN path if not already set.
+ #
+ # Also get the platform header files, SDK, etc based on the
+ # host type. This is used for unit test compilation.
+ # If CLANG_VS_HOST is not set then find the host type based on Host Info.
+ ##
+ elif thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "CLANGPDB":
+ HostInfo = GetHostInfo()
+
+ # check to see if host is configured
+ # HostType for VS tools should be (defined in tools_def):
+ # x86 == 32bit Intel
+ # x64 == 64bit Intel
+ # arm == 32bit Arm
+ # arm64 == 64bit Arm
+ #
+ HostType = shell_environment.GetEnvironment().get_shell_var("CLANG_VS_HOST")
+ if HostType is not None:
+ HostType = HostType.lower()
+ self.Logger.info(
+ f"CLANG_VS_HOST defined by environment. Value is {HostType}")
+ else:
+ #figure it out based on host info
+ if HostInfo.arch == "x86":
+ if HostInfo.bit == "32":
+ HostType = "x86"
+ elif HostInfo.bit == "64":
+ HostType = "x64"
+ else:
+ # anything other than x86 or x64 is not supported
+ raise NotImplementedError()
+
+ # CLANG_VS_HOST options are not exactly the same as QueryVcVariables. This translates.
+ VC_HOST_ARCH_TRANSLATOR = {
+ "x86": "x86", "x64": "AMD64", "arm": "not supported", "arm64": "not supported"}
+
+ # now get the environment variables for the platform
+ shell_env = shell_environment.GetEnvironment()
+ # Use the tools lib to determine the correct values for the vars that interest us.
+ vs_vars = locate_tools.QueryVcVariables(
+ interesting_keys, VC_HOST_ARCH_TRANSLATOR[HostType])
+ for (k, v) in vs_vars.items():
+ shell_env.set_shell_var(k, v)
+
+ ##
+ # If environment already has CLANG_HOST_BIN set then user has already
+ # set the path to the VS tools like nmake.exe
+ ##
+ if shell_environment.GetEnvironment().get_shell_var("CLANG_HOST_BIN") is not None:
+ self.Logger.debug("CLANG_HOST_BIN is already set.")
+
+ else:
+ install_path = self._get_vs_install_path(None, None)
+ vc_ver = self._get_vc_version(install_path, None)
+
+ if install_path is None or vc_ver is None:
+ self.Logger.error("Failed to configure environment for VS")
+ return -1
+
+ version_aggregator.GetVersionAggregator().ReportVersion(
+ "Visual Studio Install Path", install_path, version_aggregator.VersionTypes.INFO)
+ version_aggregator.GetVersionAggregator().ReportVersion(
+ "VC Version", vc_ver, version_aggregator.VersionTypes.TOOL)
+
+ # make path align with tools_def.txt
+ prefix = os.path.join(install_path, "VC", "Tools", "MSVC", vc_ver)
+ clang_host_bin_prefix = os.path.join(prefix, "bin", "Host%s" % HostType, HostType)
+
+ # now confirm it exists
+ if not os.path.exists(clang_host_bin_prefix):
+ self.Logger.error("Path for VS toolchain is invalid")
+ return -2
+
+ # The environment is using nmake (not make) so add "n" to the end of the path.
+ # The rest of the command is derived from definitions in tools.def.
+ shell_environment.GetEnvironment().set_shell_var("CLANG_HOST_BIN", os.path.join(clang_host_bin_prefix, "n"))
+
return 0
def _get_vs_install_path(self, vs_version, varname):
diff --git a/BaseTools/Scripts/BinToPcd.py b/BaseTools/Scripts/BinToPcd.py
index be726cc..43fc458 100644
--- a/BaseTools/Scripts/BinToPcd.py
+++ b/BaseTools/Scripts/BinToPcd.py
@@ -37,13 +37,13 @@ if __name__ == '__main__':
return Value
def ValidatePcdName (Argument):
- if re.split ('[a-zA-Z\_][a-zA-Z0-9\_]*\.[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) != ['', '']:
+ if re.split (r'[a-zA-Z\_][a-zA-Z0-9\_]*\.[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) != ['', '']:
Message = '{Argument} is not in the form <PcdTokenSpaceGuidCName>.<PcdCName>'.format (Argument = Argument)
raise argparse.ArgumentTypeError (Message)
return Argument
def ValidateGuidName (Argument):
- if re.split ('[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) != ['', '']:
+ if re.split (r'[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) != ['', '']:
Message = '{Argument} is not a valid GUID C name'.format (Argument = Argument)
raise argparse.ArgumentTypeError (Message)
return Argument
diff --git a/BaseTools/Scripts/GetMaintainer.py b/BaseTools/Scripts/GetMaintainer.py
index 8097ba4..986550c 100644
--- a/BaseTools/Scripts/GetMaintainer.py
+++ b/BaseTools/Scripts/GetMaintainer.py
@@ -179,6 +179,10 @@ if __name__ == '__main__':
PARSER.add_argument('-l', '--lookup',
help='Find section matches for path LOOKUP',
required=False)
+ PARSER.add_argument('-g', '--github',
+ action='store_true',
+ help='Include GitHub usernames in output',
+ required=False)
ARGS = PARSER.parse_args()
REPO = SetupGit.locate_repo()
@@ -203,5 +207,8 @@ if __name__ == '__main__':
for address in ADDRESSES:
if '<' in address and '>' in address:
- address = address.split('>', 1)[0] + '>'
- print(' %s' % address)
+ address, github_id = address.split('>', 1)
+ address = address + '>'
+ github_id = github_id.strip() if ARGS.github else ''
+
+ print(' %s %s' % (address, github_id))
diff --git a/BaseTools/Scripts/PatchCheck.py b/BaseTools/Scripts/PatchCheck.py
index d797ac8..83d6795 100755
--- a/BaseTools/Scripts/PatchCheck.py
+++ b/BaseTools/Scripts/PatchCheck.py
@@ -395,7 +395,6 @@ class GitDiffCheck:
self.force_notabs = False
if self.filename.endswith('.sh') or \
self.filename.startswith('BaseTools/BinWrappers/PosixLike/') or \
- self.filename.startswith('BaseTools/BinPipWrappers/PosixLike/') or \
self.filename == 'BaseTools/BuildEnv':
#
# Do not enforce CR/LF line endings for linux shell scripts.
diff --git a/BaseTools/Source/C/Common/Decompress.c b/BaseTools/Source/C/Common/Decompress.c
index 0f2bdbf..0cf0c4a 100644
--- a/BaseTools/Source/C/Common/Decompress.c
+++ b/BaseTools/Source/C/Common/Decompress.c
@@ -15,7 +15,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
//
// Decompression algorithm begins here
//
+#ifndef UINT8_MAX
#define UINT8_MAX 0xff
+#endif
#define BITBUFSIZ 32
#define MAXMATCH 256
#define THRESHOLD 3
diff --git a/BaseTools/Source/C/Include/Common/BaseTypes.h b/BaseTools/Source/C/Include/Common/BaseTypes.h
index e669da8..5093a2f 100644
--- a/BaseTools/Source/C/Include/Common/BaseTypes.h
+++ b/BaseTools/Source/C/Include/Common/BaseTypes.h
@@ -4,6 +4,8 @@
This file is stand alone self consistent set of definitions.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -202,7 +204,7 @@ typedef UINTN RETURN_STATUS;
#define ENCODE_ERROR(a) ((RETURN_STATUS)(MAX_BIT | (a)))
#define ENCODE_WARNING(a) ((RETURN_STATUS)(a))
-#define RETURN_ERROR(a) (((INTN)(RETURN_STATUS)(a)) < 0)
+#define RETURN_ERROR(a) (((RETURN_STATUS)(a)) >= MAX_BIT)
#define RETURN_SUCCESS 0
#define RETURN_LOAD_ERROR ENCODE_ERROR (1)
diff --git a/BaseTools/Source/C/Include/Common/UefiMultiPhase.h b/BaseTools/Source/C/Include/Common/UefiMultiPhase.h
index b889508..5b5af8b 100644
--- a/BaseTools/Source/C/Include/Common/UefiMultiPhase.h
+++ b/BaseTools/Source/C/Include/Common/UefiMultiPhase.h
@@ -14,6 +14,15 @@
//
// Enumeration of memory types introduced in UEFI.
+// +---------------------------------------------------+
+// | 0..(EfiMaxMemoryType - 1) - Normal memory type |
+// +---------------------------------------------------+
+// | EfiMaxMemoryType..0x6FFFFFFF - Invalid |
+// +---------------------------------------------------+
+// | 0x70000000..0x7FFFFFFF - OEM reserved |
+// +---------------------------------------------------+
+// | 0x80000000..0xFFFFFFFF - OS reserved |
+// +---------------------------------------------------+
//
typedef enum {
EfiReservedMemoryType,
@@ -31,7 +40,11 @@ typedef enum {
EfiMemoryMappedIOPortSpace,
EfiPalCode,
EfiPersistentMemory,
- EfiMaxMemoryType
+ EfiMaxMemoryType,
+ MEMORY_TYPE_OEM_RESERVED_MIN = 0x70000000,
+ MEMORY_TYPE_OEM_RESERVED_MAX = 0x7FFFFFFF,
+ MEMORY_TYPE_OS_RESERVED_MIN = 0x80000000,
+ MEMORY_TYPE_OS_RESERVED_MAX = 0xFFFFFFFF
} EFI_MEMORY_TYPE;
diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py
index 5ad10ce..86991e7 100755
--- a/BaseTools/Source/Python/AutoGen/GenC.py
+++ b/BaseTools/Source/Python/AutoGen/GenC.py
@@ -21,6 +21,9 @@ from .StrGather import *
from .GenPcdDb import CreatePcdDatabaseCode
from .IdfClassObject import *
+import json
+import secrets
+
## PCD type string
gItemTypeStringDatabase = {
TAB_PCDS_FEATURE_FLAG : TAB_PCDS_FIXED_AT_BUILD,
@@ -2039,6 +2042,34 @@ def CreateFooterCode(Info, AutoGenC, AutoGenH):
def CreateCode(Info, AutoGenC, AutoGenH, StringH, UniGenCFlag, UniGenBinBuffer, StringIdf, IdfGenCFlag, IdfGenBinBuffer):
CreateHeaderCode(Info, AutoGenC, AutoGenH)
+ # The only 32 bit archs we have are IA32 and ARM, everything else is 64 bit
+ Bitwidth = 32 if Info.Arch == 'IA32' or Info.Arch == 'ARM' else 64
+
+ if GlobalData.gStackCookieValues64 == [] and os.path.exists(os.path.join(Info.PlatformInfo.BuildDir, "StackCookieValues64.json")):
+ with open (os.path.join(Info.PlatformInfo.BuildDir, "StackCookieValues64.json"), "r") as file:
+ GlobalData.gStackCookieValues64 = json.load(file)
+ if GlobalData.gStackCookieValues32 == [] and os.path.exists(os.path.join(Info.PlatformInfo.BuildDir, "StackCookieValues32.json")):
+ with open (os.path.join(Info.PlatformInfo.BuildDir, "StackCookieValues32.json"), "r") as file:
+ GlobalData.gStackCookieValues32 = json.load(file)
+
+ try:
+ if Bitwidth == 32:
+ CookieValue = int(GlobalData.gStackCookieValues32[hash(Info.Guid) % len(GlobalData.gStackCookieValues32)])
+ else:
+ CookieValue = int(GlobalData.gStackCookieValues64[hash(Info.Guid) % len(GlobalData.gStackCookieValues64)])
+ except:
+ EdkLogger.warn("build", "Failed to get Stack Cookie Value List! Generating random value.", ExtraData="[%s]" % str(Info))
+ if Bitwidth == 32:
+ CookieValue = secrets.randbelow (0xFFFFFFFF)
+ else:
+ CookieValue = secrets.randbelow (0xFFFFFFFFFFFFFFFF)
+
+ AutoGenH.Append((
+ '#define STACK_COOKIE_VALUE 0x%XULL\n' % CookieValue
+ if Bitwidth == 64 else
+ '#define STACK_COOKIE_VALUE 0x%X\n' % CookieValue
+ ))
+
CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH)
CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH)
CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH)
diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
index fbd35d4..6d9c60b 100755
--- a/BaseTools/Source/Python/AutoGen/GenMake.py
+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
@@ -14,6 +14,7 @@ import sys
import string
import re
import os.path as path
+from Common import EdkLogger
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
from Common.BuildToolError import *
diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
index 3543594..fd3ee4a 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -10,7 +10,7 @@
# keep the tool as simple as possible, it has the following limitations:
# * Do not support vendor code bytes in a capsule.
#
-# Copyright (c) 2018 - 2022, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2018 - 2024, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -38,11 +38,68 @@ from Common.Edk2.Capsule.FmpPayloadHeader import FmpPayloadHeaderClass
# Globals for help information
#
__prog__ = 'GenerateCapsule'
-__version__ = '0.10'
-__copyright__ = 'Copyright (c) 2022, Intel Corporation. All rights reserved.'
+__version__ = '0.11'
+__copyright__ = 'Copyright (c) 2024, Intel Corporation. All rights reserved.'
__description__ = 'Generate a capsule.\n'
-def SignPayloadSignTool (Payload, ToolPath, PfxFile, SubjectName, Verbose = False):
+#
+# Globals definitions
+#
+HASH_ALG_MD5 = 'md5'
+HASH_ALG_SHA1 = 'sha1'
+HASH_ALG_SHA256 = 'sha256'
+HASH_ALG_SHA384 = 'sha384'
+HASH_ALG_SHA512 = 'sha512'
+DEFAULT_HASH_ALGORITHM = HASH_ALG_SHA256
+
+TOOL_SIGN_TOOL = 0x0
+TOOL_OPENSSL = 0x1
+
+SIGN_TOOL_HASH_ALG_EOL_LIST = [
+ HASH_ALG_MD5,
+ HASH_ALG_SHA1,
+ ]
+
+SIGN_TOOL_HASH_ALG_SUPPORT_LIST = [
+ HASH_ALG_SHA256,
+ HASH_ALG_SHA384,
+ HASH_ALG_SHA512,
+ ]
+
+OPENSSL_HASH_ALG_EOL_LIST = [
+ HASH_ALG_MD5,
+ HASH_ALG_SHA1,
+ ]
+
+OPENSSL_HASH_ALG_SUPPORT_LIST = [
+ HASH_ALG_SHA256,
+ HASH_ALG_SHA384,
+ HASH_ALG_SHA512,
+ ]
+
+def CheckHashAlgorithmSupported (ToolType, HashAlgorithm):
+ if ToolType == TOOL_SIGN_TOOL:
+ EolList = SIGN_TOOL_HASH_ALG_EOL_LIST
+ SupportList = SIGN_TOOL_HASH_ALG_SUPPORT_LIST
+ elif ToolType == TOOL_OPENSSL:
+ EolList = OPENSSL_HASH_ALG_EOL_LIST
+ SupportList = OPENSSL_HASH_ALG_SUPPORT_LIST
+ else:
+ raise ValueError ('GenerateCapsule: error: unsupported type of tool.')
+
+ if HashAlgorithm.lower () in EolList:
+ raise ValueError ('GenerateCapsule: error: hash algorithm [{HashAlgorithm}] had been EOL.'.format (HashAlgorithm = HashAlgorithm))
+ elif HashAlgorithm.lower () not in SupportList:
+ raise ValueError ('GenerateCapsule: error: hash algorithm [{HashAlgorithm}] is not supported.'.format (HashAlgorithm = HashAlgorithm))
+
+ return
+
+def SignPayloadSignTool (Payload, ToolPath, PfxFile, SubjectName, HashAlgorithm = DEFAULT_HASH_ALGORITHM, Verbose = False):
+ #
+ # Check the hash algorithm is supported
+ #
+ CheckHashAlgorithmSupported (TOOL_SIGN_TOOL, HashAlgorithm)
+
#
# Create a temporary directory
#
@@ -70,12 +127,12 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile, SubjectName, Verbose = Fals
ToolPath = ''
Command = ''
Command = Command + '"{Path}" '.format (Path = os.path.join (ToolPath, 'signtool.exe'))
- Command = Command + 'sign /fd sha256 /p7ce DetachedSignedData /p7co 1.2.840.113549.1.7.2 '
+ Command = Command + 'sign /fd {HashAlgorithm} /p7ce DetachedSignedData /p7co 1.2.840.113549.1.7.2 '.format (HashAlgorithm = HashAlgorithm)
Command = Command + '/p7 {TempDir} '.format (TempDir = TempDirectoryName)
if PfxFile is not None:
Command = Command + '/f {PfxFile} '.format (PfxFile = PfxFile)
if SubjectName is not None:
- Command = Command + '/n {SubjectName} '.format (SubjectName = SubjectName)
+ Command = Command + '/n "{SubjectName}" '.format (SubjectName = SubjectName)
Command = Command + TempFileName
if Verbose:
print (Command)
@@ -108,11 +165,16 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile, SubjectName, Verbose = Fals
shutil.rmtree (TempDirectoryName)
return Signature
-def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile, SubjectName, Verbose = False):
+def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile, SubjectName, HashAlgorithm = DEFAULT_HASH_ALGORITHM, Verbose = False):
print ('signtool verify is not supported.')
raise ValueError ('GenerateCapsule: error: signtool verify is not supported.')
-def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCertFile, TrustedPublicCertFile, Verbose = False):
+def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCertFile, TrustedPublicCertFile, HashAlgorithm = DEFAULT_HASH_ALGORITHM, Verbose = False):
+ #
+ # Check the hash algorithm is supported
+ #
+ CheckHashAlgorithmSupported (TOOL_OPENSSL, HashAlgorithm)
+
#
# Build openssl command
#
@@ -120,7 +182,7 @@ def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCer
ToolPath = ''
Command = ''
Command = Command + '"{Path}" '.format (Path = os.path.join (ToolPath, 'openssl'))
- Command = Command + 'smime -sign -binary -outform DER -md sha256 '
+ Command = Command + 'smime -sign -binary -outform DER -md {HashAlgorithm} '.format (HashAlgorithm = HashAlgorithm)
Command = Command + '-signer "{Private}" -certfile "{Public}"'.format (Private = SignerPrivateCertFile, Public = OtherPublicCertFile)
if Verbose:
print (Command)
@@ -141,7 +203,7 @@ def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPublicCer
return Signature
-def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, SignerPrivateCertFile, OtherPublicCertFile, TrustedPublicCertFile, Verbose = False):
+def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, SignerPrivateCertFile, OtherPublicCertFile, TrustedPublicCertFile, HashAlgorithm = DEFAULT_HASH_ALGORITHM, Verbose = False):
#
# Create a temporary directory
#
@@ -251,8 +313,9 @@ if __name__ == '__main__':
LowestSupportedVersion = ConvertJsonValue (Config, 'LowestSupportedVersion', ValidateUnsignedInteger, Required = False)
HardwareInstance = ConvertJsonValue (Config, 'HardwareInstance', ValidateUnsignedInteger, Required = False, Default = 0)
MonotonicCount = ConvertJsonValue (Config, 'MonotonicCount', ValidateUnsignedInteger, Required = False, Default = 0)
+ HashAlgorithm = ConvertJsonValue (Config, 'HashAlgorithm', str, Required = False, Default = DEFAULT_HASH_ALGORITHM)
SignToolPfxFile = ConvertJsonValue (Config, 'SignToolPfxFile', os.path.expandvars, Required = False, Default = None, Open = True)
- SignToolSubjectName = ConvertJsonValue (Config, 'SignToolSubjectName', os.path.expandvars, Required = False, Default = None, Open = True)
+ SignToolSubjectName = ConvertJsonValue (Config, 'SignToolSubjectName', str, Required = False, Default = None, Open = False)
OpenSslSignerPrivateCertFile = ConvertJsonValue (Config, 'OpenSslSignerPrivateCertFile', os.path.expandvars, Required = False, Default = None, Open = True)
OpenSslOtherPublicCertFile = ConvertJsonValue (Config, 'OpenSslOtherPublicCertFile', os.path.expandvars, Required = False, Default = None, Open = True)
OpenSslTrustedPublicCertFile = ConvertJsonValue (Config, 'OpenSslTrustedPublicCertFile', os.path.expandvars, Required = False, Default = None, Open = True)
@@ -267,6 +330,7 @@ if __name__ == '__main__':
MonotonicCount,
HardwareInstance,
UpdateImageIndex,
+ HashAlgorithm,
SignToolPfxFile,
SignToolSubjectName,
OpenSslSignerPrivateCertFile,
@@ -307,8 +371,9 @@ if __name__ == '__main__':
HardwareInstance = ConvertJsonValue (Config, 'HardwareInstance', ValidateUnsignedInteger, Required = False, Default = 0)
UpdateImageIndex = ConvertJsonValue (Config, 'UpdateImageIndex', ValidateUnsignedInteger, Required = False, Default = 1)
MonotonicCount = ConvertJsonValue (Config, 'MonotonicCount', ValidateUnsignedInteger, Required = False, Default = 0)
+ HashAlgorithm = ConvertJsonValue (Config, 'HashAlgorithm', str, Required = False, Default = DEFAULT_HASH_ALGORITHM)
SignToolPfxFile = ConvertJsonValue (Config, 'SignToolPfxFile', os.path.expandvars, Required = False, Default = None, Open = True)
- SignToolSubjectName = ConvertJsonValue (Config, 'SignToolSubjectName', os.path.expandvars, Required = False, Default = None, Open = True)
+ SignToolSubjectName = ConvertJsonValue (Config, 'SignToolSubjectName', str, Required = False, Default = None, Open = False)
OpenSslSignerPrivateCertFile = ConvertJsonValue (Config, 'OpenSslSignerPrivateCertFile', os.path.expandvars, Required = False, Default = None, Open = True)
OpenSslOtherPublicCertFile = ConvertJsonValue (Config, 'OpenSslOtherPublicCertFile', os.path.expandvars, Required = False, Default = None, Open = True)
OpenSslTrustedPublicCertFile = ConvertJsonValue (Config, 'OpenSslTrustedPublicCertFile', os.path.expandvars, Required = False, Default = None, Open = True)
@@ -334,6 +399,7 @@ if __name__ == '__main__':
MonotonicCount,
HardwareInstance,
UpdateImageIndex,
+ HashAlgorithm,
SignToolPfxFile,
SignToolSubjectName,
OpenSslSignerPrivateCertFile,
@@ -354,6 +420,7 @@ if __name__ == '__main__':
"Payload": PayloadDescriptor.Payload,
"HardwareInstance": str(PayloadDescriptor.HardwareInstance),
"UpdateImageIndex": str(PayloadDescriptor.UpdateImageIndex),
+ "HashAlgorithm": str(PayloadDescriptor.HashAlgorithm),
"SignToolPfxFile": str(PayloadDescriptor.SignToolPfxFile),
"SignToolSubjectName": str(PayloadDescriptor.SignToolSubjectName),
"OpenSslSignerPrivateCertFile": str(PayloadDescriptor.OpenSslSignerPrivateCertFile),
@@ -409,11 +476,14 @@ if __name__ == '__main__':
if args.HardwareInstance:
print ('GenerateCapsule: error: Argument --hardware-instance conflicts with Argument -j')
sys.exit (1)
+ if args.HashAlgorithm:
+ print ('GenerateCapsule: error: Argument --hash-algorithm conflicts with Argument -j')
+ sys.exit (1)
if args.SignToolPfxFile:
print ('GenerateCapsule: error: Argument --pfx-file conflicts with Argument -j')
sys.exit (1)
if args.SignToolSubjectName:
- print ('GenerateCapsule: error: Argument --SubjectName conflicts with Argument -j')
+ print ('GenerateCapsule: error: Argument --subject-name conflicts with Argument -j')
sys.exit (1)
if args.OpenSslSignerPrivateCertFile:
print ('GenerateCapsule: error: Argument --signer-private-cert conflicts with Argument -j')
@@ -437,6 +507,7 @@ if __name__ == '__main__':
MonotonicCount = 0,
HardwareInstance = 0,
UpdateImageIndex = 1,
+ HashAlgorithm = None,
SignToolPfxFile = None,
SignToolSubjectName = None,
OpenSslSignerPrivateCertFile = None,
@@ -452,6 +523,7 @@ if __name__ == '__main__':
self.MonotonicCount = MonotonicCount
self.HardwareInstance = HardwareInstance
self.UpdateImageIndex = UpdateImageIndex
+ self.HashAlgorithm = HashAlgorithm
self.SignToolPfxFile = SignToolPfxFile
self.SignToolSubjectName = SignToolSubjectName
self.OpenSslSignerPrivateCertFile = OpenSslSignerPrivateCertFile
@@ -513,11 +585,18 @@ if __name__ == '__main__':
raise argparse.ArgumentTypeError ('JSON field MonotonicCount must be an integer in range 0x0..0xffffffffffffffff')
else:
raise argparse.ArgumentTypeError ('--monotonic-count must be an integer in range 0x0..0xffffffffffffffff')
- if self.UpdateImageIndex >0xFF:
+ if self.UpdateImageIndex < 0x1 or self.UpdateImageIndex > 0xFF:
if args.JsonFile:
- raise argparse.ArgumentTypeError ('JSON field UpdateImageIndex must be an integer in range 0x0..0xff')
+ raise argparse.ArgumentTypeError ('JSON field UpdateImageIndex must be an integer in range 0x1..0xff')
else:
- raise argparse.ArgumentTypeError ('--update-image-index must be an integer in range 0x0..0xff')
+ raise argparse.ArgumentTypeError ('--update-image-index must be an integer in range 0x1..0xff')
+
+ if args.Decode:
+ if args.OutputFile is None:
+ raise argparse.ArgumentTypeError ('--decode requires --output')
+
+ if self.HashAlgorithm is None:
+ self.HashAlgorithm = DEFAULT_HASH_ALGORITHM
if self.UseSignTool:
if self.SignToolPfxFile is not None:
@@ -564,6 +643,7 @@ if __name__ == '__main__':
args.MonotonicCount,
args.HardwareInstance,
args.UpdateImageIndex,
+ args.HashAlgorithm,
args.SignToolPfxFile,
args.SignToolSubjectName,
args.OpenSslSignerPrivateCertFile,
@@ -576,7 +656,7 @@ if __name__ == '__main__':
try:
SinglePayloadDescriptor.Validate (args)
except Exception as Msg:
- print ('GenerateCapsule: error:' + str(Msg))
+ print ('GenerateCapsule: error: ' + str(Msg))
sys.exit (1)
for SinglePayloadDescriptor in PayloadDescriptorList:
ImageCapsuleSupport = 0x0000000000000000
@@ -609,6 +689,7 @@ if __name__ == '__main__':
SinglePayloadDescriptor.SigningToolPath,
SinglePayloadDescriptor.SignToolPfxFile,
SinglePayloadDescriptor.SignToolSubjectName,
+ HashAlgorithm = SinglePayloadDescriptor.HashAlgorithm,
Verbose = args.Verbose
)
else:
@@ -618,6 +699,7 @@ if __name__ == '__main__':
SinglePayloadDescriptor.OpenSslSignerPrivateCertFile,
SinglePayloadDescriptor.OpenSslOtherPublicCertFile,
SinglePayloadDescriptor.OpenSslTrustedPublicCertFile,
+ HashAlgorithm = SinglePayloadDescriptor.HashAlgorithm,
Verbose = args.Verbose
)
except Exception as Msg:
@@ -689,8 +771,9 @@ if __name__ == '__main__':
args.MonotonicCount,
args.HardwareInstance,
args.UpdateImageIndex,
+ args.HashAlgorithm,
args.SignToolPfxFile,
- args.SignSubjectName,
+ args.SignToolSubjectName,
args.OpenSslSignerPrivateCertFile,
args.OpenSslOtherPublicCertFile,
args.OpenSslTrustedPublicCertFile,
@@ -704,7 +787,7 @@ if __name__ == '__main__':
try:
SinglePayloadDescriptor.Validate (args)
except Exception as Msg:
- print ('GenerateCapsule: error:' + str(Msg))
+ print ('GenerateCapsule: error: ' + str(Msg))
sys.exit (1)
try:
Result = UefiCapsuleHeader.Decode (Buffer)
@@ -734,6 +817,7 @@ if __name__ == '__main__':
None,
HardwareInstance,
UpdateImageIndex,
+ PayloadDescriptorList[Index].HashAlgorithm,
PayloadDescriptorList[Index].SignToolPfxFile,
PayloadDescriptorList[Index].SignToolSubjectName,
PayloadDescriptorList[Index].OpenSslSignerPrivateCertFile,
@@ -747,7 +831,10 @@ if __name__ == '__main__':
for Index in range (0, FmpCapsuleHeader.PayloadItemCount):
if Index > 0:
PayloadDecodeFile = FmpCapsuleHeader.GetFmpCapsuleImageHeader (Index).Payload
- PayloadDescriptorList.append (PayloadDescriptor (PayloadDecodeFile,
+ PayloadDescriptorList.append (PayloadDescriptor (
+ PayloadDecodeFile,
+ None,
+ None,
None,
None,
None,
@@ -773,6 +860,7 @@ if __name__ == '__main__':
None,
HardwareInstance,
UpdateImageIndex,
+ PayloadDescriptorList[Index].HashAlgorithm,
PayloadDescriptorList[Index].SignToolPfxFile,
PayloadDescriptorList[Index].SignToolSubjectName,
PayloadDescriptorList[Index].OpenSslSignerPrivateCertFile,
@@ -808,6 +896,7 @@ if __name__ == '__main__':
SinglePayloadDescriptor.SigningToolPath,
SinglePayloadDescriptor.SignToolPfxFile,
SinglePayloadDescriptor.SignToolSubjectName,
+ HashAlgorithm = SinglePayloadDescriptor.HashAlgorithm,
Verbose = args.Verbose
)
else:
@@ -818,6 +907,7 @@ if __name__ == '__main__':
SinglePayloadDescriptor.OpenSslSignerPrivateCertFile,
SinglePayloadDescriptor.OpenSslOtherPublicCertFile,
SinglePayloadDescriptor.OpenSslTrustedPublicCertFile,
+ HashAlgorithm = SinglePayloadDescriptor.HashAlgorithm,
Verbose = args.Verbose
)
except Exception as Msg:
@@ -827,7 +917,7 @@ if __name__ == '__main__':
print ('--------')
print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION')
- PayloadSignature = struct.unpack ('<I', SinglePayloadDescriptor.Payload[0:4])
+ (PayloadSignature,) = struct.unpack ('<I', SinglePayloadDescriptor.Payload[0:4])
if PayloadSignature != FmpPayloadHeader.Signature:
SinglePayloadDescriptor.UseDependency = True
try:
@@ -873,8 +963,8 @@ if __name__ == '__main__':
print ('GenerateCapsule: error: can not write embedded driver file {File}'.format (File = EmbeddedDriverPath))
sys.exit (1)
- except:
- print ('GenerateCapsule: error: can not decode capsule')
+ except Exception as Msg:
+ print ('GenerateCapsule: error: can not decode capsule: ' + str(Msg))
sys.exit (1)
GenerateOutputJson(PayloadJsonDescriptorList)
PayloadIndex = 0
@@ -914,7 +1004,7 @@ if __name__ == '__main__':
print ('--------')
print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION')
- PayloadSignature = struct.unpack ('<I', Result[0:4])
+ (PayloadSignature,) = struct.unpack ('<I', Result[0:4])
if PayloadSignature != FmpPayloadHeader.Signature:
try:
Result = CapsuleDependency.Decode (Result)
@@ -989,6 +1079,9 @@ if __name__ == '__main__':
parser.add_argument ("--lsv", dest = 'LowestSupportedVersion', type = ValidateUnsignedInteger,
help = "The 32-bit lowest supported version of the binary payload (e.g. 0x11223344 or 5678). Required for encode operations.")
+ parser.add_argument ("--hash-algorithm", dest = 'HashAlgorithm', type = str,
+ help = "Hash algorithm for the payload digest.")
+
parser.add_argument ("--pfx-file", dest='SignToolPfxFile', type=argparse.FileType('rb'),
help="signtool PFX certificate filename.")
parser.add_argument ("--subject-name", dest='SignToolSubjectName',
diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py
index 11849e8..dd5316d 100755
--- a/BaseTools/Source/Python/Common/GlobalData.py
+++ b/BaseTools/Source/Python/Common/GlobalData.py
@@ -122,4 +122,5 @@ gEnableGenfdsMultiThread = True
gSikpAutoGenCache = set()
# Common lock for the file access in multiple process AutoGens
file_lock = None
-
+gStackCookieValues32 = []
+gStackCookieValues64 = []
diff --git a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py
index 8abb449..6a112d5 100644
--- a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py
+++ b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py
@@ -92,7 +92,7 @@ class FmpCapsuleImageHeaderClass (object):
def Decode (self, Buffer):
if len (Buffer) < self._StructSize:
- raise ValueError
+ raise ValueError ('Buffer is too small for decoding')
(Version, UpdateImageTypeId, UpdateImageIndex, r0, r1, r2, UpdateImageSize, UpdateVendorCodeSize, UpdateHardwareInstance, ImageCapsuleSupport) = \
struct.unpack (
self._StructFormat,
@@ -100,11 +100,11 @@ class FmpCapsuleImageHeaderClass (object):
)
if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION:
- raise ValueError
+ raise ValueError ('Incorrect capsule image header version')
if UpdateImageIndex < 1:
- raise ValueError
+ raise ValueError ('Update image index is less than 1')
if UpdateImageSize + UpdateVendorCodeSize != len (Buffer[self._StructSize:]):
- raise ValueError
+ raise ValueError ('Non-vendor and vendor parts do not add up')
self.Version = Version
self.UpdateImageTypeId = uuid.UUID (bytes_le = UpdateImageTypeId)
@@ -120,7 +120,7 @@ class FmpCapsuleImageHeaderClass (object):
def DumpInfo (self):
if not self._Valid:
- raise ValueError
+ raise ValueError ('Can not dump an invalid header')
print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version = {Version:08X}'.format (Version = self.Version))
print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId = {UpdateImageTypeId}'.format (UpdateImageTypeId = str(self.UpdateImageTypeId).upper()))
print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex = {UpdateImageIndex:08X}'.format (UpdateImageIndex = self.UpdateImageIndex))
@@ -180,7 +180,7 @@ class FmpCapsuleHeaderClass (object):
def GetEmbeddedDriver (self, Index):
if Index > len (self._EmbeddedDriverList):
- raise ValueError
+ raise ValueError ('Invalid embedded driver index')
return self._EmbeddedDriverList[Index]
def AddPayload (self, UpdateImageTypeId, Payload = b'', VendorCodeBytes = b'', HardwareInstance = 0, UpdateImageIndex = 1, CapsuleSupport = 0):
@@ -188,7 +188,7 @@ class FmpCapsuleHeaderClass (object):
def GetFmpCapsuleImageHeader (self, Index):
if Index >= len (self._FmpCapsuleImageHeaderList):
- raise ValueError
+ raise ValueError ('Invalid capsule image index')
return self._FmpCapsuleImageHeaderList[Index]
def Encode (self):
@@ -234,14 +234,14 @@ class FmpCapsuleHeaderClass (object):
def Decode (self, Buffer):
if len (Buffer) < self._StructSize:
- raise ValueError
+ raise ValueError ('Buffer is too small for decoding')
(Version, EmbeddedDriverCount, PayloadItemCount) = \
struct.unpack (
self._StructFormat,
Buffer[0:self._StructSize]
)
if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION:
- raise ValueError
+ raise ValueError ('Incorrect capsule header version')
self.Version = Version
self.EmbeddedDriverCount = EmbeddedDriverCount
@@ -258,7 +258,7 @@ class FmpCapsuleHeaderClass (object):
for Index in range (0, EmbeddedDriverCount + PayloadItemCount):
ItemOffset = struct.unpack (self._ItemOffsetFormat, Buffer[Offset:Offset + self._ItemOffsetSize])[0]
if ItemOffset >= len (Buffer):
- raise ValueError
+ raise ValueError ('Item offset is outside of buffer')
self._ItemOffsetList.append (ItemOffset)
Offset = Offset + self._ItemOffsetSize
Result = Buffer[Offset:]
@@ -297,7 +297,7 @@ class FmpCapsuleHeaderClass (object):
def DumpInfo (self):
if not self._Valid:
- raise ValueError
+ raise ValueError ('Can not dump an invalid header')
print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = {Version:08X}'.format (Version = self.Version))
print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount = {EmbeddedDriverCount:08X}'.format (EmbeddedDriverCount = self.EmbeddedDriverCount))
for EmbeddedDriver in self._EmbeddedDriverList:
diff --git a/BaseTools/Source/Python/Ecc/Check.py b/BaseTools/Source/Python/Ecc/Check.py
index 33060db..160e803 100644
--- a/BaseTools/Source/Python/Ecc/Check.py
+++ b/BaseTools/Source/Python/Ecc/Check.py
@@ -181,7 +181,6 @@ class Check(object):
# General Checking
def GeneralCheck(self):
- self.GeneralCheckNonAcsii()
self.UniCheck()
self.GeneralCheckNoTab()
self.GeneralCheckLineEnding()
@@ -238,25 +237,6 @@ class Check(object):
OtherMsg = "File %s has trailing white spaces at line %s" % (Record[1], IndexOfLine)
EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_TRAILING_WHITE_SPACE_LINE, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])
- # Check whether file has non ACSII char
- def GeneralCheckNonAcsii(self):
- if EccGlobalData.gConfig.GeneralCheckNonAcsii == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
- EdkLogger.quiet("Checking Non-ACSII char in file ...")
- SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
- RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
- for Record in RecordSet:
- if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList:
- op = open(Record[1]).readlines()
- IndexOfLine = 0
- for Line in op:
- IndexOfLine += 1
- IndexOfChar = 0
- for Char in Line:
- IndexOfChar += 1
- if ord(Char) > 126:
- OtherMsg = "File %s has Non-ASCII char at line %s column %s" % (Record[1], IndexOfLine, IndexOfChar)
- EccGlobalData.gDb.TblReport.Insert(ERROR_GENERAL_CHECK_NON_ACSII, OtherMsg=OtherMsg, BelongsToTable='File', BelongsToItem=Record[0])
-
# C Function Layout Checking
def FunctionLayoutCheck(self):
self.FunctionLayoutCheckReturnType()
@@ -1112,7 +1092,7 @@ class Check(object):
RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand)
for Record in RecordSet:
Path = Record[1]
- Path = Path.upper().replace('\X64', '').replace('\IA32', '').replace('\EBC', '').replace('\IPF', '').replace('\ARM', '')
+ Path = Path.upper().replace(r'\X64', '').replace(r'\IA32', '').replace(r'\EBC', '').replace(r'\IPF', '').replace(r'\ARM', '')
if Path in InfPathList:
if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, Record[2]):
EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_MODULE_FILE_NO_USE, OtherMsg="The source file [%s] is existing in module directory but it is not described in INF file." % (Record[2]), BelongsToTable='File', BelongsToItem=Record[0])
diff --git a/BaseTools/Source/Python/Ecc/Configuration.py b/BaseTools/Source/Python/Ecc/Configuration.py
index 9d9feac..9a9ca49 100644
--- a/BaseTools/Source/Python/Ecc/Configuration.py
+++ b/BaseTools/Source/Python/Ecc/Configuration.py
@@ -59,7 +59,6 @@ _ConfigFileToInternalTranslation = {
"GeneralCheckNoProgma":"GeneralCheckNoProgma",
"GeneralCheckNoTab":"GeneralCheckNoTab",
"GeneralCheckNo_Asm":"GeneralCheckNo_Asm",
- "GeneralCheckNonAcsii":"GeneralCheckNonAcsii",
"GeneralCheckTabWidth":"GeneralCheckTabWidth",
"GeneralCheckTrailingWhiteSpaceLine":"GeneralCheckTrailingWhiteSpaceLine",
"GeneralCheckUni":"GeneralCheckUni",
@@ -179,8 +178,6 @@ class Configuration(object):
self.GeneralCheckCarriageReturn = 1
# Check whether the file exists
self.GeneralCheckFileExistence = 1
- # Check whether file has non ACSII char
- self.GeneralCheckNonAcsii = 1
# Check whether UNI file is valid
self.GeneralCheckUni = 1
# Check Only use CRLF (Carriage Return Line Feed) line endings.
@@ -435,7 +432,7 @@ class Configuration(object):
# test that our dict and out class still match in contents.
#
if __name__ == '__main__':
- myconfig = Configuration("BaseTools\Source\Python\Ecc\config.ini")
+ myconfig = Configuration(r"BaseTools\Source\Python\Ecc\config.ini")
for each in myconfig.__dict__:
if each == "Filename":
continue
diff --git a/BaseTools/Source/Python/Ecc/EccToolError.py b/BaseTools/Source/Python/Ecc/EccToolError.py
index 2ff36c8..734a2b8 100644
--- a/BaseTools/Source/Python/Ecc/EccToolError.py
+++ b/BaseTools/Source/Python/Ecc/EccToolError.py
@@ -14,7 +14,6 @@ ERROR_GENERAL_CHECK_NO_ASM = 1004
ERROR_GENERAL_CHECK_NO_PROGMA = 1005
ERROR_GENERAL_CHECK_CARRIAGE_RETURN = 1006
ERROR_GENERAL_CHECK_FILE_EXISTENCE = 1007
-ERROR_GENERAL_CHECK_NON_ACSII = 1008
ERROR_GENERAL_CHECK_UNI = 1009
ERROR_GENERAL_CHECK_UNI_HELP_INFO = 1010
ERROR_GENERAL_CHECK_INVALID_LINE_ENDING = 1011
@@ -113,7 +112,6 @@ gEccErrorMessage = {
ERROR_GENERAL_CHECK_NO_PROGMA : """There should be no use of "#progma" in source file except "#pragma pack(#)\"""",
ERROR_GENERAL_CHECK_CARRIAGE_RETURN : "There should be a carriage return at the end of the file",
ERROR_GENERAL_CHECK_FILE_EXISTENCE : "File not found",
- ERROR_GENERAL_CHECK_NON_ACSII : "File has invalid Non-ACSII char",
ERROR_GENERAL_CHECK_UNI : "File is not a valid UTF-16 UNI file",
ERROR_GENERAL_CHECK_UNI_HELP_INFO : "UNI file that is associated by INF or DEC file need define the prompt and help information.",
ERROR_GENERAL_CHECK_INVALID_LINE_ENDING : "Only CRLF (Carriage Return Line Feed) is allowed to line ending.",
diff --git a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py
index 2d98ac5..2ef2847 100644
--- a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py
@@ -1841,14 +1841,14 @@ class DecParser(MetaFileParser):
if EccGlobalData.gConfig.UniCheckPCDInfo == '1' or EccGlobalData.gConfig.UniCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
# check Description, Prompt information
- PatternDesc = re.compile('##\s*([\x21-\x7E\s]*)', re.S)
- PatternPrompt = re.compile('#\s+@Prompt\s+([\x21-\x7E\s]*)', re.S)
+ PatternDesc = re.compile(r'##\s*([\x21-\x7E\s]*)', re.S)
+ PatternPrompt = re.compile(r'#\s+@Prompt\s+([\x21-\x7E\s]*)', re.S)
Description = None
Prompt = None
# check @ValidRange, @ValidList and @Expression format valid
ErrorCodeValid = '0x0 <= %s <= 0xFFFFFFFF'
- PatternValidRangeIn = '(NOT)?\s*(\d+\s*-\s*\d+|0[xX][a-fA-F0-9]+\s*-\s*0[xX][a-fA-F0-9]+|LT\s*\d+|LT\s*0[xX][a-fA-F0-9]+|GT\s*\d+|GT\s*0[xX][a-fA-F0-9]+|LE\s*\d+|LE\s*0[xX][a-fA-F0-9]+|GE\s*\d+|GE\s*0[xX][a-fA-F0-9]+|XOR\s*\d+|XOR\s*0[xX][a-fA-F0-9]+|EQ\s*\d+|EQ\s*0[xX][a-fA-F0-9]+)'
- PatternValidRng = re.compile('^' + '(NOT)?\s*' + PatternValidRangeIn + '$')
+ PatternValidRangeIn = r'(NOT)?\s*(\d+\s*-\s*\d+|0[xX][a-fA-F0-9]+\s*-\s*0[xX][a-fA-F0-9]+|LT\s*\d+|LT\s*0[xX][a-fA-F0-9]+|GT\s*\d+|GT\s*0[xX][a-fA-F0-9]+|LE\s*\d+|LE\s*0[xX][a-fA-F0-9]+|GE\s*\d+|GE\s*0[xX][a-fA-F0-9]+|XOR\s*\d+|XOR\s*0[xX][a-fA-F0-9]+|EQ\s*\d+|EQ\s*0[xX][a-fA-F0-9]+)'
+ PatternValidRng = re.compile('^' + r'(NOT)?\s*' + PatternValidRangeIn + '$')
for Comment in self._Comments:
Comm = Comment[0].strip()
if not Comm:
@@ -2071,7 +2071,7 @@ class UniParser(object):
def CheckKeyValid(self, Key, Contents=None):
if not Contents:
Contents = self.FileIn
- KeyPattern = re.compile('#string\s+%s\s+.*?#language.*?".*?"' % Key, re.S)
+ KeyPattern = re.compile(r'#string\s+%s\s+.*?#language.*?".*?"' % Key, re.S)
if KeyPattern.search(Contents):
return True
return False
diff --git a/BaseTools/Source/Python/Ecc/c.py b/BaseTools/Source/Python/Ecc/c.py
index 61ad084..0ebdc1a 100644
--- a/BaseTools/Source/Python/Ecc/c.py
+++ b/BaseTools/Source/Python/Ecc/c.py
@@ -43,7 +43,7 @@ def GetArrayPattern():
return p
def GetTypedefFuncPointerPattern():
- p = re.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL)
+ p = re.compile(r'[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL)
return p
def GetDB():
diff --git a/BaseTools/Source/Python/Ecc/config.ini b/BaseTools/Source/Python/Ecc/config.ini
index 5529d0f..ba4346e 100644
--- a/BaseTools/Source/Python/Ecc/config.ini
+++ b/BaseTools/Source/Python/Ecc/config.ini
@@ -35,7 +35,7 @@ AutoCorrect = 1
#
# List customized Modifer here, split with ','
#
-ModifierList = IN, OUT, OPTIONAL, UNALIGNED, EFI_RUNTIMESERVICE, EFI_BOOTSERVICE, EFIAPI, TPMINTERNALAPI, STATIC
+ModifierList = IN, OUT, OPTIONAL, UNALIGNED, EFI_RUNTIMESERVICE, EFI_BOOTSERVICE, EFIAPI, TPMINTERNALAPI, STATIC, static
#
# General Checking
@@ -62,8 +62,6 @@ GeneralCheckNoProgma = 1
GeneralCheckCarriageReturn = 1
# Check whether the file exists
GeneralCheckFileExistence = 1
-# Check whether file has non ACSII char
-GeneralCheckNonAcsii = 1
# Check whether UNI file is valid
GeneralCheckUni = 1
# Check Only use CRLF (Carriage Return Line Feed) line endings.
diff --git a/BaseTools/Source/Python/Eot/EotGlobalData.py b/BaseTools/Source/Python/Eot/EotGlobalData.py
index 3218f86..887a7a2 100644
--- a/BaseTools/Source/Python/Eot/EotGlobalData.py
+++ b/BaseTools/Source/Python/Eot/EotGlobalData.py
@@ -11,7 +11,7 @@ from Common.LongFilePathSupport import OpenLongFilePath as open
gEFI_SOURCE = ''
gEDK_SOURCE = ''
gWORKSPACE = ''
-gSHELL_INF = 'Application\Shell'
+gSHELL_INF = r'Application\Shell'
gMAKE_FILE = ''
gDSC_FILE = ''
gFV_FILE = []
diff --git a/BaseTools/Source/Python/Eot/c.py b/BaseTools/Source/Python/Eot/c.py
index dd9530f..a85564d 100644
--- a/BaseTools/Source/Python/Eot/c.py
+++ b/BaseTools/Source/Python/Eot/c.py
@@ -54,7 +54,7 @@ def GetArrayPattern():
# @return p: the pattern of function pointer
#
def GetTypedefFuncPointerPattern():
- p = re.compile('[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL)
+ p = re.compile(r'[_\w\s]*\([\w\s]*\*+\s*[_\w]+\s*\)\s*\(.*\)', re.DOTALL)
return p
## GetDB() method
diff --git a/BaseTools/Source/Python/README.md b/BaseTools/Source/Python/README.md
deleted file mode 100644
index 8c4d9e7..0000000
--- a/BaseTools/Source/Python/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Edk2 Basetools
-
-This folder has traditionally held the source of Python based tools used by EDK2.
-The official repo this source has moved to https://github.com/tianocore/edk2-basetools.
-This folder will remain in the tree until the next stable release (expected 202102).
-There is a new folder under Basetools `BinPipWrappers` that uses the pip module rather than this tree for Basetools.
-By adding the scope `pipbuild-win` or `pipbuild-unix` (depending on your host system), the SDE will use the
-`BinPipWrappers` instead of the regular `BinWrappers`.
-
-## Why Move It?
-
-The discussion is on the mailing list. The RFC is here: https://edk2.groups.io/g/rfc/topic/74009714#270
-The benefits allow for the Basetools project to be used separately from EDK2 itself as well as offering it in a
-globally accessible manner.
-This makes it much easier to build a module using Basetools.
-Separating the Basetools into their own repo allows for easier CI and contribution process.
-Additional pros, cons, and process can be found on the mailing list.
-
-## How Do I Install It?
-
-By default, EDK2 is tied to and tested with a specific version of the Basetools through `pip-requirements.txt`.
-You can simply run:
-
-```bash
-pip install -r pip-requirements.txt
-```
-
-This will install the required module, thought we strongly suggest setting up a virtual environment.
-Additionally, you can also install a local clone of the Basetools as well as a specific git commit.
diff --git a/BaseTools/Source/Python/Trim/Trim.py b/BaseTools/Source/Python/Trim/Trim.py
index 6d7bc05..ea9d1a0 100644
--- a/BaseTools/Source/Python/Trim/Trim.py
+++ b/BaseTools/Source/Python/Trim/Trim.py
@@ -248,6 +248,23 @@ def TrimPreprocessedVfr(Source, Target):
except:
EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target)
+# Create a banner to indicate the start and
+# end of the included ASL file. Banner looks like:-
+#
+# /*************************************
+# * @param *
+# *************************************/
+#
+# @param Pathname File pathname to be included in the banner
+#
+def AddIncludeHeader(Pathname):
+ StartLine = "/*" + '*' * (len(Pathname) + 4)
+ EndLine = '*' * (len(Pathname) + 4) + "*/"
+ Banner = '\n' + StartLine
+ Banner += '\n' + ('{0} {1} {0}'.format('*', Pathname))
+ Banner += '\n' + EndLine + '\n'
+ return Banner
+
## Read the content ASL file, including ASL included, recursively
#
# @param Source File to be read
@@ -276,16 +293,18 @@ def DoInclude(Source, Indent='', IncludePathList=[], LocalSearchPath=None, Inclu
try:
with open(IncludeFile, "r") as File:
F = File.readlines()
- except:
+ except Exception:
with codecs.open(IncludeFile, "r", encoding='utf-8') as File:
F = File.readlines()
break
else:
- EdkLogger.error("Trim", "Failed to find include file %s" % Source)
+ EdkLogger.error("Trim", FILE_NOT_FOUND, ExtraData="Failed to find include file %s" % Source)
return []
- except:
- EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source)
- return []
+ except Exception as e:
+ if str(e) == str(FILE_NOT_FOUND):
+ raise
+ else:
+ EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source)
# avoid A "include" B and B "include" A
@@ -312,7 +331,9 @@ def DoInclude(Source, Indent='', IncludePathList=[], LocalSearchPath=None, Inclu
LocalSearchPath = os.path.dirname(IncludeFile)
CurrentIndent = Indent + Result[0][0]
IncludedFile = Result[0][1]
+ NewFileContent.append(AddIncludeHeader(IncludedFile+" --START"))
NewFileContent.extend(DoInclude(IncludedFile, CurrentIndent, IncludePathList, LocalSearchPath,IncludeFileList,filetype))
+ NewFileContent.append(AddIncludeHeader(IncludedFile+" --END"))
NewFileContent.append("\n")
elif filetype == "ASM":
Result = gIncludePattern.findall(Line)
@@ -324,7 +345,9 @@ def DoInclude(Source, Indent='', IncludePathList=[], LocalSearchPath=None, Inclu
IncludedFile = IncludedFile.strip()
IncludedFile = os.path.normpath(IncludedFile)
+ NewFileContent.append(AddIncludeHeader(IncludedFile+" --START"))
NewFileContent.extend(DoInclude(IncludedFile, '', IncludePathList, LocalSearchPath,IncludeFileList,filetype))
+ NewFileContent.append(AddIncludeHeader(IncludedFile+" --END"))
NewFileContent.append("\n")
gIncludedAslFile.pop()
diff --git a/BaseTools/Source/Python/UPT/Library/CommentParsing.py b/BaseTools/Source/Python/UPT/Library/CommentParsing.py
index 7ba9830..7b1ce05 100644
--- a/BaseTools/Source/Python/UPT/Library/CommentParsing.py
+++ b/BaseTools/Source/Python/UPT/Library/CommentParsing.py
@@ -238,7 +238,7 @@ def ParseDecPcdGenericComment (GenericComment, ContainerFile, TokenSpaceGuidCNam
#
# To replace Macro
#
- MACRO_PATTERN = '[\t\s]*\$\([A-Z][_A-Z0-9]*\)'
+ MACRO_PATTERN = r'[\t\s]*\$\([A-Z][_A-Z0-9]*\)'
MatchedStrs = re.findall(MACRO_PATTERN, Comment)
for MatchedStr in MatchedStrs:
if MatchedStr:
diff --git a/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py b/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
index 7718ca1..2c0750e 100644
--- a/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
+++ b/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
@@ -66,13 +66,13 @@ class _ExprError(Exception):
## _ExprBase
#
class _ExprBase:
- HEX_PATTERN = '[\t\s]*0[xX][a-fA-F0-9]+'
- INT_PATTERN = '[\t\s]*[0-9]+'
- MACRO_PATTERN = '[\t\s]*\$\(([A-Z][_A-Z0-9]*)\)'
+ HEX_PATTERN = r'[\t\s]*0[xX][a-fA-F0-9]+'
+ INT_PATTERN = r'[\t\s]*[0-9]+'
+ MACRO_PATTERN = r'[\t\s]*\$\(([A-Z][_A-Z0-9]*)\)'
PCD_PATTERN = \
- '[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*[\t\s]*\.[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*'
- QUOTED_PATTERN = '[\t\s]*L?"[^"]*"'
- BOOL_PATTERN = '[\t\s]*(true|True|TRUE|false|False|FALSE)'
+ r'[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*[\t\s]*\.[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*'
+ QUOTED_PATTERN = r'[\t\s]*L?"[^"]*"'
+ BOOL_PATTERN = r'[\t\s]*(true|True|TRUE|false|False|FALSE)'
def __init__(self, Token):
self.Token = Token
self.Index = 0
@@ -303,9 +303,9 @@ class _LogicalExpressionParser(_ExprBase):
## _ValidRangeExpressionParser
#
class _ValidRangeExpressionParser(_ExprBase):
- INT_RANGE_PATTERN = '[\t\s]*[0-9]+[\t\s]*-[\t\s]*[0-9]+'
+ INT_RANGE_PATTERN = r'[\t\s]*[0-9]+[\t\s]*-[\t\s]*[0-9]+'
HEX_RANGE_PATTERN = \
- '[\t\s]*0[xX][a-fA-F0-9]+[\t\s]*-[\t\s]*0[xX][a-fA-F0-9]+'
+ r'[\t\s]*0[xX][a-fA-F0-9]+[\t\s]*-[\t\s]*0[xX][a-fA-F0-9]+'
def __init__(self, Token):
_ExprBase.__init__(self, Token)
self.Parens = 0
@@ -407,7 +407,7 @@ class _ValidRangeExpressionParser(_ExprBase):
## _ValidListExpressionParser
#
class _ValidListExpressionParser(_ExprBase):
- VALID_LIST_PATTERN = '(0[xX][0-9a-fA-F]+|[0-9]+)([\t\s]*,[\t\s]*(0[xX][0-9a-fA-F]+|[0-9]+))*'
+ VALID_LIST_PATTERN = r'(0[xX][0-9a-fA-F]+|[0-9]+)([\t\s]*,[\t\s]*(0[xX][0-9a-fA-F]+|[0-9]+))*'
def __init__(self, Token):
_ExprBase.__init__(self, Token)
self.NUM = 1
diff --git a/BaseTools/Source/Python/UPT/Library/Misc.py b/BaseTools/Source/Python/UPT/Library/Misc.py
index 77ba358..f3688de 100644
--- a/BaseTools/Source/Python/UPT/Library/Misc.py
+++ b/BaseTools/Source/Python/UPT/Library/Misc.py
@@ -69,11 +69,11 @@ def GuidStringToGuidStructureString(Guid):
def CheckGuidRegFormat(GuidValue):
## Regular expression used to find out register format of GUID
#
- RegFormatGuidPattern = re.compile("^\s*([0-9a-fA-F]){8}-"
+ RegFormatGuidPattern = re.compile(r"^\s*([0-9a-fA-F]){8}-"
"([0-9a-fA-F]){4}-"
"([0-9a-fA-F]){4}-"
"([0-9a-fA-F]){4}-"
- "([0-9a-fA-F]){12}\s*$")
+ r"([0-9a-fA-F]){12}\s*$")
if RegFormatGuidPattern.match(GuidValue):
return True
@@ -837,8 +837,8 @@ def GetLibInstanceInfo(String, WorkSpace, LineNo):
ST.ERR_FILE_OPEN_FAILURE,
File=FullFileName)
- ReFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$")
- ReVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$")
+ ReFileGuidPattern = re.compile(r"^\s*FILE_GUID\s*=.*$")
+ ReVerStringPattern = re.compile(r"^\s*VERSION_STRING\s*=.*$")
FileLinesList = ProcessLineExtender(FileLinesList)
@@ -978,7 +978,7 @@ def ValidateUNIFilePath(Path):
#
# Check if the file name is valid according to the DEC and INF specification
#
- Pattern = '[a-zA-Z0-9_][a-zA-Z0-9_\-\.]*'
+ Pattern = r'[a-zA-Z0-9_][a-zA-Z0-9_\-\.]*'
FileName = Path.replace(Suffix, '')
InvalidCh = re.sub(Pattern, '', FileName)
if InvalidCh:
diff --git a/BaseTools/Source/Python/UPT/Library/StringUtils.py b/BaseTools/Source/Python/UPT/Library/StringUtils.py
index fbc5177..a6f47d0 100644
--- a/BaseTools/Source/Python/UPT/Library/StringUtils.py
+++ b/BaseTools/Source/Python/UPT/Library/StringUtils.py
@@ -23,7 +23,7 @@ from Logger import StringTable as ST
#
# Regular expression for matching macro used in DSC/DEC/INF file inclusion
#
-gMACRO_PATTERN = re.compile("\$\(([_A-Z][_A-Z0-9]*)\)", re.UNICODE)
+gMACRO_PATTERN = re.compile(r"\$\(([_A-Z][_A-Z0-9]*)\)", re.UNICODE)
## GetSplitValueList
#
diff --git a/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py b/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py
index 2799046..92dbcaa 100644
--- a/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py
+++ b/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py
@@ -25,7 +25,7 @@ from Library.ExpressionValidate import IsValidStringTest
from Library.Misc import CheckGuidRegFormat
TOOL_NAME = 'DecParser'
-VERSION_PATTERN = '[0-9]+(\.[0-9]+)?'
+VERSION_PATTERN = r'[0-9]+(\.[0-9]+)?'
CVAR_PATTERN = '[_a-zA-Z][a-zA-Z0-9_]*'
PCD_TOKEN_PATTERN = '(0[xX]0*[a-fA-F0-9]{1,8})|([0-9]+)'
MACRO_PATTERN = '[A-Z][_A-Z0-9]*'
diff --git a/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py b/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py
index 992b609..fb64619 100644
--- a/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py
+++ b/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py
@@ -53,12 +53,12 @@ def GetLibInstanceInfo(String, WorkSpace, LineNo, CurrentInfFileName):
#
# To deal with library instance specified by GUID and version
#
- RegFormatGuidPattern = re.compile("\s*([0-9a-fA-F]){8}-"
+ RegFormatGuidPattern = re.compile(r"\s*([0-9a-fA-F]){8}-"
"([0-9a-fA-F]){4}-"
"([0-9a-fA-F]){4}-"
"([0-9a-fA-F]){4}-"
- "([0-9a-fA-F]){12}\s*")
- VersionPattern = re.compile('[\t\s]*\d+(\.\d+)?[\t\s]*')
+ r"([0-9a-fA-F]){12}\s*")
+ VersionPattern = re.compile(r'[\t\s]*\d+(\.\d+)?[\t\s]*')
GuidMatchedObj = RegFormatGuidPattern.search(String)
if String.upper().startswith('GUID') and GuidMatchedObj and 'Version' in String:
@@ -75,8 +75,8 @@ def GetLibInstanceInfo(String, WorkSpace, LineNo, CurrentInfFileName):
FileLinesList = GetFileLineContent(String, WorkSpace, LineNo, OriginalString)
- ReFindFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$")
- ReFindVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$")
+ ReFindFileGuidPattern = re.compile(r"^\s*FILE_GUID\s*=.*$")
+ ReFindVerStringPattern = re.compile(r"^\s*VERSION_STRING\s*=.*$")
for Line in FileLinesList:
if ReFindFileGuidPattern.match(Line):
@@ -106,8 +106,8 @@ def GetPackageListInfo(FileNameString, WorkSpace, LineNo):
FileLinesList = GetFileLineContent(FileNameString, WorkSpace, LineNo, '')
- RePackageHeader = re.compile('^\s*\[Packages.*\].*$')
- ReDefineHeader = re.compile('^\s*\[Defines].*$')
+ RePackageHeader = re.compile(r'^\s*\[Packages.*\].*$')
+ ReDefineHeader = re.compile(r'^\s*\[Defines].*$')
PackageHederFlag = False
DefineHeaderFlag = False
@@ -255,8 +255,8 @@ def GetGuidVerFormLibInstance(Guid, Version, WorkSpace, CurrentInfFileName):
FileLinesList = InfFileObj.readlines()
FileLinesList = ProcessLineExtender(FileLinesList)
- ReFindFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$")
- ReFindVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$")
+ ReFindFileGuidPattern = re.compile(r"^\s*FILE_GUID\s*=.*$")
+ ReFindVerStringPattern = re.compile(r"^\s*VERSION_STRING\s*=.*$")
for Line in FileLinesList:
if ReFindFileGuidPattern.match(Line):
diff --git a/BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py
index a63e40e..9edcc2c 100644
--- a/BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py
+++ b/BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py
@@ -40,7 +40,7 @@ def GetValidateArchList(LineContent):
TempArch = GetSplitValueList(TempArch, '(', 1)[0]
- ArchList = re.split('\s+', TempArch)
+ ArchList = re.split(r'\s+', TempArch)
NewArchList = []
for Arch in ArchList:
if IsValidArch(Arch):
diff --git a/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py b/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py
index d01ae9a..eb768b9 100644
--- a/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py
+++ b/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py
@@ -109,7 +109,7 @@ def InfExpandMacro(Content, LineInfo, GlobalMacros=None, SectionMacros=None, Fla
return Content
else:
for Macro in MacroUsed:
- gQuotedMacro = re.compile(".*\".*\$\(%s\).*\".*"%(Macro))
+ gQuotedMacro = re.compile(r".*\".*\$\(%s\).*\".*"%(Macro))
if not gQuotedMacro.match(Content):
#
# Still have MACROs can't be expanded.
@@ -130,8 +130,8 @@ def IsBinaryInf(FileLineList):
if not FileLineList:
return False
- ReIsSourcesSection = re.compile("^\s*\[Sources.*\]\s.*$", re.IGNORECASE)
- ReIsBinarySection = re.compile("^\s*\[Binaries.*\]\s.*$", re.IGNORECASE)
+ ReIsSourcesSection = re.compile(r"^\s*\[Sources.*\]\s.*$", re.IGNORECASE)
+ ReIsBinarySection = re.compile(r"^\s*\[Binaries.*\]\s.*$", re.IGNORECASE)
BinarySectionFoundFlag = False
for Line in FileLineList:
@@ -155,7 +155,7 @@ def IsBinaryInf(FileLineList):
# @return Flag
#
def IsLibInstanceInfo(String):
- ReIsLibInstance = re.compile("^\s*##\s*@LIB_INSTANCES\s*$")
+ ReIsLibInstance = re.compile(r"^\s*##\s*@LIB_INSTANCES\s*$")
if ReIsLibInstance.match(String):
return True
else:
@@ -171,7 +171,7 @@ def IsLibInstanceInfo(String):
# @return Flag
#
def IsAsBuildOptionInfo(String):
- ReIsAsBuildInstance = re.compile("^\s*##\s*@AsBuilt\s*$")
+ ReIsAsBuildInstance = re.compile(r"^\s*##\s*@AsBuilt\s*$")
if ReIsAsBuildInstance.match(String):
return True
else:
diff --git a/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py b/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py
index da92fe5..b1f8135 100644
--- a/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py
+++ b/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py
@@ -747,12 +747,12 @@ class DecPomAlignment(PackageObject):
#
# deal with "NOT EQ", "NOT LT", "NOT GT", "NOT LE", "NOT GE", "NOT NOT"
#
- NOTNOT_Pattern = '[\t\s]*NOT[\t\s]+NOT[\t\s]*'
- NOTGE_Pattern = '[\t\s]*NOT[\t\s]+GE[\t\s]*'
- NOTLE_Pattern = '[\t\s]*NOT[\t\s]+LE[\t\s]*'
- NOTGT_Pattern = '[\t\s]*NOT[\t\s]+GT[\t\s]*'
- NOTLT_Pattern = '[\t\s]*NOT[\t\s]+LT[\t\s]*'
- NOTEQ_Pattern = '[\t\s]*NOT[\t\s]+EQ[\t\s]*'
+ NOTNOT_Pattern = r'[\t\s]*NOT[\t\s]+NOT[\t\s]*'
+ NOTGE_Pattern = r'[\t\s]*NOT[\t\s]+GE[\t\s]*'
+ NOTLE_Pattern = r'[\t\s]*NOT[\t\s]+LE[\t\s]*'
+ NOTGT_Pattern = r'[\t\s]*NOT[\t\s]+GT[\t\s]*'
+ NOTLT_Pattern = r'[\t\s]*NOT[\t\s]+LT[\t\s]*'
+ NOTEQ_Pattern = r'[\t\s]*NOT[\t\s]+EQ[\t\s]*'
ReplaceValue = re.compile(NOTNOT_Pattern).sub('', ReplaceValue)
ReplaceValue = re.compile(NOTLT_Pattern).sub('x >= ', ReplaceValue)
ReplaceValue = re.compile(NOTGT_Pattern).sub('x <= ', ReplaceValue)
@@ -785,7 +785,7 @@ class DecPomAlignment(PackageObject):
if ReplaceValue.find('!') >= 0 and ReplaceValue[ReplaceValue.index('!') + 1] != '=':
ReplaceValue = ReplaceValue.replace('!', ' not ')
if '.' in ReplaceValue:
- Pattern = '[a-zA-Z0-9]{1,}\.[a-zA-Z0-9]{1,}'
+ Pattern = r'[a-zA-Z0-9]{1,}\.[a-zA-Z0-9]{1,}'
MatchedList = re.findall(Pattern, ReplaceValue)
for MatchedItem in MatchedList:
if MatchedItem not in self.PcdDefaultValueDict:
@@ -814,7 +814,7 @@ class DecPomAlignment(PackageObject):
#
# Delete the 'L' prefix of a quoted string, this operation is for eval()
#
- QUOTED_PATTERN = '[\t\s]*L?"[^"]*"'
+ QUOTED_PATTERN = r'[\t\s]*L?"[^"]*"'
QuotedMatchedObj = re.search(QUOTED_PATTERN, Expression)
if QuotedMatchedObj:
MatchedStr = QuotedMatchedObj.group().strip()
@@ -847,7 +847,7 @@ class DecPomAlignment(PackageObject):
#
# Delete the 'L' prefix of a quoted string, this operation is for eval()
#
- QUOTED_PATTERN = '[\t\s]*L?"[^"]*"'
+ QUOTED_PATTERN = r'[\t\s]*L?"[^"]*"'
QuotedMatchedObj = re.search(QUOTED_PATTERN, DefaultValue)
if QuotedMatchedObj:
MatchedStr = QuotedMatchedObj.group().strip()
diff --git a/BaseTools/Source/Python/UPT/Xml/IniToXml.py b/BaseTools/Source/Python/UPT/Xml/IniToXml.py
index 3dc4001..2c01c97 100644
--- a/BaseTools/Source/Python/UPT/Xml/IniToXml.py
+++ b/BaseTools/Source/Python/UPT/Xml/IniToXml.py
@@ -200,9 +200,9 @@ def ValidateRegValues(Key, Value):
('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}'
'-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}',
ST.ERR_GUID_VALUE % Value),
- 'Version' : ('[0-9]+(\.[0-9]+)?', ST.ERR_VERSION_VALUE % \
+ 'Version' : (r'[0-9]+(\.[0-9]+)?', ST.ERR_VERSION_VALUE % \
(Key, Value)),
- 'XmlSpecification' : ('1\.1', ST.ERR_VERSION_XMLSPEC % Value)
+ 'XmlSpecification' : (r'1\.1', ST.ERR_VERSION_XMLSPEC % Value)
}
if Key not in ValidateMap:
return True, ''
diff --git a/BaseTools/Source/Python/UPT/Xml/PcdXml.py b/BaseTools/Source/Python/UPT/Xml/PcdXml.py
index bbcee45..ca95c82 100644
--- a/BaseTools/Source/Python/UPT/Xml/PcdXml.py
+++ b/BaseTools/Source/Python/UPT/Xml/PcdXml.py
@@ -100,11 +100,11 @@ class PcdErrorXml(object):
def TransferValidRange2Expr(self, TokenSpaceGuidCName, CName, ValidRange):
if self.Expression:
pass
- INT_RANGE_PATTERN1 = '[\t\s]*[0-9]+[\t\s]*-[\t\s]*[0-9]+'
- INT_RANGE_PATTERN2 = '[\t\s]*(LT|GT|LE|GE|XOR|EQ)[\t\s]+\d+[\t\s]*'
+ INT_RANGE_PATTERN1 = r'[\t\s]*[0-9]+[\t\s]*-[\t\s]*[0-9]+'
+ INT_RANGE_PATTERN2 = r'[\t\s]*(LT|GT|LE|GE|XOR|EQ)[\t\s]+\d+[\t\s]*'
HEX_RANGE_PATTERN1 = \
- '[\t\s]*0[xX][a-fA-F0-9]+[\t\s]*-[\t\s]*0[xX][a-fA-F0-9]+'
- HEX_RANGE_PATTERN2 = '[\t\s]*(LT|GT|LE|GE|XOR|EQ)[\t\s]+0[xX][a-fA-F0-9]+[\t\s]*'
+ r'[\t\s]*0[xX][a-fA-F0-9]+[\t\s]*-[\t\s]*0[xX][a-fA-F0-9]+'
+ HEX_RANGE_PATTERN2 = r'[\t\s]*(LT|GT|LE|GE|XOR|EQ)[\t\s]+0[xX][a-fA-F0-9]+[\t\s]*'
IntMatch1 = re.compile(INT_RANGE_PATTERN1)
IntMatch2 = re.compile(INT_RANGE_PATTERN2)
HexMatch1 = re.compile(HEX_RANGE_PATTERN1)
@@ -158,18 +158,18 @@ class PcdErrorXml(object):
pass
PCD_PATTERN = \
- '[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*[\t\s]*\.[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*[\t\s]*'
+ r'[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*[\t\s]*\.[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*[\t\s]*'
IntPattern1 = \
- '[\t\s]*\([\t\s]*'+PCD_PATTERN+'[\t\s]+GE[\t\s]+\d+[\t\s]*\)[\t\s]+AND[\t\s]+\([\t\s]*'+\
- PCD_PATTERN+'[\t\s]+LE[\t\s]+\d+[\t\s]*\)'
+ r'[\t\s]*\([\t\s]*'+PCD_PATTERN+r'[\t\s]+GE[\t\s]+\d+[\t\s]*\)[\t\s]+AND[\t\s]+\([\t\s]*'+\
+ PCD_PATTERN+r'[\t\s]+LE[\t\s]+\d+[\t\s]*\)'
IntPattern1 = IntPattern1.replace(' ', '')
- IntPattern2 = '[\t\s]*'+PCD_PATTERN+'[\t\s]+(LT|GT|LE|GE|XOR|EQ)[\t\s]+\d+[\t\s]*'
+ IntPattern2 = r'[\t\s]*'+PCD_PATTERN+r'[\t\s]+(LT|GT|LE|GE|XOR|EQ)[\t\s]+\d+[\t\s]*'
HexPattern1 = \
- '[\t\s]*\([\t\s]*'+PCD_PATTERN+'[\t\s]+GE[\t\s]+0[xX][0-9a-fA-F]+[\t\s]*\)[\t\s]+AND[\t\s]+\([\t\s]*'+\
- PCD_PATTERN+'[\t\s]+LE[\t\s]+0[xX][0-9a-fA-F]+[\t\s]*\)'
+ r'[\t\s]*\([\t\s]*'+PCD_PATTERN+r'[\t\s]+GE[\t\s]+0[xX][0-9a-fA-F]+[\t\s]*\)[\t\s]+AND[\t\s]+\([\t\s]*'+\
+ PCD_PATTERN+r'[\t\s]+LE[\t\s]+0[xX][0-9a-fA-F]+[\t\s]*\)'
HexPattern1 = HexPattern1.replace(' ', '')
- HexPattern2 = '[\t\s]*'+PCD_PATTERN+'[\t\s]+(LT|GT|LE|GE|XOR|EQ)[\t\s]+0[xX][0-9a-zA-Z]+[\t\s]*'
+ HexPattern2 = r'[\t\s]*'+PCD_PATTERN+r'[\t\s]+(LT|GT|LE|GE|XOR|EQ)[\t\s]+0[xX][0-9a-zA-Z]+[\t\s]*'
#
# Do the Hex1 conversion
@@ -180,7 +180,7 @@ class PcdErrorXml(object):
#
# To match items on both sides of '-'
#
- RangeItemList = re.compile('[\t\s]*0[xX][0-9a-fA-F]+[\t\s]*').findall(HexMatchedItem)
+ RangeItemList = re.compile(r'[\t\s]*0[xX][0-9a-fA-F]+[\t\s]*').findall(HexMatchedItem)
if RangeItemList and len(RangeItemList) == 2:
HexRangeDict[HexMatchedItem] = RangeItemList
@@ -204,7 +204,7 @@ class PcdErrorXml(object):
#
# To match items on both sides of '-'
#
- RangeItemList = re.compile('[\t\s]*\d+[\t\s]*').findall(MatchedItem)
+ RangeItemList = re.compile(r'[\t\s]*\d+[\t\s]*').findall(MatchedItem)
if RangeItemList and len(RangeItemList) == 2:
IntRangeDict[MatchedItem] = RangeItemList
diff --git a/BaseTools/Source/Python/UPT/Xml/XmlParser.py b/BaseTools/Source/Python/UPT/Xml/XmlParser.py
index 8e22a28..f239588 100644
--- a/BaseTools/Source/Python/UPT/Xml/XmlParser.py
+++ b/BaseTools/Source/Python/UPT/Xml/XmlParser.py
@@ -281,33 +281,33 @@ class DistributionPackageXml(object):
#
XmlContent = \
re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
- '[\s\r\n]*"', '', XmlContent)
+ r'[\s\r\n]*"', '', XmlContent)
XmlContent = \
re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
- '[\s\r\n]*"', '', XmlContent)
+ r'[\s\r\n]*"', '', XmlContent)
#
# Remove <SupArchList> COMMON </SupArchList>
#
XmlContent = \
re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*COMMON[\s\r\n]*'
- '</SupArchList>[\s\r\n]*', '', XmlContent)
+ r'</SupArchList>[\s\r\n]*', '', XmlContent)
#
# Remove <SupArchList> common </SupArchList>
#
XmlContent = \
re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*'
- 'common[\s\r\n]*</SupArchList>[\s\r\n]*', '', XmlContent)
+ r'common[\s\r\n]*</SupArchList>[\s\r\n]*', '', XmlContent)
#
# Remove SupModList="COMMON" or "common"
#
XmlContent = \
re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
- '[\s\r\n]*"', '', XmlContent)
+ r'[\s\r\n]*"', '', XmlContent)
XmlContent = \
re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
- '[\s\r\n]*"', '', XmlContent)
+ r'[\s\r\n]*"', '', XmlContent)
return XmlContent
diff --git a/BaseTools/Source/Python/Workspace/InfBuildData.py b/BaseTools/Source/Python/Workspace/InfBuildData.py
index e4ff1c6..6339e49 100644
--- a/BaseTools/Source/Python/Workspace/InfBuildData.py
+++ b/BaseTools/Source/Python/Workspace/InfBuildData.py
@@ -592,7 +592,7 @@ class InfBuildData(ModuleBuildClassObject):
RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
- Value = _ProtocolValue(CName, self.Packages, self.MetaFile.Path)
+ Value = _ProtocolValue(CName, self.Packages, self.MetaFile.OriginalPath.Path)
if Value is None:
PackageList = "\n\t".join(str(P) for P in self.Packages)
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
@@ -616,7 +616,7 @@ class InfBuildData(ModuleBuildClassObject):
RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
- Value = _PpiValue(CName, self.Packages, self.MetaFile.Path)
+ Value = _PpiValue(CName, self.Packages, self.MetaFile.OriginalPath.Path)
if Value is None:
PackageList = "\n\t".join(str(P) for P in self.Packages)
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
@@ -640,7 +640,7 @@ class InfBuildData(ModuleBuildClassObject):
RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
- Value = GuidValue(CName, self.Packages, self.MetaFile.Path)
+ Value = GuidValue(CName, self.Packages, self.MetaFile.OriginalPath.Path)
if Value is None:
PackageList = "\n\t".join(str(P) for P in self.Packages)
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
@@ -655,7 +655,7 @@ class InfBuildData(ModuleBuildClassObject):
for TokenSpaceGuid, _, _, _, _, _, LineNo in RecordList:
# get the guid value
if TokenSpaceGuid not in RetVal:
- Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)
+ Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.OriginalPath.Path)
if Value is None:
PackageList = "\n\t".join(str(P) for P in self.Packages)
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
@@ -818,11 +818,11 @@ class InfBuildData(ModuleBuildClassObject):
Value = Token
else:
# get the GUID value now
- Value = _ProtocolValue(Token, self.Packages, self.MetaFile.Path)
+ Value = _ProtocolValue(Token, self.Packages, self.MetaFile.OriginalPath.Path)
if Value is None:
- Value = _PpiValue(Token, self.Packages, self.MetaFile.Path)
+ Value = _PpiValue(Token, self.Packages, self.MetaFile.OriginalPath.Path)
if Value is None:
- Value = GuidValue(Token, self.Packages, self.MetaFile.Path)
+ Value = GuidValue(Token, self.Packages, self.MetaFile.OriginalPath.Path)
if Value is None:
PackageList = "\n\t".join(str(P) for P in self.Packages)
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index 51fb1f4..ce1bb87 100755
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -28,6 +28,8 @@ import threading
from linecache import getlines
from subprocess import Popen,PIPE, STDOUT
from collections import OrderedDict, defaultdict
+import json
+import secrets
from AutoGen.PlatformAutoGen import PlatformAutoGen
from AutoGen.ModuleAutoGen import ModuleAutoGen
@@ -282,6 +284,22 @@ def LaunchCommand(Command, WorkingDir,ModuleAuto = None):
iau.CreateDepsTarget()
return "%dms" % (int(round((time.time() - BeginTime) * 1000)))
+def GenerateStackCookieValues():
+ if GlobalData.gBuildDirectory == "":
+ return
+
+ # Check if the 32 bit values array needs to be created
+ if not os.path.exists(os.path.join(GlobalData.gBuildDirectory, "StackCookieValues32.json")):
+ StackCookieValues32 = [secrets.randbelow(0xFFFFFFFF) for _ in range(0, 100)]
+ with open (os.path.join(GlobalData.gBuildDirectory, "StackCookieValues32.json"), "w") as file:
+ json.dump(StackCookieValues32, file)
+
+ # Check if the 64 bit values array needs to be created
+ if not os.path.exists(os.path.join(GlobalData.gBuildDirectory, "StackCookieValues64.json")):
+ StackCookieValues64 = [secrets.randbelow(0xFFFFFFFFFFFFFFFF) for _ in range(0, 100)]
+ with open (os.path.join(GlobalData.gBuildDirectory, "StackCookieValues64.json"), "w") as file:
+ json.dump(StackCookieValues64, file)
+
## The smallest unit that can be built in multi-thread build mode
#
# This is the base class of build unit. The "Obj" parameter must provide
@@ -1794,6 +1812,7 @@ class Build():
self.UniFlag,
self.Progress
)
+ GenerateStackCookieValues()
self.Fdf = Wa.FdfFile
self.LoadFixAddress = Wa.Platform.LoadFixAddress
self.BuildReport.AddPlatformReport(Wa)
@@ -1897,6 +1916,7 @@ class Build():
self.Progress,
self.ModuleFile
)
+ GenerateStackCookieValues()
self.Fdf = Wa.FdfFile
self.LoadFixAddress = Wa.Platform.LoadFixAddress
Wa.CreateMakeFile(False)
@@ -2147,6 +2167,7 @@ class Build():
self.UniFlag,
self.Progress
)
+ GenerateStackCookieValues()
self.Fdf = Wa.FdfFile
self.LoadFixAddress = Wa.Platform.LoadFixAddress
self.BuildReport.AddPlatformReport(Wa)
diff --git a/BaseTools/set_vsprefix_envs.bat b/BaseTools/set_vsprefix_envs.bat
index 0b9a0c7..df2c771 100644
--- a/BaseTools/set_vsprefix_envs.bat
+++ b/BaseTools/set_vsprefix_envs.bat
@@ -18,6 +18,7 @@ set SCRIPT_ERROR=1
goto :EOF
:main
+if /I "%1"=="VS2022" goto SetVS2022
if /I "%1"=="VS2019" goto SetVS2019
if /I "%1"=="VS2017" goto SetVS2017
if /I "%1"=="VS2015" goto SetVS2015
@@ -34,10 +35,18 @@ if defined VS140COMNTOOLS (
set "VS2015_PREFIX=%VS140COMNTOOLS:~0,-14%"
)
if not defined WINSDK81_PREFIX (
- set "WINSDK81_PREFIX=c:\Program Files\Windows Kits\8.1\bin\"
+ if exist "%ProgramFiles%\Windows Kits\8.1\bin" (
+ set "WINSDK81_PREFIX=%ProgramFiles%\Windows Kits\8.1\bin\"
+ ) else if exist "%ProgramFiles(x86)%\Windows Kits\8.1\bin" (
+ set "WINSDK81_PREFIX=%ProgramFiles(x86)%\Windows Kits\8.1\bin\"
+ )
)
if not defined WINSDK81x86_PREFIX (
- set "WINSDK81x86_PREFIX=c:\Program Files (x86)\Windows Kits\8.1\bin\"
+ if exist "%ProgramFiles(x86)%\Windows Kits\8.1\bin" (
+ set "WINSDK81x86_PREFIX=%ProgramFiles(x86)%\Windows Kits\8.1\bin\"
+ ) else if exist "%ProgramFiles%\Windows Kits\8.1\bin" (
+ set "WINSDK81x86_PREFIX=%ProgramFiles%\Windows Kits\8.1\bin\"
+ )
)
) else (
if /I "%1"=="VS2015" goto ToolNotInstall
@@ -166,6 +175,67 @@ if not defined WINSDK_PATH_FOR_RC_EXE (
if /I "%1"=="VS2019" goto SetWinDDK
+:SetVS2022
+if not defined VS170COMNTOOLS (
+ @REM clear two envs so that vcvars32.bat can run successfully.
+ set VSINSTALLDIR=
+ set VCToolsVersion=
+ if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" (
+ if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\2022\BuildTools" (
+ call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -products Microsoft.VisualStudio.Product.BuildTools -version 17,18 > vswhereInfo
+ for /f "usebackq tokens=1* delims=: " %%i in (vswhereInfo) do (
+ if /i "%%i"=="installationPath" call "%%j\VC\Auxiliary\Build\vcvars32.bat"
+ )
+ del vswhereInfo
+ ) else (
+ call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -version 17,18 > vswhereInfo
+ for /f "usebackq tokens=1* delims=: " %%i in (vswhereInfo) do (
+ if /i "%%i"=="installationPath" call "%%j\VC\Auxiliary\Build\vcvars32.bat"
+ )
+ del vswhereInfo
+ )
+ ) else if exist "%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" (
+ if exist "%ProgramFiles%\Microsoft Visual Studio\2022\BuildTools" (
+ call "%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" -products Microsoft.VisualStudio.Product.BuildTools -version 17,18 > vswhereInfo
+ for /f "usebackq tokens=1* delims=: " %%i in (vswhereInfo) do (
+ if /i "%%i"=="installationPath" call "%%j\VC\Auxiliary\Build\vcvars32.bat"
+ )
+ del vswhereInfo
+ ) else (
+ call "%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" -version 17,18 > vswhereInfo
+ for /f "usebackq tokens=1* delims=: " %%i in (vswhereInfo) do (
+ if /i "%%i"=="installationPath" call "%%j\VC\Auxiliary\Build\vcvars32.bat"
+ )
+ del vswhereInfo
+ )
+ ) else (
+ if /I "%1"=="VS2022" goto ToolNotInstall
+ goto SetWinDDK
+ )
+)
+
+if defined VCToolsInstallDir (
+ if not defined VS2022_PREFIX (
+ set "VS2022_PREFIX=%VCToolsInstallDir%"
+ )
+ if not defined WINSDK10_PREFIX (
+ if defined WindowsSdkVerBinPath (
+ set "WINSDK10_PREFIX=%WindowsSdkVerBinPath%"
+ ) else if exist "%ProgramFiles(x86)%\Windows Kits\10\bin" (
+ set "WINSDK10_PREFIX=%ProgramFiles(x86)%\Windows Kits\10\bin\"
+ ) else if exist "%ProgramFiles%\Windows Kits\10\bin" (
+ set "WINSDK10_PREFIX=%ProgramFiles%\Windows Kits\10\bin\"
+ )
+ )
+)
+if not defined WINSDK_PATH_FOR_RC_EXE (
+ if defined WINSDK10_PREFIX (
+ set "WINSDK_PATH_FOR_RC_EXE=%WINSDK10_PREFIX%x86"
+ )
+)
+
+if /I "%1"=="VS2022" goto SetWinDDK
+
:SetWinDDK
if not defined WINDDK3790_PREFIX (
set WINDDK3790_PREFIX=C:\WINDDK\3790.1830\bin\
diff --git a/BaseTools/toolsetup.bat b/BaseTools/toolsetup.bat
index 22bd0fa..bdbc052 100755
--- a/BaseTools/toolsetup.bat
+++ b/BaseTools/toolsetup.bat
@@ -44,6 +44,12 @@ if /I "%1"=="/?" goto Usage
set FORCE_REBUILD=TRUE
goto loop
)
+ if /I "%1"=="VS2022" (
+ shift
+ set VS2022=TRUE
+ set VSTool=VS2022
+ goto loop
+ )
if /I "%1"=="VS2019" (
shift
set VS2019=TRUE
@@ -172,7 +178,9 @@ IF NOT exist "%EDK_TOOLS_PATH%\set_vsprefix_envs.bat" (
@echo.
goto end
)
-if defined VS2019 (
+if defined VS2022 (
+ call %EDK_TOOLS_PATH%\set_vsprefix_envs.bat VS2022
+) else if defined VS2019 (
call %EDK_TOOLS_PATH%\set_vsprefix_envs.bat VS2019
) else if defined VS2017 (
call %EDK_TOOLS_PATH%\set_vsprefix_envs.bat VS2017
@@ -342,28 +350,12 @@ if %ERRORLEVEL% NEQ 0 (
endlocal
-%PYTHON_COMMAND% -c "import edk2basetools" >NUL 2>NUL
-if %ERRORLEVEL% EQU 0 (
- goto use_pip_basetools
-) else (
- REM reset ERRORLEVEL
- type nul>nul
- goto use_builtin_basetools
-)
-
-:use_builtin_basetools
@echo Using EDK2 in-source Basetools
if defined BASETOOLS_PYTHON_SOURCE goto print_python_info
set "PATH=%BASE_TOOLS_PATH%\BinWrappers\WindowsLike;%PATH%"
set PYTHONPATH=%BASE_TOOLS_PATH%\Source\Python;%PYTHONPATH%
goto print_python_info
-:use_pip_basetools
- @echo Using Pip Basetools
- set "PATH=%BASE_TOOLS_PATH%\BinPipWrappers\WindowsLike;%PATH%"
- set PYTHONPATH=%BASE_TOOLS_PATH%\Source\Python;%PYTHONPATH%
- goto print_python_info
-
:print_python_info
echo PATH = %PATH%
echo.
@@ -437,12 +429,14 @@ if %ERRORLEVEL% EQU 0 (
@echo VS2015 Set the env for VS2015 build.
@echo VS2017 Set the env for VS2017 build.
@echo VS2019 Set the env for VS2019 build.
+ @echo VS2022 Set the env for VS2022 build.
@echo.
:end
set REBUILD=
set FORCE_REBUILD=
set RECONFIG=
+set VS2022=
set VS2019=
set VS2017=
set VS2015=
diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec
index e613b6b..dc521c0 100644
--- a/CryptoPkg/CryptoPkg.dec
+++ b/CryptoPkg/CryptoPkg.dec
@@ -22,6 +22,7 @@
[Includes.Common.Private]
Private
Library/Include
+ Library/OpensslLib/openssl
Library/OpensslLib/openssl/include
Library/OpensslLib/openssl/providers/common/include
Library/OpensslLib/openssl/providers/implementations/include
diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
index 6a0104a..d440069 100644
--- a/CryptoPkg/CryptoPkg.dsc
+++ b/CryptoPkg/CryptoPkg.dsc
@@ -5,6 +5,7 @@
# Copyright (c) 2009 - 2022, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
+# Copyright (c) 2023, Arm Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -116,16 +117,6 @@
[LibraryClasses.ARM, LibraryClasses.AARCH64]
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
- #
- # It is not possible to prevent the ARM compiler for generic intrinsic functions.
- # This library provides the instrinsic functions generate by a given compiler.
- # [LibraryClasses.ARM, LibraryClasses.AARCH64] and NULL mean link this library
- # into all ARM and AARCH64 images.
- #
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- # Add support for stack protector
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
[LibraryClasses.ARM]
ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
@@ -133,6 +124,8 @@
[LibraryClasses.common.SEC]
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf
+ # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
[LibraryClasses.common.PEIM]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
@@ -327,7 +320,7 @@
MSFT:NOOPT_*_*_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /BASE:0x10000
}
-[Components.IA32, Components.X64]
+[Components.IA32, Components.X64, Components.AARCH64]
CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf {
<Defines>
FILE_GUID = B91B9A95-4D52-4501-A98F-A1711C14ED93
@@ -379,6 +372,7 @@
CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
CryptoPkg/Library/OpensslLib/OpensslLib.inf
CryptoPkg/Library/OpensslLib/OpensslLibFull.inf
+ CryptoPkg/Library/OpensslLib/OpensslLibSm3.inf
CryptoPkg/Library/BaseHashApiLib/BaseHashApiLib.inf
CryptoPkg/Library/BaseCryptLibOnProtocolPpi/PeiCryptLib.inf
CryptoPkg/Library/BaseCryptLibOnProtocolPpi/DxeCryptLib.inf
@@ -396,9 +390,9 @@
TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
}
-[Components.IA32, Components.X64]
+[Components.IA32, Components.X64, Components.AARCH64]
#
- # Build verification of IA32/X64 specific libraries
+ # Build verification of IA32/X64/AARCH64 specific libraries
#
CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf
CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf
@@ -439,9 +433,9 @@
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf
}
-[Components.IA32, Components.X64]
+[Components.IA32, Components.X64, Components.AARCH64]
#
- # CryptoPei with IA32/X64 performance optimized OpensslLib instance without EC services
+ # CryptoPei with IA32/X64/AARCH64 performance optimized OpensslLib instance without EC services
# IA32/X64 assembly optimizations required larger alignments
#
CryptoPkg/Driver/CryptoPei.inf {
@@ -455,7 +449,7 @@
}
#
- # CryptoPei with IA32/X64 performance optimized OpensslLib instance all services
+ # CryptoPei with IA32/X64/AARCH64 performance optimized OpensslLib instance all services
# IA32/X64 assembly optimizations required larger alignments
#
CryptoPkg/Driver/CryptoPei.inf {
@@ -505,9 +499,9 @@
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf
}
-[Components.IA32, Components.X64]
+[Components.IA32, Components.X64, Components.AARCH64]
#
- # CryptoDxe with IA32/X64 performance optimized OpensslLib instance with no EC services
+ # CryptoDxe with IA32/X64/AARCH64 performance optimized OpensslLib instance with no EC services
# with TLS feature enabled.
# IA32/X64 assembly optimizations required larger alignments
#
@@ -521,7 +515,7 @@
MSFT:*_*_X64_DLINK_FLAGS = /ALIGN:256
}
#
- # CryptoDxe with IA32/X64 performance optimized OpensslLib instance with all services.
+ # CryptoDxe with IA32/X64/AARCH64 performance optimized OpensslLib instance with all services.
# IA32/X64 assembly optimizations required larger alignments
#
CryptoPkg/Driver/CryptoDxe.inf {
@@ -561,7 +555,7 @@
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf
}
#
- # CryptoSmm with IA32/X64 performance optimized OpensslLib instance with no EC services
+ # CryptoSmm with IA32/X64/AARCH64 performance optimized OpensslLib instance with no EC services
# IA32/X64 assembly optimizations required larger alignments
#
CryptoPkg/Driver/CryptoSmm.inf {
@@ -574,7 +568,7 @@
MSFT:*_*_X64_DLINK_FLAGS = /ALIGN:256
}
#
- # CryptoSmm with IA32/X64 performance optimized OpensslLib instance with all services
+ # CryptoSmm with IA32/X64/AARCH64 performance optimized OpensslLib instance with all services
# IA32/X64 assembly optimizations required larger alignments
#
CryptoPkg/Driver/CryptoSmm.inf {
diff --git a/CryptoPkg/CryptoPkgMbedTls.dsc b/CryptoPkg/CryptoPkgMbedTls.dsc
index c97b28c..17f41c4 100644
--- a/CryptoPkg/CryptoPkgMbedTls.dsc
+++ b/CryptoPkg/CryptoPkgMbedTls.dsc
@@ -51,18 +51,6 @@
RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
-[LibraryClasses.ARM, LibraryClasses.AARCH64]
- #
- # It is not possible to prevent the ARM compiler for generic intrinsic functions.
- # This library provides the instrinsic functions generate by a given compiler.
- # [LibraryClasses.ARM, LibraryClasses.AARCH64] and NULL mean link this library
- # into all ARM and AARCH64 images.
- #
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- # Add support for stack protector
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
[LibraryClasses.common.PEIM]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
index 95e4142..84ed87e 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -23,9 +23,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define CRYPTO_NID_SHA512 0x0003
// Key Exchange
-#define CRYPTO_NID_SECP256R1 0x0204
-#define CRYPTO_NID_SECP384R1 0x0205
-#define CRYPTO_NID_SECP521R1 0x0206
+#define CRYPTO_NID_SECP256R1 0x0204
+#define CRYPTO_NID_SECP384R1 0x0205
+#define CRYPTO_NID_SECP521R1 0x0206
+#define CRYPTO_NID_BRAINPOOLP512R1 0x03A5
///
/// MD5 digest size in bytes
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c
index d8cc9ba..f85232b 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptEc.c
@@ -42,6 +42,9 @@ CryptoNidToOpensslNid (
case CRYPTO_NID_SECP521R1:
Nid = NID_secp521r1;
break;
+ case CRYPTO_NID_BRAINPOOLP512R1:
+ Nid = NID_brainpoolP512r1;
+ break;
default:
return -1;
}
@@ -833,6 +836,9 @@ EcDsaSign (
case NID_secp521r1:
HalfSize = 66;
break;
+ case NID_brainpoolP512r1:
+ HalfSize = 64;
+ break;
default:
return FALSE;
}
@@ -961,6 +967,9 @@ EcDsaVerify (
case NID_secp521r1:
HalfSize = 66;
break;
+ case NID_brainpoolP512r1:
+ HalfSize = 64;
+ break;
default:
return FALSE;
}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
index 349d37b..628e714 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
@@ -102,7 +102,6 @@ X509ConstructCertificateStackV (
STACK_OF (X509) *CertStack;
BOOLEAN Status;
- UINTN Index;
//
// Check input parameters.
@@ -124,7 +123,7 @@ X509ConstructCertificateStackV (
}
}
- for (Index = 0; ; Index++) {
+ while (TRUE) {
//
// If Cert is NULL, then it is the end of the list.
//
diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/ConstantTimeClock.c b/CryptoPkg/Library/BaseCryptLib/SysCall/ConstantTimeClock.c
index 2956b92..3f3ec3e 100644
--- a/CryptoPkg/Library/BaseCryptLib/SysCall/ConstantTimeClock.c
+++ b/CryptoPkg/Library/BaseCryptLib/SysCall/ConstantTimeClock.c
@@ -42,3 +42,32 @@ gmtime (
{
return NULL;
}
+
+time_t
+mktime (
+ struct tm *t
+ )
+{
+ return 0;
+}
+
+unsigned int
+sleep (
+ unsigned int seconds
+ )
+{
+ return 0;
+}
+
+int
+gettimeofday (
+ struct timeval *tv,
+ struct timezone *tz
+ )
+{
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+ return 0;
+}
+
+long timezone;
diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
index 2dfc6fe..9b3a291 100644
--- a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
+++ b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
@@ -9,6 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Uefi.h>
#include <CrtLibSupport.h>
+#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
//
@@ -19,6 +20,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define SECSPERHOUR (60 * 60)
#define SECSPERDAY (24 * SECSPERHOUR)
+long timezone;
+
//
// 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.
@@ -79,6 +82,37 @@ IsLeap (
return (Remainder1 == 0 && (Remainder2 != 0 || Remainder3 == 0));
}
+STATIC
+time_t
+CalculateTimeT (
+ EFI_TIME *Time
+ )
+{
+ time_t CalTime;
+ UINTN Year;
+
+ //
+ // 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;
+
+ return CalTime;
+}
+
/* Get the system time as seconds elapsed since midnight, January 1, 1970. */
// INTN time(
// INTN *timer
@@ -91,7 +125,6 @@ time (
EFI_STATUS Status;
EFI_TIME Time;
time_t CalTime;
- UINTN Year;
//
// Get the current time and date information
@@ -101,24 +134,7 @@ time (
return 0;
}
- //
- // 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;
+ CalTime = CalculateTimeT (&Time);
if (timer != NULL) {
*timer = CalTime;
@@ -127,6 +143,24 @@ time (
return CalTime;
}
+time_t
+mktime (
+ struct tm *t
+ )
+{
+ EFI_TIME Time = {
+ .Year = (UINT16)t->tm_year,
+ .Month = (UINT8)t->tm_mon,
+ .Day = (UINT8)t->tm_mday,
+ .Hour = (UINT8)t->tm_hour,
+ .Minute = (UINT8)t->tm_min,
+ .Second = (UINT8)t->tm_sec,
+ .TimeZone = EFI_UNSPECIFIED_TIMEZONE,
+ };
+
+ return CalculateTimeT (&Time);
+}
+
//
// Convert a time value from type time_t to struct tm.
//
@@ -195,3 +229,23 @@ gmtime (
return GmTime;
}
+
+unsigned int
+sleep (
+ unsigned int seconds
+ )
+{
+ gBS->Stall (seconds * 1000 * 1000);
+ return 0;
+}
+
+int
+gettimeofday (
+ struct timeval *tv,
+ struct timezone *tz
+ )
+{
+ tv->tv_sec = (long)time (NULL);
+ tv->tv_usec = 0;
+ return 0;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/UnitTestHostCrtWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/UnitTestHostCrtWrapper.c
index 244e574..3aa76e0 100644
--- a/CryptoPkg/Library/BaseCryptLib/SysCall/UnitTestHostCrtWrapper.c
+++ b/CryptoPkg/Library/BaseCryptLib/SysCall/UnitTestHostCrtWrapper.c
@@ -104,4 +104,24 @@ getegid (
return 0;
}
-int errno = 0;
+unsigned int
+sleep (
+ unsigned int seconds
+ )
+{
+ return 0;
+}
+
+int
+gettimeofday (
+ struct timeval *tv,
+ struct timezone *tz
+ )
+{
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+ return 0;
+}
+
+int errno = 0;
+long timezone;
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf
index 3c05766..5ff7bf4 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/PeiCryptLib.inf
@@ -99,8 +99,7 @@
#
MSFT:*_*_*_CC_FLAGS = /wd4090 /wd4718
- GCC:*_CLANG35_*_CC_FLAGS = -std=c99
- GCC:*_CLANG38_*_CC_FLAGS = -std=c99
+ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99
GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=incompatible-pointer-types
XCODE:*_*_*_CC_FLAGS = -std=c99
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
index e3283da..6caed97 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
@@ -486,6 +486,7 @@ Pkcs7Sign (
return FALSE;
}
+ Buffer = NULL;
BufferSize = 4096;
SignatureLen = MAX_SIGNATURE_SIZE;
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptTs.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptTs.c
index d3fa205..d7a0783 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptTs.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptTs.c
@@ -118,12 +118,11 @@ ImageTimestampVerify (
OUT EFI_TIME *SigningTime
)
{
- BOOLEAN Status;
- UINT8 *Ptr;
- UINT8 *End;
- INT32 Len;
- UINTN ObjLen;
- UINT8 *TempPtr;
+ UINT8 *Ptr;
+ UINT8 *End;
+ INT32 Len;
+ UINTN ObjLen;
+ UINT8 *TempPtr;
//
// Initializations
@@ -374,8 +373,8 @@ ImageTimestampVerify (
//
if (SigningTime != NULL) {
SetMem (SigningTime, sizeof (EFI_TIME), 0);
- Status = ConvertAsn1TimeToEfiTime (Ptr, SigningTime);
+ return ConvertAsn1TimeToEfiTime (Ptr, SigningTime);
}
- return Status;
+ return TRUE;
}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf
index 824aa4f..7cf478a 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/RuntimeCryptLib.inf
@@ -87,11 +87,7 @@
# Remove these [BuildOptions] after this library is cleaned up
#
[BuildOptions]
- #
- # suppress the following warnings so we do not break the build with warnings-as-errors:
- #
- GCC:*_CLANG35_*_CC_FLAGS = -std=c99
- GCC:*_CLANG38_*_CC_FLAGS = -std=c99
+ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99
GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=incompatible-pointer-types
XCODE:*_*_*_CC_FLAGS = -std=c99
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SecCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/SecCryptLib.inf
index e61e07d..e21deb2 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/SecCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SecCryptLib.inf
@@ -73,11 +73,7 @@
# Remove these [BuildOptions] after this library is cleaned up
#
[BuildOptions]
- #
- # suppress the following warnings so we do not break the build with warnings-as-errors:
- #
- GCC:*_CLANG35_*_CC_FLAGS = -std=c99
- GCC:*_CLANG38_*_CC_FLAGS = -std=c99
+ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99
GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=incompatible-pointer-types
XCODE:*_*_*_CC_FLAGS = -std=c99
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf
index 649c2a3..33e86b4 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/SmmCryptLib.inf
@@ -87,12 +87,7 @@
# Remove these [BuildOptions] after this library is cleaned up
#
[BuildOptions]
- #
- # suppress the following warnings so we do not break the build with warnings-as-errors:
- #
-
XCODE:*_*_*_CC_FLAGS = -mmmx -msse -std=c99
- GCC:*_CLANG35_*_CC_FLAGS = -std=c99
- GCC:*_CLANG38_*_CC_FLAGS = -std=c99
+ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99
GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=incompatible-pointer-types
diff --git a/CryptoPkg/Library/Include/CrtLibSupport.h b/CryptoPkg/Library/Include/CrtLibSupport.h
index afc0095..cd51e19 100644
--- a/CryptoPkg/Library/Include/CrtLibSupport.h
+++ b/CryptoPkg/Library/Include/CrtLibSupport.h
@@ -16,6 +16,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PrintLib.h>
+#include <Library/TimerLib.h>
#define OPENSSLDIR ""
#define ENGINESDIR ""
@@ -108,6 +109,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
typedef UINTN size_t;
typedef UINTN off_t;
typedef UINTN u_int;
+typedef UINTN intptr_t;
typedef INTN ptrdiff_t;
typedef INTN ssize_t;
typedef INT64 time_t;
@@ -146,6 +148,8 @@ struct timeval {
long tv_usec; /* time value, in microseconds */
};
+struct timezone;
+
struct sockaddr {
__uint8_t sa_len; /* total length */
sa_family_t sa_family; /* address family */
@@ -157,6 +161,7 @@ struct sockaddr {
//
extern int errno;
extern FILE *stderr;
+extern long timezone;
//
// Function prototypes of CRT Library routines
@@ -334,6 +339,22 @@ gmtime (
const time_t *
);
+unsigned int
+sleep (
+ unsigned int seconds
+ );
+
+int
+gettimeofday (
+ struct timeval *tv,
+ struct timezone *tz
+ );
+
+time_t
+mktime (
+ struct tm *t
+ );
+
uid_t
getuid (
void
@@ -433,6 +454,5 @@ strcat (
#define assert(expression)
#define offsetof(type, member) OFFSET_OF(type,member)
#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
-#define gettimeofday(tvp, tz) do { (tvp)->tv_sec = time(NULL); (tvp)->tv_usec = 0; } while (0)
#endif
diff --git a/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf b/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
index adcf770..4ccd173 100644
--- a/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
+++ b/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
@@ -135,8 +135,7 @@
GCC:*_*_AARCH64_CC_FLAGS = -Wno-error=maybe-uninitialized -Wno-format -Wno-error=unused-but-set-variable -Wno-error=format
GCC:*_*_RISCV64_CC_FLAGS = -Wno-error=maybe-uninitialized -Wno-format -Wno-error=unused-but-set-variable
GCC:*_*_LOONGARCH64_CC_FLAGS = -Wno-error=maybe-uninitialized -Wno-format -Wno-error=unused-but-set-variable
- GCC:*_CLANG35_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized
- GCC:*_CLANG38_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized
+ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99 -Wno-error=uninitialized
GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize
# suppress the following warnings in mbedtls so we don't break the build with warnings-as-errors:
diff --git a/CryptoPkg/Library/MbedTlsLib/MbedTlsLibFull.inf b/CryptoPkg/Library/MbedTlsLib/MbedTlsLibFull.inf
index 7715392..a26e9ac 100644
--- a/CryptoPkg/Library/MbedTlsLib/MbedTlsLibFull.inf
+++ b/CryptoPkg/Library/MbedTlsLib/MbedTlsLibFull.inf
@@ -139,8 +139,7 @@
GCC:*_*_AARCH64_CC_FLAGS = -Wno-error=maybe-uninitialized -Wno-format -Wno-error=unused-but-set-variable -Wno-error=format
GCC:*_*_RISCV64_CC_FLAGS = -Wno-error=maybe-uninitialized -Wno-format -Wno-error=unused-but-set-variable
GCC:*_*_LOONGARCH64_CC_FLAGS = -Wno-error=maybe-uninitialized -Wno-format -Wno-error=unused-but-set-variable
- GCC:*_CLANG35_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized
- GCC:*_CLANG38_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized
+ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99 -Wno-error=uninitialized
GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize
# suppress the following warnings in mbedtls so we don't break the build with warnings-as-errors:
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/aesv8-armx.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/aesv8-armx.S
new file mode 100644
index 0000000..1e61e46
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/aesv8-armx.S
@@ -0,0 +1,3180 @@
+#include "arm_arch.h"
+
+#if __ARM_MAX_ARCH__>=7
+.arch armv8-a+crypto
+.text
+.align 5
+.Lrcon:
+.long 0x01,0x01,0x01,0x01
+.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat
+.long 0x1b,0x1b,0x1b,0x1b
+
+.globl aes_v8_set_encrypt_key
+.type aes_v8_set_encrypt_key,%function
+.align 5
+aes_v8_set_encrypt_key:
+.Lenc_key:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ mov x3,#-1
+ cmp x0,#0
+ b.eq .Lenc_key_abort
+ cmp x2,#0
+ b.eq .Lenc_key_abort
+ mov x3,#-2
+ cmp w1,#128
+ b.lt .Lenc_key_abort
+ cmp w1,#256
+ b.gt .Lenc_key_abort
+ tst w1,#0x3f
+ b.ne .Lenc_key_abort
+
+ adr x3,.Lrcon
+ cmp w1,#192
+
+ eor v0.16b,v0.16b,v0.16b
+ ld1 {v3.16b},[x0],#16
+ mov w1,#8 // reuse w1
+ ld1 {v1.4s,v2.4s},[x3],#32
+
+ b.lt .Loop128
+ b.eq .L192
+ b .L256
+
+.align 4
+.Loop128:
+ tbl v6.16b,{v3.16b},v2.16b
+ ext v5.16b,v0.16b,v3.16b,#12
+ st1 {v3.4s},[x2],#16
+ aese v6.16b,v0.16b
+ subs w1,w1,#1
+
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v6.16b,v6.16b,v1.16b
+ eor v3.16b,v3.16b,v5.16b
+ shl v1.16b,v1.16b,#1
+ eor v3.16b,v3.16b,v6.16b
+ b.ne .Loop128
+
+ ld1 {v1.4s},[x3]
+
+ tbl v6.16b,{v3.16b},v2.16b
+ ext v5.16b,v0.16b,v3.16b,#12
+ st1 {v3.4s},[x2],#16
+ aese v6.16b,v0.16b
+
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v6.16b,v6.16b,v1.16b
+ eor v3.16b,v3.16b,v5.16b
+ shl v1.16b,v1.16b,#1
+ eor v3.16b,v3.16b,v6.16b
+
+ tbl v6.16b,{v3.16b},v2.16b
+ ext v5.16b,v0.16b,v3.16b,#12
+ st1 {v3.4s},[x2],#16
+ aese v6.16b,v0.16b
+
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v6.16b,v6.16b,v1.16b
+ eor v3.16b,v3.16b,v5.16b
+ eor v3.16b,v3.16b,v6.16b
+ st1 {v3.4s},[x2]
+ add x2,x2,#0x50
+
+ mov w12,#10
+ b .Ldone
+
+.align 4
+.L192:
+ ld1 {v4.8b},[x0],#8
+ movi v6.16b,#8 // borrow v6.16b
+ st1 {v3.4s},[x2],#16
+ sub v2.16b,v2.16b,v6.16b // adjust the mask
+
+.Loop192:
+ tbl v6.16b,{v4.16b},v2.16b
+ ext v5.16b,v0.16b,v3.16b,#12
+#ifdef __AARCH64EB__
+ st1 {v4.4s},[x2],#16
+ sub x2,x2,#8
+#else
+ st1 {v4.8b},[x2],#8
+#endif
+ aese v6.16b,v0.16b
+ subs w1,w1,#1
+
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+
+ dup v5.4s,v3.s[3]
+ eor v5.16b,v5.16b,v4.16b
+ eor v6.16b,v6.16b,v1.16b
+ ext v4.16b,v0.16b,v4.16b,#12
+ shl v1.16b,v1.16b,#1
+ eor v4.16b,v4.16b,v5.16b
+ eor v3.16b,v3.16b,v6.16b
+ eor v4.16b,v4.16b,v6.16b
+ st1 {v3.4s},[x2],#16
+ b.ne .Loop192
+
+ mov w12,#12
+ add x2,x2,#0x20
+ b .Ldone
+
+.align 4
+.L256:
+ ld1 {v4.16b},[x0]
+ mov w1,#7
+ mov w12,#14
+ st1 {v3.4s},[x2],#16
+
+.Loop256:
+ tbl v6.16b,{v4.16b},v2.16b
+ ext v5.16b,v0.16b,v3.16b,#12
+ st1 {v4.4s},[x2],#16
+ aese v6.16b,v0.16b
+ subs w1,w1,#1
+
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v6.16b,v6.16b,v1.16b
+ eor v3.16b,v3.16b,v5.16b
+ shl v1.16b,v1.16b,#1
+ eor v3.16b,v3.16b,v6.16b
+ st1 {v3.4s},[x2],#16
+ b.eq .Ldone
+
+ dup v6.4s,v3.s[3] // just splat
+ ext v5.16b,v0.16b,v4.16b,#12
+ aese v6.16b,v0.16b
+
+ eor v4.16b,v4.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v4.16b,v4.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v4.16b,v4.16b,v5.16b
+
+ eor v4.16b,v4.16b,v6.16b
+ b .Loop256
+
+.Ldone:
+ str w12,[x2]
+ mov x3,#0
+
+.Lenc_key_abort:
+ mov x0,x3 // return value
+ ldr x29,[sp],#16
+ ret
+.size aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key
+
+.globl aes_v8_set_decrypt_key
+.type aes_v8_set_decrypt_key,%function
+.align 5
+aes_v8_set_decrypt_key:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ bl .Lenc_key
+
+ cmp x0,#0
+ b.ne .Ldec_key_abort
+
+ sub x2,x2,#240 // restore original x2
+ mov x4,#-16
+ add x0,x2,x12,lsl#4 // end of key schedule
+
+ ld1 {v0.4s},[x2]
+ ld1 {v1.4s},[x0]
+ st1 {v0.4s},[x0],x4
+ st1 {v1.4s},[x2],#16
+
+.Loop_imc:
+ ld1 {v0.4s},[x2]
+ ld1 {v1.4s},[x0]
+ aesimc v0.16b,v0.16b
+ aesimc v1.16b,v1.16b
+ st1 {v0.4s},[x0],x4
+ st1 {v1.4s},[x2],#16
+ cmp x0,x2
+ b.hi .Loop_imc
+
+ ld1 {v0.4s},[x2]
+ aesimc v0.16b,v0.16b
+ st1 {v0.4s},[x0]
+
+ eor x0,x0,x0 // return value
+.Ldec_key_abort:
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key
+.globl aes_v8_encrypt
+.type aes_v8_encrypt,%function
+.align 5
+aes_v8_encrypt:
+ ldr w3,[x2,#240]
+ ld1 {v0.4s},[x2],#16
+ ld1 {v2.16b},[x0]
+ sub w3,w3,#2
+ ld1 {v1.4s},[x2],#16
+
+.Loop_enc:
+ aese v2.16b,v0.16b
+ aesmc v2.16b,v2.16b
+ ld1 {v0.4s},[x2],#16
+ subs w3,w3,#2
+ aese v2.16b,v1.16b
+ aesmc v2.16b,v2.16b
+ ld1 {v1.4s},[x2],#16
+ b.gt .Loop_enc
+
+ aese v2.16b,v0.16b
+ aesmc v2.16b,v2.16b
+ ld1 {v0.4s},[x2]
+ aese v2.16b,v1.16b
+ eor v2.16b,v2.16b,v0.16b
+
+ st1 {v2.16b},[x1]
+ ret
+.size aes_v8_encrypt,.-aes_v8_encrypt
+.globl aes_v8_decrypt
+.type aes_v8_decrypt,%function
+.align 5
+aes_v8_decrypt:
+ ldr w3,[x2,#240]
+ ld1 {v0.4s},[x2],#16
+ ld1 {v2.16b},[x0]
+ sub w3,w3,#2
+ ld1 {v1.4s},[x2],#16
+
+.Loop_dec:
+ aesd v2.16b,v0.16b
+ aesimc v2.16b,v2.16b
+ ld1 {v0.4s},[x2],#16
+ subs w3,w3,#2
+ aesd v2.16b,v1.16b
+ aesimc v2.16b,v2.16b
+ ld1 {v1.4s},[x2],#16
+ b.gt .Loop_dec
+
+ aesd v2.16b,v0.16b
+ aesimc v2.16b,v2.16b
+ ld1 {v0.4s},[x2]
+ aesd v2.16b,v1.16b
+ eor v2.16b,v2.16b,v0.16b
+
+ st1 {v2.16b},[x1]
+ ret
+.size aes_v8_decrypt,.-aes_v8_decrypt
+.globl aes_v8_ecb_encrypt
+.type aes_v8_ecb_encrypt,%function
+.align 5
+aes_v8_ecb_encrypt:
+ subs x2,x2,#16
+ // Original input data size bigger than 16, jump to big size processing.
+ b.ne .Lecb_big_size
+ ld1 {v0.16b},[x0]
+ cmp w4,#0 // en- or decrypting?
+ ldr w5,[x3,#240]
+ ld1 {v5.4s,v6.4s},[x3],#32 // load key schedule...
+
+ b.eq .Lecb_small_dec
+ aese v0.16b,v5.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule...
+ aese v0.16b,v6.16b
+ aesmc v0.16b,v0.16b
+ subs w5,w5,#10 // if rounds==10, jump to aes-128-ecb processing
+ b.eq .Lecb_128_enc
+.Lecb_round_loop:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.4s},[x3],#16 // load key schedule...
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v17.4s},[x3],#16 // load key schedule...
+ subs w5,w5,#2 // bias
+ b.gt .Lecb_round_loop
+.Lecb_128_enc:
+ ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule...
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule...
+ aese v0.16b,v18.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v19.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule...
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v7.4s},[x3]
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v23.16b
+ eor v0.16b,v0.16b,v7.16b
+ st1 {v0.16b},[x1]
+ b .Lecb_Final_abort
+.Lecb_small_dec:
+ aesd v0.16b,v5.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule...
+ aesd v0.16b,v6.16b
+ aesimc v0.16b,v0.16b
+ subs w5,w5,#10 // bias
+ b.eq .Lecb_128_dec
+.Lecb_dec_round_loop:
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v16.4s},[x3],#16 // load key schedule...
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v17.4s},[x3],#16 // load key schedule...
+ subs w5,w5,#2 // bias
+ b.gt .Lecb_dec_round_loop
+.Lecb_128_dec:
+ ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule...
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule...
+ aesd v0.16b,v18.16b
+ aesimc v0.16b,v0.16b
+ aesd v0.16b,v19.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule...
+ aesd v0.16b,v20.16b
+ aesimc v0.16b,v0.16b
+ aesd v0.16b,v21.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v7.4s},[x3]
+ aesd v0.16b,v22.16b
+ aesimc v0.16b,v0.16b
+ aesd v0.16b,v23.16b
+ eor v0.16b,v0.16b,v7.16b
+ st1 {v0.16b},[x1]
+ b .Lecb_Final_abort
+.Lecb_big_size:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ mov x8,#16
+ b.lo .Lecb_done
+ csel x8,xzr,x8,eq
+
+ cmp w4,#0 // en- or decrypting?
+ ldr w5,[x3,#240]
+ and x2,x2,#-16
+ ld1 {v0.16b},[x0],x8
+
+ ld1 {v16.4s,v17.4s},[x3] // load key schedule...
+ sub w5,w5,#6
+ add x7,x3,x5,lsl#4 // pointer to last 7 round keys
+ sub w5,w5,#2
+ ld1 {v18.4s,v19.4s},[x7],#32
+ ld1 {v20.4s,v21.4s},[x7],#32
+ ld1 {v22.4s,v23.4s},[x7],#32
+ ld1 {v7.4s},[x7]
+
+ add x7,x3,#32
+ mov w6,w5
+ b.eq .Lecb_dec
+
+ ld1 {v1.16b},[x0],#16
+ subs x2,x2,#32 // bias
+ add w6,w5,#2
+ orr v3.16b,v1.16b,v1.16b
+ orr v24.16b,v1.16b,v1.16b
+ orr v1.16b,v0.16b,v0.16b
+ b.lo .Lecb_enc_tail
+
+ orr v1.16b,v3.16b,v3.16b
+ ld1 {v24.16b},[x0],#16
+ cmp x2,#32
+ b.lo .Loop3x_ecb_enc
+
+ ld1 {v25.16b},[x0],#16
+ ld1 {v26.16b},[x0],#16
+ sub x2,x2,#32 // bias
+ mov w6,w5
+
+.Loop5x_ecb_enc:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v16.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v16.16b
+ aesmc v26.16b,v26.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v17.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v17.16b
+ aesmc v26.16b,v26.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Loop5x_ecb_enc
+
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v16.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v16.16b
+ aesmc v26.16b,v26.16b
+ cmp x2,#0x40 // because .Lecb_enc_tail4x
+ sub x2,x2,#0x50
+
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v17.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v17.16b
+ aesmc v26.16b,v26.16b
+ csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo
+ mov x7,x3
+
+ aese v0.16b,v18.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v18.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v18.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v18.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v18.16b
+ aesmc v26.16b,v26.16b
+ add x0,x0,x6 // x0 is adjusted in such way that
+ // at exit from the loop v1.16b-v26.16b
+ // are loaded with last "words"
+ add x6,x2,#0x60 // because .Lecb_enc_tail4x
+
+ aese v0.16b,v19.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v19.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v19.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v19.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v19.16b
+ aesmc v26.16b,v26.16b
+
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v20.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v20.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v20.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v20.16b
+ aesmc v26.16b,v26.16b
+
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v21.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v21.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v21.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v21.16b
+ aesmc v26.16b,v26.16b
+
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v22.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v22.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v22.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v22.16b
+ aesmc v26.16b,v26.16b
+
+ aese v0.16b,v23.16b
+ ld1 {v2.16b},[x0],#16
+ aese v1.16b,v23.16b
+ ld1 {v3.16b},[x0],#16
+ aese v24.16b,v23.16b
+ ld1 {v27.16b},[x0],#16
+ aese v25.16b,v23.16b
+ ld1 {v28.16b},[x0],#16
+ aese v26.16b,v23.16b
+ ld1 {v29.16b},[x0],#16
+ cbz x6,.Lecb_enc_tail4x
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ eor v4.16b,v7.16b,v0.16b
+ orr v0.16b,v2.16b,v2.16b
+ eor v5.16b,v7.16b,v1.16b
+ orr v1.16b,v3.16b,v3.16b
+ eor v17.16b,v7.16b,v24.16b
+ orr v24.16b,v27.16b,v27.16b
+ eor v30.16b,v7.16b,v25.16b
+ orr v25.16b,v28.16b,v28.16b
+ eor v31.16b,v7.16b,v26.16b
+ st1 {v4.16b},[x1],#16
+ orr v26.16b,v29.16b,v29.16b
+ st1 {v5.16b},[x1],#16
+ mov w6,w5
+ st1 {v17.16b},[x1],#16
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v30.16b},[x1],#16
+ st1 {v31.16b},[x1],#16
+ b.hs .Loop5x_ecb_enc
+
+ add x2,x2,#0x50
+ cbz x2,.Lecb_done
+
+ add w6,w5,#2
+ subs x2,x2,#0x30
+ orr v0.16b,v27.16b,v27.16b
+ orr v1.16b,v28.16b,v28.16b
+ orr v24.16b,v29.16b,v29.16b
+ b.lo .Lecb_enc_tail
+
+ b .Loop3x_ecb_enc
+
+.align 4
+.Lecb_enc_tail4x:
+ eor v5.16b,v7.16b,v1.16b
+ eor v17.16b,v7.16b,v24.16b
+ eor v30.16b,v7.16b,v25.16b
+ eor v31.16b,v7.16b,v26.16b
+ st1 {v5.16b},[x1],#16
+ st1 {v17.16b},[x1],#16
+ st1 {v30.16b},[x1],#16
+ st1 {v31.16b},[x1],#16
+
+ b .Lecb_done
+.align 4
+.Loop3x_ecb_enc:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Loop3x_ecb_enc
+
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ subs x2,x2,#0x30
+ csel x6,x2,x6,lo // x6, w6, is zero at this point
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ add x0,x0,x6 // x0 is adjusted in such way that
+ // at exit from the loop v1.16b-v24.16b
+ // are loaded with last "words"
+ mov x7,x3
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v20.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v20.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v2.16b},[x0],#16
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v21.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v21.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v3.16b},[x0],#16
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v22.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v22.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v27.16b},[x0],#16
+ aese v0.16b,v23.16b
+ aese v1.16b,v23.16b
+ aese v24.16b,v23.16b
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ add w6,w5,#2
+ eor v4.16b,v7.16b,v0.16b
+ eor v5.16b,v7.16b,v1.16b
+ eor v24.16b,v24.16b,v7.16b
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v4.16b},[x1],#16
+ orr v0.16b,v2.16b,v2.16b
+ st1 {v5.16b},[x1],#16
+ orr v1.16b,v3.16b,v3.16b
+ st1 {v24.16b},[x1],#16
+ orr v24.16b,v27.16b,v27.16b
+ b.hs .Loop3x_ecb_enc
+
+ cmn x2,#0x30
+ b.eq .Lecb_done
+ nop
+
+.Lecb_enc_tail:
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Lecb_enc_tail
+
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ aese v1.16b,v20.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v20.16b
+ aesmc v24.16b,v24.16b
+ cmn x2,#0x20
+ aese v1.16b,v21.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v21.16b
+ aesmc v24.16b,v24.16b
+ aese v1.16b,v22.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v22.16b
+ aesmc v24.16b,v24.16b
+ aese v1.16b,v23.16b
+ aese v24.16b,v23.16b
+ b.eq .Lecb_enc_one
+ eor v5.16b,v7.16b,v1.16b
+ eor v17.16b,v7.16b,v24.16b
+ st1 {v5.16b},[x1],#16
+ st1 {v17.16b},[x1],#16
+ b .Lecb_done
+
+.Lecb_enc_one:
+ eor v5.16b,v7.16b,v24.16b
+ st1 {v5.16b},[x1],#16
+ b .Lecb_done
+.align 5
+.Lecb_dec:
+ ld1 {v1.16b},[x0],#16
+ subs x2,x2,#32 // bias
+ add w6,w5,#2
+ orr v3.16b,v1.16b,v1.16b
+ orr v24.16b,v1.16b,v1.16b
+ orr v1.16b,v0.16b,v0.16b
+ b.lo .Lecb_dec_tail
+
+ orr v1.16b,v3.16b,v3.16b
+ ld1 {v24.16b},[x0],#16
+ cmp x2,#32
+ b.lo .Loop3x_ecb_dec
+
+ ld1 {v25.16b},[x0],#16
+ ld1 {v26.16b},[x0],#16
+ sub x2,x2,#32 // bias
+ mov w6,w5
+
+.Loop5x_ecb_dec:
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v16.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v16.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v17.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v17.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Loop5x_ecb_dec
+
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v16.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v16.16b
+ aesimc v26.16b,v26.16b
+ cmp x2,#0x40 // because .Lecb_tail4x
+ sub x2,x2,#0x50
+
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v17.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v17.16b
+ aesimc v26.16b,v26.16b
+ csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo
+ mov x7,x3
+
+ aesd v0.16b,v18.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v18.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v18.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v18.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v18.16b
+ aesimc v26.16b,v26.16b
+ add x0,x0,x6 // x0 is adjusted in such way that
+ // at exit from the loop v1.16b-v26.16b
+ // are loaded with last "words"
+ add x6,x2,#0x60 // because .Lecb_tail4x
+
+ aesd v0.16b,v19.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v19.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v19.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v19.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v19.16b
+ aesimc v26.16b,v26.16b
+
+ aesd v0.16b,v20.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v20.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v20.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v20.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v20.16b
+ aesimc v26.16b,v26.16b
+
+ aesd v0.16b,v21.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v21.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v21.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v21.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v21.16b
+ aesimc v26.16b,v26.16b
+
+ aesd v0.16b,v22.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v22.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v22.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v22.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v22.16b
+ aesimc v26.16b,v26.16b
+
+ aesd v0.16b,v23.16b
+ ld1 {v2.16b},[x0],#16
+ aesd v1.16b,v23.16b
+ ld1 {v3.16b},[x0],#16
+ aesd v24.16b,v23.16b
+ ld1 {v27.16b},[x0],#16
+ aesd v25.16b,v23.16b
+ ld1 {v28.16b},[x0],#16
+ aesd v26.16b,v23.16b
+ ld1 {v29.16b},[x0],#16
+ cbz x6,.Lecb_tail4x
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ eor v4.16b,v7.16b,v0.16b
+ orr v0.16b,v2.16b,v2.16b
+ eor v5.16b,v7.16b,v1.16b
+ orr v1.16b,v3.16b,v3.16b
+ eor v17.16b,v7.16b,v24.16b
+ orr v24.16b,v27.16b,v27.16b
+ eor v30.16b,v7.16b,v25.16b
+ orr v25.16b,v28.16b,v28.16b
+ eor v31.16b,v7.16b,v26.16b
+ st1 {v4.16b},[x1],#16
+ orr v26.16b,v29.16b,v29.16b
+ st1 {v5.16b},[x1],#16
+ mov w6,w5
+ st1 {v17.16b},[x1],#16
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v30.16b},[x1],#16
+ st1 {v31.16b},[x1],#16
+ b.hs .Loop5x_ecb_dec
+
+ add x2,x2,#0x50
+ cbz x2,.Lecb_done
+
+ add w6,w5,#2
+ subs x2,x2,#0x30
+ orr v0.16b,v27.16b,v27.16b
+ orr v1.16b,v28.16b,v28.16b
+ orr v24.16b,v29.16b,v29.16b
+ b.lo .Lecb_dec_tail
+
+ b .Loop3x_ecb_dec
+
+.align 4
+.Lecb_tail4x:
+ eor v5.16b,v7.16b,v1.16b
+ eor v17.16b,v7.16b,v24.16b
+ eor v30.16b,v7.16b,v25.16b
+ eor v31.16b,v7.16b,v26.16b
+ st1 {v5.16b},[x1],#16
+ st1 {v17.16b},[x1],#16
+ st1 {v30.16b},[x1],#16
+ st1 {v31.16b},[x1],#16
+
+ b .Lecb_done
+.align 4
+.Loop3x_ecb_dec:
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Loop3x_ecb_dec
+
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ subs x2,x2,#0x30
+ csel x6,x2,x6,lo // x6, w6, is zero at this point
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ add x0,x0,x6 // x0 is adjusted in such way that
+ // at exit from the loop v1.16b-v24.16b
+ // are loaded with last "words"
+ mov x7,x3
+ aesd v0.16b,v20.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v20.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v20.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v2.16b},[x0],#16
+ aesd v0.16b,v21.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v21.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v21.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v3.16b},[x0],#16
+ aesd v0.16b,v22.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v22.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v22.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v27.16b},[x0],#16
+ aesd v0.16b,v23.16b
+ aesd v1.16b,v23.16b
+ aesd v24.16b,v23.16b
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ add w6,w5,#2
+ eor v4.16b,v7.16b,v0.16b
+ eor v5.16b,v7.16b,v1.16b
+ eor v24.16b,v24.16b,v7.16b
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v4.16b},[x1],#16
+ orr v0.16b,v2.16b,v2.16b
+ st1 {v5.16b},[x1],#16
+ orr v1.16b,v3.16b,v3.16b
+ st1 {v24.16b},[x1],#16
+ orr v24.16b,v27.16b,v27.16b
+ b.hs .Loop3x_ecb_dec
+
+ cmn x2,#0x30
+ b.eq .Lecb_done
+ nop
+
+.Lecb_dec_tail:
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Lecb_dec_tail
+
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ aesd v1.16b,v20.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v20.16b
+ aesimc v24.16b,v24.16b
+ cmn x2,#0x20
+ aesd v1.16b,v21.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v21.16b
+ aesimc v24.16b,v24.16b
+ aesd v1.16b,v22.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v22.16b
+ aesimc v24.16b,v24.16b
+ aesd v1.16b,v23.16b
+ aesd v24.16b,v23.16b
+ b.eq .Lecb_dec_one
+ eor v5.16b,v7.16b,v1.16b
+ eor v17.16b,v7.16b,v24.16b
+ st1 {v5.16b},[x1],#16
+ st1 {v17.16b},[x1],#16
+ b .Lecb_done
+
+.Lecb_dec_one:
+ eor v5.16b,v7.16b,v24.16b
+ st1 {v5.16b},[x1],#16
+
+.Lecb_done:
+ ldr x29,[sp],#16
+.Lecb_Final_abort:
+ ret
+.size aes_v8_ecb_encrypt,.-aes_v8_ecb_encrypt
+.globl aes_v8_cbc_encrypt
+.type aes_v8_cbc_encrypt,%function
+.align 5
+aes_v8_cbc_encrypt:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ subs x2,x2,#16
+ mov x8,#16
+ b.lo .Lcbc_abort
+ csel x8,xzr,x8,eq
+
+ cmp w5,#0 // en- or decrypting?
+ ldr w5,[x3,#240]
+ and x2,x2,#-16
+ ld1 {v6.16b},[x4]
+ ld1 {v0.16b},[x0],x8
+
+ ld1 {v16.4s,v17.4s},[x3] // load key schedule...
+ sub w5,w5,#6
+ add x7,x3,x5,lsl#4 // pointer to last 7 round keys
+ sub w5,w5,#2
+ ld1 {v18.4s,v19.4s},[x7],#32
+ ld1 {v20.4s,v21.4s},[x7],#32
+ ld1 {v22.4s,v23.4s},[x7],#32
+ ld1 {v7.4s},[x7]
+
+ add x7,x3,#32
+ mov w6,w5
+ b.eq .Lcbc_dec
+
+ cmp w5,#2
+ eor v0.16b,v0.16b,v6.16b
+ eor v5.16b,v16.16b,v7.16b
+ b.eq .Lcbc_enc128
+
+ ld1 {v2.4s,v3.4s},[x7]
+ add x7,x3,#16
+ add x6,x3,#16*4
+ add x12,x3,#16*5
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ add x14,x3,#16*6
+ add x3,x3,#16*7
+ b .Lenter_cbc_enc
+
+.align 4
+.Loop_cbc_enc:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ st1 {v6.16b},[x1],#16
+.Lenter_cbc_enc:
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v2.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.4s},[x6]
+ cmp w5,#4
+ aese v0.16b,v3.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v17.4s},[x12]
+ b.eq .Lcbc_enc192
+
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.4s},[x14]
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v17.4s},[x3]
+ nop
+
+.Lcbc_enc192:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ subs x2,x2,#16
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ csel x8,xzr,x8,eq
+ aese v0.16b,v18.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v19.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.16b},[x0],x8
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ eor v16.16b,v16.16b,v5.16b
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v17.4s},[x7] // re-pre-load rndkey[1]
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v23.16b
+ eor v6.16b,v0.16b,v7.16b
+ b.hs .Loop_cbc_enc
+
+ st1 {v6.16b},[x1],#16
+ b .Lcbc_done
+
+.align 5
+.Lcbc_enc128:
+ ld1 {v2.4s,v3.4s},[x7]
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ b .Lenter_cbc_enc128
+.Loop_cbc_enc128:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ st1 {v6.16b},[x1],#16
+.Lenter_cbc_enc128:
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ subs x2,x2,#16
+ aese v0.16b,v2.16b
+ aesmc v0.16b,v0.16b
+ csel x8,xzr,x8,eq
+ aese v0.16b,v3.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v18.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v19.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.16b},[x0],x8
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ eor v16.16b,v16.16b,v5.16b
+ aese v0.16b,v23.16b
+ eor v6.16b,v0.16b,v7.16b
+ b.hs .Loop_cbc_enc128
+
+ st1 {v6.16b},[x1],#16
+ b .Lcbc_done
+.align 5
+.Lcbc_dec:
+ ld1 {v24.16b},[x0],#16
+ subs x2,x2,#32 // bias
+ add w6,w5,#2
+ orr v3.16b,v0.16b,v0.16b
+ orr v1.16b,v0.16b,v0.16b
+ orr v27.16b,v24.16b,v24.16b
+ b.lo .Lcbc_dec_tail
+
+ orr v1.16b,v24.16b,v24.16b
+ ld1 {v24.16b},[x0],#16
+ orr v2.16b,v0.16b,v0.16b
+ orr v3.16b,v1.16b,v1.16b
+ orr v27.16b,v24.16b,v24.16b
+ cmp x2,#32
+ b.lo .Loop3x_cbc_dec
+
+ ld1 {v25.16b},[x0],#16
+ ld1 {v26.16b},[x0],#16
+ sub x2,x2,#32 // bias
+ mov w6,w5
+ orr v28.16b,v25.16b,v25.16b
+ orr v29.16b,v26.16b,v26.16b
+
+.Loop5x_cbc_dec:
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v16.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v16.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v17.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v17.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Loop5x_cbc_dec
+
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v16.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v16.16b
+ aesimc v26.16b,v26.16b
+ cmp x2,#0x40 // because .Lcbc_tail4x
+ sub x2,x2,#0x50
+
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v17.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v17.16b
+ aesimc v26.16b,v26.16b
+ csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo
+ mov x7,x3
+
+ aesd v0.16b,v18.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v18.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v18.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v18.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v18.16b
+ aesimc v26.16b,v26.16b
+ add x0,x0,x6 // x0 is adjusted in such way that
+ // at exit from the loop v1.16b-v26.16b
+ // are loaded with last "words"
+ add x6,x2,#0x60 // because .Lcbc_tail4x
+
+ aesd v0.16b,v19.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v19.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v19.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v19.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v19.16b
+ aesimc v26.16b,v26.16b
+
+ aesd v0.16b,v20.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v20.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v20.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v20.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v20.16b
+ aesimc v26.16b,v26.16b
+
+ aesd v0.16b,v21.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v21.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v21.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v21.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v21.16b
+ aesimc v26.16b,v26.16b
+
+ aesd v0.16b,v22.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v22.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v22.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v22.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v22.16b
+ aesimc v26.16b,v26.16b
+
+ eor v4.16b,v6.16b,v7.16b
+ aesd v0.16b,v23.16b
+ eor v5.16b,v2.16b,v7.16b
+ ld1 {v2.16b},[x0],#16
+ aesd v1.16b,v23.16b
+ eor v17.16b,v3.16b,v7.16b
+ ld1 {v3.16b},[x0],#16
+ aesd v24.16b,v23.16b
+ eor v30.16b,v27.16b,v7.16b
+ ld1 {v27.16b},[x0],#16
+ aesd v25.16b,v23.16b
+ eor v31.16b,v28.16b,v7.16b
+ ld1 {v28.16b},[x0],#16
+ aesd v26.16b,v23.16b
+ orr v6.16b,v29.16b,v29.16b
+ ld1 {v29.16b},[x0],#16
+ cbz x6,.Lcbc_tail4x
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ eor v4.16b,v4.16b,v0.16b
+ orr v0.16b,v2.16b,v2.16b
+ eor v5.16b,v5.16b,v1.16b
+ orr v1.16b,v3.16b,v3.16b
+ eor v17.16b,v17.16b,v24.16b
+ orr v24.16b,v27.16b,v27.16b
+ eor v30.16b,v30.16b,v25.16b
+ orr v25.16b,v28.16b,v28.16b
+ eor v31.16b,v31.16b,v26.16b
+ st1 {v4.16b},[x1],#16
+ orr v26.16b,v29.16b,v29.16b
+ st1 {v5.16b},[x1],#16
+ mov w6,w5
+ st1 {v17.16b},[x1],#16
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v30.16b},[x1],#16
+ st1 {v31.16b},[x1],#16
+ b.hs .Loop5x_cbc_dec
+
+ add x2,x2,#0x50
+ cbz x2,.Lcbc_done
+
+ add w6,w5,#2
+ subs x2,x2,#0x30
+ orr v0.16b,v27.16b,v27.16b
+ orr v2.16b,v27.16b,v27.16b
+ orr v1.16b,v28.16b,v28.16b
+ orr v3.16b,v28.16b,v28.16b
+ orr v24.16b,v29.16b,v29.16b
+ orr v27.16b,v29.16b,v29.16b
+ b.lo .Lcbc_dec_tail
+
+ b .Loop3x_cbc_dec
+
+.align 4
+.Lcbc_tail4x:
+ eor v5.16b,v4.16b,v1.16b
+ eor v17.16b,v17.16b,v24.16b
+ eor v30.16b,v30.16b,v25.16b
+ eor v31.16b,v31.16b,v26.16b
+ st1 {v5.16b},[x1],#16
+ st1 {v17.16b},[x1],#16
+ st1 {v30.16b},[x1],#16
+ st1 {v31.16b},[x1],#16
+
+ b .Lcbc_done
+.align 4
+.Loop3x_cbc_dec:
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Loop3x_cbc_dec
+
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ eor v4.16b,v6.16b,v7.16b
+ subs x2,x2,#0x30
+ eor v5.16b,v2.16b,v7.16b
+ csel x6,x2,x6,lo // x6, w6, is zero at this point
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ eor v17.16b,v3.16b,v7.16b
+ add x0,x0,x6 // x0 is adjusted in such way that
+ // at exit from the loop v1.16b-v24.16b
+ // are loaded with last "words"
+ orr v6.16b,v27.16b,v27.16b
+ mov x7,x3
+ aesd v0.16b,v20.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v20.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v20.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v2.16b},[x0],#16
+ aesd v0.16b,v21.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v21.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v21.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v3.16b},[x0],#16
+ aesd v0.16b,v22.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v22.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v22.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v27.16b},[x0],#16
+ aesd v0.16b,v23.16b
+ aesd v1.16b,v23.16b
+ aesd v24.16b,v23.16b
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ add w6,w5,#2
+ eor v4.16b,v4.16b,v0.16b
+ eor v5.16b,v5.16b,v1.16b
+ eor v24.16b,v24.16b,v17.16b
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v4.16b},[x1],#16
+ orr v0.16b,v2.16b,v2.16b
+ st1 {v5.16b},[x1],#16
+ orr v1.16b,v3.16b,v3.16b
+ st1 {v24.16b},[x1],#16
+ orr v24.16b,v27.16b,v27.16b
+ b.hs .Loop3x_cbc_dec
+
+ cmn x2,#0x30
+ b.eq .Lcbc_done
+ nop
+
+.Lcbc_dec_tail:
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Lcbc_dec_tail
+
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ aesd v1.16b,v20.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v20.16b
+ aesimc v24.16b,v24.16b
+ cmn x2,#0x20
+ aesd v1.16b,v21.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v21.16b
+ aesimc v24.16b,v24.16b
+ eor v5.16b,v6.16b,v7.16b
+ aesd v1.16b,v22.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v22.16b
+ aesimc v24.16b,v24.16b
+ eor v17.16b,v3.16b,v7.16b
+ aesd v1.16b,v23.16b
+ aesd v24.16b,v23.16b
+ b.eq .Lcbc_dec_one
+ eor v5.16b,v5.16b,v1.16b
+ eor v17.16b,v17.16b,v24.16b
+ orr v6.16b,v27.16b,v27.16b
+ st1 {v5.16b},[x1],#16
+ st1 {v17.16b},[x1],#16
+ b .Lcbc_done
+
+.Lcbc_dec_one:
+ eor v5.16b,v5.16b,v24.16b
+ orr v6.16b,v27.16b,v27.16b
+ st1 {v5.16b},[x1],#16
+
+.Lcbc_done:
+ st1 {v6.16b},[x4]
+.Lcbc_abort:
+ ldr x29,[sp],#16
+ ret
+.size aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt
+.globl aes_v8_ctr32_encrypt_blocks
+.type aes_v8_ctr32_encrypt_blocks,%function
+.align 5
+aes_v8_ctr32_encrypt_blocks:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ ldr w5,[x3,#240]
+
+ ldr w8, [x4, #12]
+#ifdef __AARCH64EB__
+ ld1 {v0.16b},[x4]
+#else
+ ld1 {v0.4s},[x4]
+#endif
+ ld1 {v16.4s,v17.4s},[x3] // load key schedule...
+ sub w5,w5,#4
+ mov x12,#16
+ cmp x2,#2
+ add x7,x3,x5,lsl#4 // pointer to last 5 round keys
+ sub w5,w5,#2
+ ld1 {v20.4s,v21.4s},[x7],#32
+ ld1 {v22.4s,v23.4s},[x7],#32
+ ld1 {v7.4s},[x7]
+ add x7,x3,#32
+ mov w6,w5
+ csel x12,xzr,x12,lo
+#ifndef __AARCH64EB__
+ rev w8, w8
+#endif
+ orr v1.16b,v0.16b,v0.16b
+ add w10, w8, #1
+ orr v18.16b,v0.16b,v0.16b
+ add w8, w8, #2
+ orr v6.16b,v0.16b,v0.16b
+ rev w10, w10
+ mov v1.s[3],w10
+ b.ls .Lctr32_tail
+ rev w12, w8
+ sub x2,x2,#3 // bias
+ mov v18.s[3],w12
+ cmp x2,#32
+ b.lo .Loop3x_ctr32
+
+ add w13,w8,#1
+ add w14,w8,#2
+ orr v24.16b,v0.16b,v0.16b
+ rev w13,w13
+ orr v25.16b,v0.16b,v0.16b
+ rev w14,w14
+ mov v24.s[3],w13
+ sub x2,x2,#2 // bias
+ mov v25.s[3],w14
+ add w8,w8,#2
+ b .Loop5x_ctr32
+
+.align 4
+.Loop5x_ctr32:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v18.16b,v16.16b
+ aesmc v18.16b,v18.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v16.16b
+ aesmc v25.16b,v25.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v18.16b,v17.16b
+ aesmc v18.16b,v18.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v17.16b
+ aesmc v25.16b,v25.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Loop5x_ctr32
+
+ mov x7,x3
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v18.16b,v16.16b
+ aesmc v18.16b,v18.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v16.16b
+ aesmc v25.16b,v25.16b
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v18.16b,v17.16b
+ aesmc v18.16b,v18.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v17.16b
+ aesmc v25.16b,v25.16b
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ add w9,w8,#1
+ add w10,w8,#2
+ aese v1.16b,v20.16b
+ aesmc v1.16b,v1.16b
+ add w12,w8,#3
+ add w13,w8,#4
+ aese v18.16b,v20.16b
+ aesmc v18.16b,v18.16b
+ add w14,w8,#5
+ rev w9,w9
+ aese v24.16b,v20.16b
+ aesmc v24.16b,v24.16b
+ rev w10,w10
+ rev w12,w12
+ aese v25.16b,v20.16b
+ aesmc v25.16b,v25.16b
+ rev w13,w13
+ rev w14,w14
+
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v21.16b
+ aesmc v1.16b,v1.16b
+ aese v18.16b,v21.16b
+ aesmc v18.16b,v18.16b
+ aese v24.16b,v21.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v21.16b
+ aesmc v25.16b,v25.16b
+
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v2.16b},[x0],#16
+ aese v1.16b,v22.16b
+ aesmc v1.16b,v1.16b
+ ld1 {v3.16b},[x0],#16
+ aese v18.16b,v22.16b
+ aesmc v18.16b,v18.16b
+ ld1 {v19.16b},[x0],#16
+ aese v24.16b,v22.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v26.16b},[x0],#16
+ aese v25.16b,v22.16b
+ aesmc v25.16b,v25.16b
+ ld1 {v27.16b},[x0],#16
+
+ aese v0.16b,v23.16b
+ eor v2.16b,v2.16b,v7.16b
+ aese v1.16b,v23.16b
+ eor v3.16b,v3.16b,v7.16b
+ aese v18.16b,v23.16b
+ eor v19.16b,v19.16b,v7.16b
+ aese v24.16b,v23.16b
+ eor v26.16b,v26.16b,v7.16b
+ aese v25.16b,v23.16b
+ eor v27.16b,v27.16b,v7.16b
+
+ eor v2.16b,v2.16b,v0.16b
+ orr v0.16b,v6.16b,v6.16b
+ eor v3.16b,v3.16b,v1.16b
+ orr v1.16b,v6.16b,v6.16b
+ eor v19.16b,v19.16b,v18.16b
+ orr v18.16b,v6.16b,v6.16b
+ eor v26.16b,v26.16b,v24.16b
+ orr v24.16b,v6.16b,v6.16b
+ eor v27.16b,v27.16b,v25.16b
+ orr v25.16b,v6.16b,v6.16b
+
+ st1 {v2.16b},[x1],#16
+ mov v0.s[3],w9
+ st1 {v3.16b},[x1],#16
+ mov v1.s[3],w10
+ st1 {v19.16b},[x1],#16
+ mov v18.s[3],w12
+ st1 {v26.16b},[x1],#16
+ mov v24.s[3],w13
+ st1 {v27.16b},[x1],#16
+ mov v25.s[3],w14
+
+ mov w6,w5
+ cbz x2,.Lctr32_done
+
+ add w8,w8,#5
+ subs x2,x2,#5
+ b.hs .Loop5x_ctr32
+
+ add x2,x2,#5
+ sub w8,w8,#5
+
+ cmp x2,#2
+ mov x12,#16
+ csel x12,xzr,x12,lo
+ b.ls .Lctr32_tail
+
+ sub x2,x2,#3 // bias
+ add w8,w8,#3
+ b .Loop3x_ctr32
+
+.align 4
+.Loop3x_ctr32:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v18.16b,v16.16b
+ aesmc v18.16b,v18.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v18.16b,v17.16b
+ aesmc v18.16b,v18.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Loop3x_ctr32
+
+ aese v0.16b,v16.16b
+ aesmc v4.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v5.16b,v1.16b
+ ld1 {v2.16b},[x0],#16
+ orr v0.16b,v6.16b,v6.16b
+ aese v18.16b,v16.16b
+ aesmc v18.16b,v18.16b
+ ld1 {v3.16b},[x0],#16
+ orr v1.16b,v6.16b,v6.16b
+ aese v4.16b,v17.16b
+ aesmc v4.16b,v4.16b
+ aese v5.16b,v17.16b
+ aesmc v5.16b,v5.16b
+ ld1 {v19.16b},[x0],#16
+ mov x7,x3
+ aese v18.16b,v17.16b
+ aesmc v17.16b,v18.16b
+ orr v18.16b,v6.16b,v6.16b
+ add w9,w8,#1
+ aese v4.16b,v20.16b
+ aesmc v4.16b,v4.16b
+ aese v5.16b,v20.16b
+ aesmc v5.16b,v5.16b
+ eor v2.16b,v2.16b,v7.16b
+ add w10,w8,#2
+ aese v17.16b,v20.16b
+ aesmc v17.16b,v17.16b
+ eor v3.16b,v3.16b,v7.16b
+ add w8,w8,#3
+ aese v4.16b,v21.16b
+ aesmc v4.16b,v4.16b
+ aese v5.16b,v21.16b
+ aesmc v5.16b,v5.16b
+ eor v19.16b,v19.16b,v7.16b
+ rev w9,w9
+ aese v17.16b,v21.16b
+ aesmc v17.16b,v17.16b
+ mov v0.s[3], w9
+ rev w10,w10
+ aese v4.16b,v22.16b
+ aesmc v4.16b,v4.16b
+ aese v5.16b,v22.16b
+ aesmc v5.16b,v5.16b
+ mov v1.s[3], w10
+ rev w12,w8
+ aese v17.16b,v22.16b
+ aesmc v17.16b,v17.16b
+ mov v18.s[3], w12
+ subs x2,x2,#3
+ aese v4.16b,v23.16b
+ aese v5.16b,v23.16b
+ aese v17.16b,v23.16b
+
+ eor v2.16b,v2.16b,v4.16b
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ st1 {v2.16b},[x1],#16
+ eor v3.16b,v3.16b,v5.16b
+ mov w6,w5
+ st1 {v3.16b},[x1],#16
+ eor v19.16b,v19.16b,v17.16b
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v19.16b},[x1],#16
+ b.hs .Loop3x_ctr32
+
+ adds x2,x2,#3
+ b.eq .Lctr32_done
+ cmp x2,#1
+ mov x12,#16
+ csel x12,xzr,x12,eq
+
+.Lctr32_tail:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Lctr32_tail
+
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ ld1 {v2.16b},[x0],x12
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v20.16b
+ aesmc v1.16b,v1.16b
+ ld1 {v3.16b},[x0]
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v21.16b
+ aesmc v1.16b,v1.16b
+ eor v2.16b,v2.16b,v7.16b
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v22.16b
+ aesmc v1.16b,v1.16b
+ eor v3.16b,v3.16b,v7.16b
+ aese v0.16b,v23.16b
+ aese v1.16b,v23.16b
+
+ cmp x2,#1
+ eor v2.16b,v2.16b,v0.16b
+ eor v3.16b,v3.16b,v1.16b
+ st1 {v2.16b},[x1],#16
+ b.eq .Lctr32_done
+ st1 {v3.16b},[x1]
+
+.Lctr32_done:
+ ldr x29,[sp],#16
+ ret
+.size aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks
+.globl aes_v8_xts_encrypt
+.type aes_v8_xts_encrypt,%function
+.align 5
+aes_v8_xts_encrypt:
+ cmp x2,#16
+ // Original input data size bigger than 16, jump to big size processing.
+ b.ne .Lxts_enc_big_size
+ // Encrypt the iv with key2, as the first XEX iv.
+ ldr w6,[x4,#240]
+ ld1 {v0.4s},[x4],#16
+ ld1 {v6.16b},[x5]
+ sub w6,w6,#2
+ ld1 {v1.4s},[x4],#16
+
+.Loop_enc_iv_enc:
+ aese v6.16b,v0.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v0.4s},[x4],#16
+ subs w6,w6,#2
+ aese v6.16b,v1.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v1.4s},[x4],#16
+ b.gt .Loop_enc_iv_enc
+
+ aese v6.16b,v0.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v0.4s},[x4]
+ aese v6.16b,v1.16b
+ eor v6.16b,v6.16b,v0.16b
+
+ ld1 {v0.16b},[x0]
+ eor v0.16b,v6.16b,v0.16b
+
+ ldr w6,[x3,#240]
+ ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule...
+
+ aese v0.16b,v28.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule...
+ aese v0.16b,v29.16b
+ aesmc v0.16b,v0.16b
+ subs w6,w6,#10 // if rounds==10, jump to aes-128-xts processing
+ b.eq .Lxts_128_enc
+.Lxts_enc_round_loop:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.4s},[x3],#16 // load key schedule...
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v17.4s},[x3],#16 // load key schedule...
+ subs w6,w6,#2 // bias
+ b.gt .Lxts_enc_round_loop
+.Lxts_128_enc:
+ ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule...
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule...
+ aese v0.16b,v18.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v19.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule...
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v7.4s},[x3]
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v23.16b
+ eor v0.16b,v0.16b,v7.16b
+ eor v0.16b,v0.16b,v6.16b
+ st1 {v0.16b},[x1]
+ b .Lxts_enc_final_abort
+
+.align 4
+.Lxts_enc_big_size:
+ stp x19,x20,[sp,#-64]!
+ stp x21,x22,[sp,#48]
+ stp d8,d9,[sp,#32]
+ stp d10,d11,[sp,#16]
+
+ // tailcnt store the tail value of length%16.
+ and x21,x2,#0xf
+ and x2,x2,#-16
+ subs x2,x2,#16
+ mov x8,#16
+ b.lo .Lxts_abort
+ csel x8,xzr,x8,eq
+
+ // Firstly, encrypt the iv with key2, as the first iv of XEX.
+ ldr w6,[x4,#240]
+ ld1 {v0.4s},[x4],#16
+ ld1 {v6.16b},[x5]
+ sub w6,w6,#2
+ ld1 {v1.4s},[x4],#16
+
+.Loop_iv_enc:
+ aese v6.16b,v0.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v0.4s},[x4],#16
+ subs w6,w6,#2
+ aese v6.16b,v1.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v1.4s},[x4],#16
+ b.gt .Loop_iv_enc
+
+ aese v6.16b,v0.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v0.4s},[x4]
+ aese v6.16b,v1.16b
+ eor v6.16b,v6.16b,v0.16b
+
+ // The iv for second block
+ // x9- iv(low), x10 - iv(high)
+ // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b
+ fmov x9,d6
+ fmov x10,v6.d[1]
+ mov w19,#0x87
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr#31
+ eor x9,x11,x9,lsl#1
+ fmov d8,x9
+ fmov v8.d[1],x10
+
+ ldr w5,[x3,#240] // next starting point
+ ld1 {v0.16b},[x0],x8
+
+ ld1 {v16.4s,v17.4s},[x3] // load key schedule...
+ sub w5,w5,#6
+ add x7,x3,x5,lsl#4 // pointer to last 7 round keys
+ sub w5,w5,#2
+ ld1 {v18.4s,v19.4s},[x7],#32
+ ld1 {v20.4s,v21.4s},[x7],#32
+ ld1 {v22.4s,v23.4s},[x7],#32
+ ld1 {v7.4s},[x7]
+
+ add x7,x3,#32
+ mov w6,w5
+
+ // Encryption
+.Lxts_enc:
+ ld1 {v24.16b},[x0],#16
+ subs x2,x2,#32 // bias
+ add w6,w5,#2
+ orr v3.16b,v0.16b,v0.16b
+ orr v1.16b,v0.16b,v0.16b
+ orr v28.16b,v0.16b,v0.16b
+ orr v27.16b,v24.16b,v24.16b
+ orr v29.16b,v24.16b,v24.16b
+ b.lo .Lxts_inner_enc_tail
+ eor v0.16b,v0.16b,v6.16b // before encryption, xor with iv
+ eor v24.16b,v24.16b,v8.16b
+
+ // The iv for third block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr#31
+ eor x9,x11,x9,lsl#1
+ fmov d9,x9
+ fmov v9.d[1],x10
+
+
+ orr v1.16b,v24.16b,v24.16b
+ ld1 {v24.16b},[x0],#16
+ orr v2.16b,v0.16b,v0.16b
+ orr v3.16b,v1.16b,v1.16b
+ eor v27.16b,v24.16b,v9.16b // the third block
+ eor v24.16b,v24.16b,v9.16b
+ cmp x2,#32
+ b.lo .Lxts_outer_enc_tail
+
+ // The iv for fourth block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr#31
+ eor x9,x11,x9,lsl#1
+ fmov d10,x9
+ fmov v10.d[1],x10
+
+ ld1 {v25.16b},[x0],#16
+ // The iv for fifth block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr#31
+ eor x9,x11,x9,lsl#1
+ fmov d11,x9
+ fmov v11.d[1],x10
+
+ ld1 {v26.16b},[x0],#16
+ eor v25.16b,v25.16b,v10.16b // the fourth block
+ eor v26.16b,v26.16b,v11.16b
+ sub x2,x2,#32 // bias
+ mov w6,w5
+ b .Loop5x_xts_enc
+
+.align 4
+.Loop5x_xts_enc:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v16.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v16.16b
+ aesmc v26.16b,v26.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v17.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v17.16b
+ aesmc v26.16b,v26.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Loop5x_xts_enc
+
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v16.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v16.16b
+ aesmc v26.16b,v26.16b
+ subs x2,x2,#0x50 // because .Lxts_enc_tail4x
+
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v17.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v17.16b
+ aesmc v26.16b,v26.16b
+ csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo
+ mov x7,x3
+
+ aese v0.16b,v18.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v18.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v18.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v18.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v18.16b
+ aesmc v26.16b,v26.16b
+ add x0,x0,x6 // x0 is adjusted in such way that
+ // at exit from the loop v1.16b-v26.16b
+ // are loaded with last "words"
+ add x6,x2,#0x60 // because .Lxts_enc_tail4x
+
+ aese v0.16b,v19.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v19.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v19.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v19.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v19.16b
+ aesmc v26.16b,v26.16b
+
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v20.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v20.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v20.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v20.16b
+ aesmc v26.16b,v26.16b
+
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v21.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v21.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v21.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v21.16b
+ aesmc v26.16b,v26.16b
+
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v22.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v22.16b
+ aesmc v24.16b,v24.16b
+ aese v25.16b,v22.16b
+ aesmc v25.16b,v25.16b
+ aese v26.16b,v22.16b
+ aesmc v26.16b,v26.16b
+
+ eor v4.16b,v7.16b,v6.16b
+ aese v0.16b,v23.16b
+ // The iv for first block of one iteration
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr#31
+ eor x9,x11,x9,lsl#1
+ fmov d6,x9
+ fmov v6.d[1],x10
+ eor v5.16b,v7.16b,v8.16b
+ ld1 {v2.16b},[x0],#16
+ aese v1.16b,v23.16b
+ // The iv for second block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr#31
+ eor x9,x11,x9,lsl#1
+ fmov d8,x9
+ fmov v8.d[1],x10
+ eor v17.16b,v7.16b,v9.16b
+ ld1 {v3.16b},[x0],#16
+ aese v24.16b,v23.16b
+ // The iv for third block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr#31
+ eor x9,x11,x9,lsl#1
+ fmov d9,x9
+ fmov v9.d[1],x10
+ eor v30.16b,v7.16b,v10.16b
+ ld1 {v27.16b},[x0],#16
+ aese v25.16b,v23.16b
+ // The iv for fourth block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr#31
+ eor x9,x11,x9,lsl#1
+ fmov d10,x9
+ fmov v10.d[1],x10
+ eor v31.16b,v7.16b,v11.16b
+ ld1 {v28.16b},[x0],#16
+ aese v26.16b,v23.16b
+
+ // The iv for fifth block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d11,x9
+ fmov v11.d[1],x10
+
+ ld1 {v29.16b},[x0],#16
+ cbz x6,.Lxts_enc_tail4x
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ eor v4.16b,v4.16b,v0.16b
+ eor v0.16b,v2.16b,v6.16b
+ eor v5.16b,v5.16b,v1.16b
+ eor v1.16b,v3.16b,v8.16b
+ eor v17.16b,v17.16b,v24.16b
+ eor v24.16b,v27.16b,v9.16b
+ eor v30.16b,v30.16b,v25.16b
+ eor v25.16b,v28.16b,v10.16b
+ eor v31.16b,v31.16b,v26.16b
+ st1 {v4.16b},[x1],#16
+ eor v26.16b,v29.16b,v11.16b
+ st1 {v5.16b},[x1],#16
+ mov w6,w5
+ st1 {v17.16b},[x1],#16
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v30.16b},[x1],#16
+ st1 {v31.16b},[x1],#16
+ b.hs .Loop5x_xts_enc
+
+
+ // If left 4 blocks, borrow the five block's processing.
+ cmn x2,#0x10
+ b.ne .Loop5x_enc_after
+ orr v11.16b,v10.16b,v10.16b
+ orr v10.16b,v9.16b,v9.16b
+ orr v9.16b,v8.16b,v8.16b
+ orr v8.16b,v6.16b,v6.16b
+ fmov x9,d11
+ fmov x10,v11.d[1]
+ eor v0.16b,v6.16b,v2.16b
+ eor v1.16b,v8.16b,v3.16b
+ eor v24.16b,v27.16b,v9.16b
+ eor v25.16b,v28.16b,v10.16b
+ eor v26.16b,v29.16b,v11.16b
+ b.eq .Loop5x_xts_enc
+
+.Loop5x_enc_after:
+ add x2,x2,#0x50
+ cbz x2,.Lxts_enc_done
+
+ add w6,w5,#2
+ subs x2,x2,#0x30
+ b.lo .Lxts_inner_enc_tail
+
+ eor v0.16b,v6.16b,v27.16b
+ eor v1.16b,v8.16b,v28.16b
+ eor v24.16b,v29.16b,v9.16b
+ b .Lxts_outer_enc_tail
+
+.align 4
+.Lxts_enc_tail4x:
+ add x0,x0,#16
+ eor v5.16b,v1.16b,v5.16b
+ st1 {v5.16b},[x1],#16
+ eor v17.16b,v24.16b,v17.16b
+ st1 {v17.16b},[x1],#16
+ eor v30.16b,v25.16b,v30.16b
+ eor v31.16b,v26.16b,v31.16b
+ st1 {v30.16b,v31.16b},[x1],#32
+
+ b .Lxts_enc_done
+.align 4
+.Lxts_outer_enc_tail:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Lxts_outer_enc_tail
+
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ eor v4.16b,v6.16b,v7.16b
+ subs x2,x2,#0x30
+ // The iv for first block
+ fmov x9,d9
+ fmov x10,v9.d[1]
+ //mov w19,#0x87
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr#31
+ eor x9,x11,x9,lsl#1
+ fmov d6,x9
+ fmov v6.d[1],x10
+ eor v5.16b,v8.16b,v7.16b
+ csel x6,x2,x6,lo // x6, w6, is zero at this point
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ eor v17.16b,v9.16b,v7.16b
+
+ add x6,x6,#0x20
+ add x0,x0,x6
+ mov x7,x3
+
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v20.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v20.16b
+ aesmc v24.16b,v24.16b
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v21.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v21.16b
+ aesmc v24.16b,v24.16b
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v22.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v22.16b
+ aesmc v24.16b,v24.16b
+ aese v0.16b,v23.16b
+ aese v1.16b,v23.16b
+ aese v24.16b,v23.16b
+ ld1 {v27.16b},[x0],#16
+ add w6,w5,#2
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ eor v4.16b,v4.16b,v0.16b
+ eor v5.16b,v5.16b,v1.16b
+ eor v24.16b,v24.16b,v17.16b
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v4.16b},[x1],#16
+ st1 {v5.16b},[x1],#16
+ st1 {v24.16b},[x1],#16
+ cmn x2,#0x30
+ b.eq .Lxts_enc_done
+.Lxts_encxor_one:
+ orr v28.16b,v3.16b,v3.16b
+ orr v29.16b,v27.16b,v27.16b
+ nop
+
+.Lxts_inner_enc_tail:
+ cmn x2,#0x10
+ eor v1.16b,v28.16b,v6.16b
+ eor v24.16b,v29.16b,v8.16b
+ b.eq .Lxts_enc_tail_loop
+ eor v24.16b,v29.16b,v6.16b
+.Lxts_enc_tail_loop:
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Lxts_enc_tail_loop
+
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v16.16b
+ aesmc v24.16b,v24.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v17.16b
+ aesmc v24.16b,v24.16b
+ aese v1.16b,v20.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v20.16b
+ aesmc v24.16b,v24.16b
+ cmn x2,#0x20
+ aese v1.16b,v21.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v21.16b
+ aesmc v24.16b,v24.16b
+ eor v5.16b,v6.16b,v7.16b
+ aese v1.16b,v22.16b
+ aesmc v1.16b,v1.16b
+ aese v24.16b,v22.16b
+ aesmc v24.16b,v24.16b
+ eor v17.16b,v8.16b,v7.16b
+ aese v1.16b,v23.16b
+ aese v24.16b,v23.16b
+ b.eq .Lxts_enc_one
+ eor v5.16b,v5.16b,v1.16b
+ st1 {v5.16b},[x1],#16
+ eor v17.16b,v17.16b,v24.16b
+ orr v6.16b,v8.16b,v8.16b
+ st1 {v17.16b},[x1],#16
+ fmov x9,d8
+ fmov x10,v8.d[1]
+ mov w19,#0x87
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d6,x9
+ fmov v6.d[1],x10
+ b .Lxts_enc_done
+
+.Lxts_enc_one:
+ eor v5.16b,v5.16b,v24.16b
+ orr v6.16b,v6.16b,v6.16b
+ st1 {v5.16b},[x1],#16
+ fmov x9,d6
+ fmov x10,v6.d[1]
+ mov w19,#0x87
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d6,x9
+ fmov v6.d[1],x10
+ b .Lxts_enc_done
+.align 5
+.Lxts_enc_done:
+ // Process the tail block with cipher stealing.
+ tst x21,#0xf
+ b.eq .Lxts_abort
+
+ mov x20,x0
+ mov x13,x1
+ sub x1,x1,#16
+.composite_enc_loop:
+ subs x21,x21,#1
+ ldrb w15,[x1,x21]
+ ldrb w14,[x20,x21]
+ strb w15,[x13,x21]
+ strb w14,[x1,x21]
+ b.gt .composite_enc_loop
+.Lxts_enc_load_done:
+ ld1 {v26.16b},[x1]
+ eor v26.16b,v26.16b,v6.16b
+
+ // Encrypt the composite block to get the last second encrypted text block
+ ldr w6,[x3,#240] // load key schedule...
+ ld1 {v0.4s},[x3],#16
+ sub w6,w6,#2
+ ld1 {v1.4s},[x3],#16 // load key schedule...
+.Loop_final_enc:
+ aese v26.16b,v0.16b
+ aesmc v26.16b,v26.16b
+ ld1 {v0.4s},[x3],#16
+ subs w6,w6,#2
+ aese v26.16b,v1.16b
+ aesmc v26.16b,v26.16b
+ ld1 {v1.4s},[x3],#16
+ b.gt .Loop_final_enc
+
+ aese v26.16b,v0.16b
+ aesmc v26.16b,v26.16b
+ ld1 {v0.4s},[x3]
+ aese v26.16b,v1.16b
+ eor v26.16b,v26.16b,v0.16b
+ eor v26.16b,v26.16b,v6.16b
+ st1 {v26.16b},[x1]
+
+.Lxts_abort:
+ ldp x21,x22,[sp,#48]
+ ldp d8,d9,[sp,#32]
+ ldp d10,d11,[sp,#16]
+ ldp x19,x20,[sp],#64
+.Lxts_enc_final_abort:
+ ret
+.size aes_v8_xts_encrypt,.-aes_v8_xts_encrypt
+.globl aes_v8_xts_decrypt
+.type aes_v8_xts_decrypt,%function
+.align 5
+aes_v8_xts_decrypt:
+ cmp x2,#16
+ // Original input data size bigger than 16, jump to big size processing.
+ b.ne .Lxts_dec_big_size
+ // Encrypt the iv with key2, as the first XEX iv.
+ ldr w6,[x4,#240]
+ ld1 {v0.4s},[x4],#16
+ ld1 {v6.16b},[x5]
+ sub w6,w6,#2
+ ld1 {v1.4s},[x4],#16
+
+.Loop_dec_small_iv_enc:
+ aese v6.16b,v0.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v0.4s},[x4],#16
+ subs w6,w6,#2
+ aese v6.16b,v1.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v1.4s},[x4],#16
+ b.gt .Loop_dec_small_iv_enc
+
+ aese v6.16b,v0.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v0.4s},[x4]
+ aese v6.16b,v1.16b
+ eor v6.16b,v6.16b,v0.16b
+
+ ld1 {v0.16b},[x0]
+ eor v0.16b,v6.16b,v0.16b
+
+ ldr w6,[x3,#240]
+ ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule...
+
+ aesd v0.16b,v28.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule...
+ aesd v0.16b,v29.16b
+ aesimc v0.16b,v0.16b
+ subs w6,w6,#10 // bias
+ b.eq .Lxts_128_dec
+.Lxts_dec_round_loop:
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v16.4s},[x3],#16 // load key schedule...
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v17.4s},[x3],#16 // load key schedule...
+ subs w6,w6,#2 // bias
+ b.gt .Lxts_dec_round_loop
+.Lxts_128_dec:
+ ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule...
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule...
+ aesd v0.16b,v18.16b
+ aesimc v0.16b,v0.16b
+ aesd v0.16b,v19.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule...
+ aesd v0.16b,v20.16b
+ aesimc v0.16b,v0.16b
+ aesd v0.16b,v21.16b
+ aesimc v0.16b,v0.16b
+ ld1 {v7.4s},[x3]
+ aesd v0.16b,v22.16b
+ aesimc v0.16b,v0.16b
+ aesd v0.16b,v23.16b
+ eor v0.16b,v0.16b,v7.16b
+ eor v0.16b,v6.16b,v0.16b
+ st1 {v0.16b},[x1]
+ b .Lxts_dec_final_abort
+.Lxts_dec_big_size:
+ stp x19,x20,[sp,#-64]!
+ stp x21,x22,[sp,#48]
+ stp d8,d9,[sp,#32]
+ stp d10,d11,[sp,#16]
+
+ and x21,x2,#0xf
+ and x2,x2,#-16
+ subs x2,x2,#16
+ mov x8,#16
+ b.lo .Lxts_dec_abort
+
+ // Encrypt the iv with key2, as the first XEX iv
+ ldr w6,[x4,#240]
+ ld1 {v0.4s},[x4],#16
+ ld1 {v6.16b},[x5]
+ sub w6,w6,#2
+ ld1 {v1.4s},[x4],#16
+
+.Loop_dec_iv_enc:
+ aese v6.16b,v0.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v0.4s},[x4],#16
+ subs w6,w6,#2
+ aese v6.16b,v1.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v1.4s},[x4],#16
+ b.gt .Loop_dec_iv_enc
+
+ aese v6.16b,v0.16b
+ aesmc v6.16b,v6.16b
+ ld1 {v0.4s},[x4]
+ aese v6.16b,v1.16b
+ eor v6.16b,v6.16b,v0.16b
+
+ // The iv for second block
+ // x9- iv(low), x10 - iv(high)
+ // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b
+ fmov x9,d6
+ fmov x10,v6.d[1]
+ mov w19,#0x87
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d8,x9
+ fmov v8.d[1],x10
+
+ ldr w5,[x3,#240] // load rounds number
+
+ // The iv for third block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d9,x9
+ fmov v9.d[1],x10
+
+ ld1 {v16.4s,v17.4s},[x3] // load key schedule...
+ sub w5,w5,#6
+ add x7,x3,x5,lsl#4 // pointer to last 7 round keys
+ sub w5,w5,#2
+ ld1 {v18.4s,v19.4s},[x7],#32 // load key schedule...
+ ld1 {v20.4s,v21.4s},[x7],#32
+ ld1 {v22.4s,v23.4s},[x7],#32
+ ld1 {v7.4s},[x7]
+
+ // The iv for fourth block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d10,x9
+ fmov v10.d[1],x10
+
+ add x7,x3,#32
+ mov w6,w5
+ b .Lxts_dec
+
+ // Decryption
+.align 5
+.Lxts_dec:
+ tst x21,#0xf
+ b.eq .Lxts_dec_begin
+ subs x2,x2,#16
+ csel x8,xzr,x8,eq
+ ld1 {v0.16b},[x0],#16
+ b.lo .Lxts_done
+ sub x0,x0,#16
+.Lxts_dec_begin:
+ ld1 {v0.16b},[x0],x8
+ subs x2,x2,#32 // bias
+ add w6,w5,#2
+ orr v3.16b,v0.16b,v0.16b
+ orr v1.16b,v0.16b,v0.16b
+ orr v28.16b,v0.16b,v0.16b
+ ld1 {v24.16b},[x0],#16
+ orr v27.16b,v24.16b,v24.16b
+ orr v29.16b,v24.16b,v24.16b
+ b.lo .Lxts_inner_dec_tail
+ eor v0.16b,v0.16b,v6.16b // before decryt, xor with iv
+ eor v24.16b,v24.16b,v8.16b
+
+ orr v1.16b,v24.16b,v24.16b
+ ld1 {v24.16b},[x0],#16
+ orr v2.16b,v0.16b,v0.16b
+ orr v3.16b,v1.16b,v1.16b
+ eor v27.16b,v24.16b,v9.16b // third block xox with third iv
+ eor v24.16b,v24.16b,v9.16b
+ cmp x2,#32
+ b.lo .Lxts_outer_dec_tail
+
+ ld1 {v25.16b},[x0],#16
+
+ // The iv for fifth block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d11,x9
+ fmov v11.d[1],x10
+
+ ld1 {v26.16b},[x0],#16
+ eor v25.16b,v25.16b,v10.16b // the fourth block
+ eor v26.16b,v26.16b,v11.16b
+ sub x2,x2,#32 // bias
+ mov w6,w5
+ b .Loop5x_xts_dec
+
+.align 4
+.Loop5x_xts_dec:
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v16.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v16.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v16.4s},[x7],#16 // load key schedule...
+ subs w6,w6,#2
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v17.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v17.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v17.4s},[x7],#16 // load key schedule...
+ b.gt .Loop5x_xts_dec
+
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v16.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v16.16b
+ aesimc v26.16b,v26.16b
+ subs x2,x2,#0x50 // because .Lxts_dec_tail4x
+
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v17.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v17.16b
+ aesimc v26.16b,v26.16b
+ csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo
+ mov x7,x3
+
+ aesd v0.16b,v18.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v18.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v18.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v18.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v18.16b
+ aesimc v26.16b,v26.16b
+ add x0,x0,x6 // x0 is adjusted in such way that
+ // at exit from the loop v1.16b-v26.16b
+ // are loaded with last "words"
+ add x6,x2,#0x60 // because .Lxts_dec_tail4x
+
+ aesd v0.16b,v19.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v19.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v19.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v19.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v19.16b
+ aesimc v26.16b,v26.16b
+
+ aesd v0.16b,v20.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v20.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v20.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v20.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v20.16b
+ aesimc v26.16b,v26.16b
+
+ aesd v0.16b,v21.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v21.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v21.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v21.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v21.16b
+ aesimc v26.16b,v26.16b
+
+ aesd v0.16b,v22.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v22.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v22.16b
+ aesimc v24.16b,v24.16b
+ aesd v25.16b,v22.16b
+ aesimc v25.16b,v25.16b
+ aesd v26.16b,v22.16b
+ aesimc v26.16b,v26.16b
+
+ eor v4.16b,v7.16b,v6.16b
+ aesd v0.16b,v23.16b
+ // The iv for first block of next iteration.
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d6,x9
+ fmov v6.d[1],x10
+ eor v5.16b,v7.16b,v8.16b
+ ld1 {v2.16b},[x0],#16
+ aesd v1.16b,v23.16b
+ // The iv for second block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d8,x9
+ fmov v8.d[1],x10
+ eor v17.16b,v7.16b,v9.16b
+ ld1 {v3.16b},[x0],#16
+ aesd v24.16b,v23.16b
+ // The iv for third block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d9,x9
+ fmov v9.d[1],x10
+ eor v30.16b,v7.16b,v10.16b
+ ld1 {v27.16b},[x0],#16
+ aesd v25.16b,v23.16b
+ // The iv for fourth block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d10,x9
+ fmov v10.d[1],x10
+ eor v31.16b,v7.16b,v11.16b
+ ld1 {v28.16b},[x0],#16
+ aesd v26.16b,v23.16b
+
+ // The iv for fifth block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d11,x9
+ fmov v11.d[1],x10
+
+ ld1 {v29.16b},[x0],#16
+ cbz x6,.Lxts_dec_tail4x
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ eor v4.16b,v4.16b,v0.16b
+ eor v0.16b,v2.16b,v6.16b
+ eor v5.16b,v5.16b,v1.16b
+ eor v1.16b,v3.16b,v8.16b
+ eor v17.16b,v17.16b,v24.16b
+ eor v24.16b,v27.16b,v9.16b
+ eor v30.16b,v30.16b,v25.16b
+ eor v25.16b,v28.16b,v10.16b
+ eor v31.16b,v31.16b,v26.16b
+ st1 {v4.16b},[x1],#16
+ eor v26.16b,v29.16b,v11.16b
+ st1 {v5.16b},[x1],#16
+ mov w6,w5
+ st1 {v17.16b},[x1],#16
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v30.16b},[x1],#16
+ st1 {v31.16b},[x1],#16
+ b.hs .Loop5x_xts_dec
+
+ cmn x2,#0x10
+ b.ne .Loop5x_dec_after
+ // If x2(x2) equal to -0x10, the left blocks is 4.
+ // After specially processing, utilize the five blocks processing again.
+ // It will use the following IVs: v6.16b,v6.16b,v8.16b,v9.16b,v10.16b.
+ orr v11.16b,v10.16b,v10.16b
+ orr v10.16b,v9.16b,v9.16b
+ orr v9.16b,v8.16b,v8.16b
+ orr v8.16b,v6.16b,v6.16b
+ fmov x9,d11
+ fmov x10,v11.d[1]
+ eor v0.16b,v6.16b,v2.16b
+ eor v1.16b,v8.16b,v3.16b
+ eor v24.16b,v27.16b,v9.16b
+ eor v25.16b,v28.16b,v10.16b
+ eor v26.16b,v29.16b,v11.16b
+ b.eq .Loop5x_xts_dec
+
+.Loop5x_dec_after:
+ add x2,x2,#0x50
+ cbz x2,.Lxts_done
+
+ add w6,w5,#2
+ subs x2,x2,#0x30
+ b.lo .Lxts_inner_dec_tail
+
+ eor v0.16b,v6.16b,v27.16b
+ eor v1.16b,v8.16b,v28.16b
+ eor v24.16b,v29.16b,v9.16b
+ b .Lxts_outer_dec_tail
+
+.align 4
+.Lxts_dec_tail4x:
+ add x0,x0,#16
+ tst x21,#0xf
+ eor v5.16b,v1.16b,v4.16b
+ st1 {v5.16b},[x1],#16
+ eor v17.16b,v24.16b,v17.16b
+ st1 {v17.16b},[x1],#16
+ eor v30.16b,v25.16b,v30.16b
+ eor v31.16b,v26.16b,v31.16b
+ st1 {v30.16b,v31.16b},[x1],#32
+
+ b.eq .Lxts_dec_abort
+ ld1 {v0.16b},[x0],#16
+ b .Lxts_done
+.align 4
+.Lxts_outer_dec_tail:
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Lxts_outer_dec_tail
+
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ eor v4.16b,v6.16b,v7.16b
+ subs x2,x2,#0x30
+ // The iv for first block
+ fmov x9,d9
+ fmov x10,v9.d[1]
+ mov w19,#0x87
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d6,x9
+ fmov v6.d[1],x10
+ eor v5.16b,v8.16b,v7.16b
+ csel x6,x2,x6,lo // x6, w6, is zero at this point
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ eor v17.16b,v9.16b,v7.16b
+ // The iv for second block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d8,x9
+ fmov v8.d[1],x10
+
+ add x6,x6,#0x20
+ add x0,x0,x6 // x0 is adjusted to the last data
+
+ mov x7,x3
+
+ // The iv for third block
+ extr x22,x10,x10,#32
+ extr x10,x10,x9,#63
+ and w11,w19,w22,asr #31
+ eor x9,x11,x9,lsl #1
+ fmov d9,x9
+ fmov v9.d[1],x10
+
+ aesd v0.16b,v20.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v20.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v20.16b
+ aesimc v24.16b,v24.16b
+ aesd v0.16b,v21.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v21.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v21.16b
+ aesimc v24.16b,v24.16b
+ aesd v0.16b,v22.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v22.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v22.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v27.16b},[x0],#16
+ aesd v0.16b,v23.16b
+ aesd v1.16b,v23.16b
+ aesd v24.16b,v23.16b
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ add w6,w5,#2
+ eor v4.16b,v4.16b,v0.16b
+ eor v5.16b,v5.16b,v1.16b
+ eor v24.16b,v24.16b,v17.16b
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v4.16b},[x1],#16
+ st1 {v5.16b},[x1],#16
+ st1 {v24.16b},[x1],#16
+
+ cmn x2,#0x30
+ add x2,x2,#0x30
+ b.eq .Lxts_done
+ sub x2,x2,#0x30
+ orr v28.16b,v3.16b,v3.16b
+ orr v29.16b,v27.16b,v27.16b
+ nop
+
+.Lxts_inner_dec_tail:
+ // x2 == -0x10 means two blocks left.
+ cmn x2,#0x10
+ eor v1.16b,v28.16b,v6.16b
+ eor v24.16b,v29.16b,v8.16b
+ b.eq .Lxts_dec_tail_loop
+ eor v24.16b,v29.16b,v6.16b
+.Lxts_dec_tail_loop:
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Lxts_dec_tail_loop
+
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v16.16b
+ aesimc v24.16b,v24.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v17.16b
+ aesimc v24.16b,v24.16b
+ aesd v1.16b,v20.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v20.16b
+ aesimc v24.16b,v24.16b
+ cmn x2,#0x20
+ aesd v1.16b,v21.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v21.16b
+ aesimc v24.16b,v24.16b
+ eor v5.16b,v6.16b,v7.16b
+ aesd v1.16b,v22.16b
+ aesimc v1.16b,v1.16b
+ aesd v24.16b,v22.16b
+ aesimc v24.16b,v24.16b
+ eor v17.16b,v8.16b,v7.16b
+ aesd v1.16b,v23.16b
+ aesd v24.16b,v23.16b
+ b.eq .Lxts_dec_one
+ eor v5.16b,v5.16b,v1.16b
+ eor v17.16b,v17.16b,v24.16b
+ orr v6.16b,v9.16b,v9.16b
+ orr v8.16b,v10.16b,v10.16b
+ st1 {v5.16b},[x1],#16
+ st1 {v17.16b},[x1],#16
+ add x2,x2,#16
+ b .Lxts_done
+
+.Lxts_dec_one:
+ eor v5.16b,v5.16b,v24.16b
+ orr v6.16b,v8.16b,v8.16b
+ orr v8.16b,v9.16b,v9.16b
+ st1 {v5.16b},[x1],#16
+ add x2,x2,#32
+
+.Lxts_done:
+ tst x21,#0xf
+ b.eq .Lxts_dec_abort
+ // Processing the last two blocks with cipher stealing.
+ mov x7,x3
+ cbnz x2,.Lxts_dec_1st_done
+ ld1 {v0.16b},[x0],#16
+
+ // Decrypt the last secod block to get the last plain text block
+.Lxts_dec_1st_done:
+ eor v26.16b,v0.16b,v8.16b
+ ldr w6,[x3,#240]
+ ld1 {v0.4s},[x3],#16
+ sub w6,w6,#2
+ ld1 {v1.4s},[x3],#16
+.Loop_final_2nd_dec:
+ aesd v26.16b,v0.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v0.4s},[x3],#16 // load key schedule...
+ subs w6,w6,#2
+ aesd v26.16b,v1.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v1.4s},[x3],#16 // load key schedule...
+ b.gt .Loop_final_2nd_dec
+
+ aesd v26.16b,v0.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v0.4s},[x3]
+ aesd v26.16b,v1.16b
+ eor v26.16b,v26.16b,v0.16b
+ eor v26.16b,v26.16b,v8.16b
+ st1 {v26.16b},[x1]
+
+ mov x20,x0
+ add x13,x1,#16
+
+ // Composite the tailcnt "16 byte not aligned block" into the last second plain blocks
+ // to get the last encrypted block.
+.composite_dec_loop:
+ subs x21,x21,#1
+ ldrb w15,[x1,x21]
+ ldrb w14,[x20,x21]
+ strb w15,[x13,x21]
+ strb w14,[x1,x21]
+ b.gt .composite_dec_loop
+.Lxts_dec_load_done:
+ ld1 {v26.16b},[x1]
+ eor v26.16b,v26.16b,v6.16b
+
+ // Decrypt the composite block to get the last second plain text block
+ ldr w6,[x7,#240]
+ ld1 {v0.4s},[x7],#16
+ sub w6,w6,#2
+ ld1 {v1.4s},[x7],#16
+.Loop_final_dec:
+ aesd v26.16b,v0.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v0.4s},[x7],#16 // load key schedule...
+ subs w6,w6,#2
+ aesd v26.16b,v1.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v1.4s},[x7],#16 // load key schedule...
+ b.gt .Loop_final_dec
+
+ aesd v26.16b,v0.16b
+ aesimc v26.16b,v26.16b
+ ld1 {v0.4s},[x7]
+ aesd v26.16b,v1.16b
+ eor v26.16b,v26.16b,v0.16b
+ eor v26.16b,v26.16b,v6.16b
+ st1 {v26.16b},[x1]
+
+.Lxts_dec_abort:
+ ldp x21,x22,[sp,#48]
+ ldp d8,d9,[sp,#32]
+ ldp d10,d11,[sp,#16]
+ ldp x19,x20,[sp],#64
+
+.Lxts_dec_final_abort:
+ ret
+.size aes_v8_xts_decrypt,.-aes_v8_xts_decrypt
+#endif
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/vpaes-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/vpaes-armv8.S
new file mode 100644
index 0000000..229dad2
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/aes/vpaes-armv8.S
@@ -0,0 +1,1196 @@
+.text
+
+.type _vpaes_consts,%object
+.align 7 // totally strategic alignment
+_vpaes_consts:
+.Lk_mc_forward: // mc_forward
+.quad 0x0407060500030201, 0x0C0F0E0D080B0A09
+.quad 0x080B0A0904070605, 0x000302010C0F0E0D
+.quad 0x0C0F0E0D080B0A09, 0x0407060500030201
+.quad 0x000302010C0F0E0D, 0x080B0A0904070605
+.Lk_mc_backward: // mc_backward
+.quad 0x0605040702010003, 0x0E0D0C0F0A09080B
+.quad 0x020100030E0D0C0F, 0x0A09080B06050407
+.quad 0x0E0D0C0F0A09080B, 0x0605040702010003
+.quad 0x0A09080B06050407, 0x020100030E0D0C0F
+.Lk_sr: // sr
+.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908
+.quad 0x030E09040F0A0500, 0x0B06010C07020D08
+.quad 0x0F060D040B020900, 0x070E050C030A0108
+.quad 0x0B0E0104070A0D00, 0x0306090C0F020508
+
+//
+// "Hot" constants
+//
+.Lk_inv: // inv, inva
+.quad 0x0E05060F0D080180, 0x040703090A0B0C02
+.quad 0x01040A060F0B0780, 0x030D0E0C02050809
+.Lk_ipt: // input transform (lo, hi)
+.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808
+.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81
+.Lk_sbo: // sbou, sbot
+.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878
+.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA
+.Lk_sb1: // sb1u, sb1t
+.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF
+.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544
+.Lk_sb2: // sb2u, sb2t
+.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A
+.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD
+
+//
+// Decryption stuff
+//
+.Lk_dipt: // decryption input transform
+.quad 0x0F505B040B545F00, 0x154A411E114E451A
+.quad 0x86E383E660056500, 0x12771772F491F194
+.Lk_dsbo: // decryption sbox final output
+.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
+.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C
+.Lk_dsb9: // decryption sbox output *9*u, *9*t
+.quad 0x851C03539A86D600, 0xCAD51F504F994CC9
+.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565
+.Lk_dsbd: // decryption sbox output *D*u, *D*t
+.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439
+.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3
+.Lk_dsbb: // decryption sbox output *B*u, *B*t
+.quad 0xD022649296B44200, 0x602646F6B0F2D404
+.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B
+.Lk_dsbe: // decryption sbox output *E*u, *E*t
+.quad 0x46F2929626D4D000, 0x2242600464B4F6B0
+.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32
+
+//
+// Key schedule constants
+//
+.Lk_dksd: // decryption key schedule: invskew x*D
+.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
+.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E
+.Lk_dksb: // decryption key schedule: invskew x*B
+.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99
+.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8
+.Lk_dkse: // decryption key schedule: invskew x*E + 0x63
+.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086
+.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487
+.Lk_dks9: // decryption key schedule: invskew x*9
+.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC
+.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE
+
+.Lk_rcon: // rcon
+.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81
+
+.Lk_opt: // output transform
+.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808
+.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0
+.Lk_deskew: // deskew tables: inverts the sbox's "skew"
+.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
+.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
+
+.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,65,82,77,118,56,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0
+.align 2
+.size _vpaes_consts,.-_vpaes_consts
+.align 6
+//
+// _aes_preheat
+//
+// Fills register %r10 -> .aes_consts (so you can -fPIC)
+// and %xmm9-%xmm15 as specified below.
+//
+.type _vpaes_encrypt_preheat,%function
+.align 4
+_vpaes_encrypt_preheat:
+ adr x10, .Lk_inv
+ movi v17.16b, #0x0f
+ ld1 {v18.2d,v19.2d}, [x10],#32 // .Lk_inv
+ ld1 {v20.2d,v21.2d,v22.2d,v23.2d}, [x10],#64 // .Lk_ipt, .Lk_sbo
+ ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x10] // .Lk_sb1, .Lk_sb2
+ ret
+.size _vpaes_encrypt_preheat,.-_vpaes_encrypt_preheat
+
+//
+// _aes_encrypt_core
+//
+// AES-encrypt %xmm0.
+//
+// Inputs:
+// %xmm0 = input
+// %xmm9-%xmm15 as in _vpaes_preheat
+// (%rdx) = scheduled keys
+//
+// Output in %xmm0
+// Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax
+// Preserves %xmm6 - %xmm8 so you get some local vectors
+//
+//
+.type _vpaes_encrypt_core,%function
+.align 4
+_vpaes_encrypt_core:
+ mov x9, x2
+ ldr w8, [x2,#240] // pull rounds
+ adr x11, .Lk_mc_forward+16
+ // vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo
+ ld1 {v16.2d}, [x9], #16 // vmovdqu (%r9), %xmm5 # round0 key
+ and v1.16b, v7.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1
+ ushr v0.16b, v7.16b, #4 // vpsrlb $4, %xmm0, %xmm0
+ tbl v1.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm1
+ // vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi
+ tbl v2.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm3, %xmm2
+ eor v0.16b, v1.16b, v16.16b // vpxor %xmm5, %xmm1, %xmm0
+ eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0
+ b .Lenc_entry
+
+.align 4
+.Lenc_loop:
+ // middle of middle round
+ add x10, x11, #0x40
+ tbl v4.16b, {v25.16b}, v2.16b // vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u
+ ld1 {v1.2d}, [x11], #16 // vmovdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[]
+ tbl v0.16b, {v24.16b}, v3.16b // vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t
+ eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k
+ tbl v5.16b, {v27.16b}, v2.16b // vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A
+ tbl v2.16b, {v26.16b}, v3.16b // vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t
+ ld1 {v4.2d}, [x10] // vmovdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[]
+ tbl v3.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm3 # 0 = B
+ eor v2.16b, v2.16b, v5.16b // vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A
+ tbl v0.16b, {v0.16b}, v4.16b // vpshufb %xmm4, %xmm0, %xmm0 # 3 = D
+ eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B
+ tbl v4.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C
+ eor v0.16b, v0.16b, v3.16b // vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D
+ and x11, x11, #~(1<<6) // and $0x30, %r11 # ... mod 4
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D
+ sub w8, w8, #1 // nr--
+
+.Lenc_entry:
+ // top of round
+ and v1.16b, v0.16b, v17.16b // vpand %xmm0, %xmm9, %xmm1 # 0 = k
+ ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i
+ tbl v5.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k
+ eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j
+ tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i
+ tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j
+ eor v3.16b, v3.16b, v5.16b // vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k
+ eor v4.16b, v4.16b, v5.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k
+ tbl v2.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak
+ tbl v3.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak
+ eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io
+ eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo
+ ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm5
+ cbnz w8, .Lenc_loop
+
+ // middle of last round
+ add x10, x11, #0x80
+ // vmovdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo
+ // vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16
+ tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou
+ ld1 {v1.2d}, [x10] // vmovdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[]
+ tbl v0.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t
+ eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A
+ tbl v0.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm0
+ ret
+.size _vpaes_encrypt_core,.-_vpaes_encrypt_core
+
+.globl vpaes_encrypt
+.type vpaes_encrypt,%function
+.align 4
+vpaes_encrypt:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ld1 {v7.16b}, [x0]
+ bl _vpaes_encrypt_preheat
+ bl _vpaes_encrypt_core
+ st1 {v0.16b}, [x1]
+
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size vpaes_encrypt,.-vpaes_encrypt
+
+.type _vpaes_encrypt_2x,%function
+.align 4
+_vpaes_encrypt_2x:
+ mov x9, x2
+ ldr w8, [x2,#240] // pull rounds
+ adr x11, .Lk_mc_forward+16
+ // vmovdqa .Lk_ipt(%rip), %xmm2 # iptlo
+ ld1 {v16.2d}, [x9], #16 // vmovdqu (%r9), %xmm5 # round0 key
+ and v1.16b, v14.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1
+ ushr v0.16b, v14.16b, #4 // vpsrlb $4, %xmm0, %xmm0
+ and v9.16b, v15.16b, v17.16b
+ ushr v8.16b, v15.16b, #4
+ tbl v1.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm1
+ tbl v9.16b, {v20.16b}, v9.16b
+ // vmovdqa .Lk_ipt+16(%rip), %xmm3 # ipthi
+ tbl v2.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm3, %xmm2
+ tbl v10.16b, {v21.16b}, v8.16b
+ eor v0.16b, v1.16b, v16.16b // vpxor %xmm5, %xmm1, %xmm0
+ eor v8.16b, v9.16b, v16.16b
+ eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0
+ eor v8.16b, v8.16b, v10.16b
+ b .Lenc_2x_entry
+
+.align 4
+.Lenc_2x_loop:
+ // middle of middle round
+ add x10, x11, #0x40
+ tbl v4.16b, {v25.16b}, v2.16b // vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u
+ tbl v12.16b, {v25.16b}, v10.16b
+ ld1 {v1.2d}, [x11], #16 // vmovdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[]
+ tbl v0.16b, {v24.16b}, v3.16b // vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t
+ tbl v8.16b, {v24.16b}, v11.16b
+ eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k
+ eor v12.16b, v12.16b, v16.16b
+ tbl v5.16b, {v27.16b}, v2.16b // vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u
+ tbl v13.16b, {v27.16b}, v10.16b
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A
+ eor v8.16b, v8.16b, v12.16b
+ tbl v2.16b, {v26.16b}, v3.16b // vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t
+ tbl v10.16b, {v26.16b}, v11.16b
+ ld1 {v4.2d}, [x10] // vmovdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[]
+ tbl v3.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm3 # 0 = B
+ tbl v11.16b, {v8.16b}, v1.16b
+ eor v2.16b, v2.16b, v5.16b // vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A
+ eor v10.16b, v10.16b, v13.16b
+ tbl v0.16b, {v0.16b}, v4.16b // vpshufb %xmm4, %xmm0, %xmm0 # 3 = D
+ tbl v8.16b, {v8.16b}, v4.16b
+ eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B
+ eor v11.16b, v11.16b, v10.16b
+ tbl v4.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C
+ tbl v12.16b, {v11.16b},v1.16b
+ eor v0.16b, v0.16b, v3.16b // vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D
+ eor v8.16b, v8.16b, v11.16b
+ and x11, x11, #~(1<<6) // and $0x30, %r11 # ... mod 4
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D
+ eor v8.16b, v8.16b, v12.16b
+ sub w8, w8, #1 // nr--
+
+.Lenc_2x_entry:
+ // top of round
+ and v1.16b, v0.16b, v17.16b // vpand %xmm0, %xmm9, %xmm1 # 0 = k
+ ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i
+ and v9.16b, v8.16b, v17.16b
+ ushr v8.16b, v8.16b, #4
+ tbl v5.16b, {v19.16b},v1.16b // vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k
+ tbl v13.16b, {v19.16b},v9.16b
+ eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j
+ eor v9.16b, v9.16b, v8.16b
+ tbl v3.16b, {v18.16b},v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i
+ tbl v11.16b, {v18.16b},v8.16b
+ tbl v4.16b, {v18.16b},v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j
+ tbl v12.16b, {v18.16b},v9.16b
+ eor v3.16b, v3.16b, v5.16b // vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k
+ eor v11.16b, v11.16b, v13.16b
+ eor v4.16b, v4.16b, v5.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k
+ eor v12.16b, v12.16b, v13.16b
+ tbl v2.16b, {v18.16b},v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak
+ tbl v10.16b, {v18.16b},v11.16b
+ tbl v3.16b, {v18.16b},v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak
+ tbl v11.16b, {v18.16b},v12.16b
+ eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io
+ eor v10.16b, v10.16b, v9.16b
+ eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo
+ eor v11.16b, v11.16b, v8.16b
+ ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm5
+ cbnz w8, .Lenc_2x_loop
+
+ // middle of last round
+ add x10, x11, #0x80
+ // vmovdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo
+ // vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16
+ tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou
+ tbl v12.16b, {v22.16b}, v10.16b
+ ld1 {v1.2d}, [x10] // vmovdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[]
+ tbl v0.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t
+ tbl v8.16b, {v23.16b}, v11.16b
+ eor v4.16b, v4.16b, v16.16b // vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k
+ eor v12.16b, v12.16b, v16.16b
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 0 = A
+ eor v8.16b, v8.16b, v12.16b
+ tbl v0.16b, {v0.16b},v1.16b // vpshufb %xmm1, %xmm0, %xmm0
+ tbl v1.16b, {v8.16b},v1.16b
+ ret
+.size _vpaes_encrypt_2x,.-_vpaes_encrypt_2x
+
+.type _vpaes_decrypt_preheat,%function
+.align 4
+_vpaes_decrypt_preheat:
+ adr x10, .Lk_inv
+ movi v17.16b, #0x0f
+ adr x11, .Lk_dipt
+ ld1 {v18.2d,v19.2d}, [x10],#32 // .Lk_inv
+ ld1 {v20.2d,v21.2d,v22.2d,v23.2d}, [x11],#64 // .Lk_dipt, .Lk_dsbo
+ ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x11],#64 // .Lk_dsb9, .Lk_dsbd
+ ld1 {v28.2d,v29.2d,v30.2d,v31.2d}, [x11] // .Lk_dsbb, .Lk_dsbe
+ ret
+.size _vpaes_decrypt_preheat,.-_vpaes_decrypt_preheat
+
+//
+// Decryption core
+//
+// Same API as encryption core.
+//
+.type _vpaes_decrypt_core,%function
+.align 4
+_vpaes_decrypt_core:
+ mov x9, x2
+ ldr w8, [x2,#240] // pull rounds
+
+ // vmovdqa .Lk_dipt(%rip), %xmm2 # iptlo
+ lsl x11, x8, #4 // mov %rax, %r11; shl $4, %r11
+ eor x11, x11, #0x30 // xor $0x30, %r11
+ adr x10, .Lk_sr
+ and x11, x11, #0x30 // and $0x30, %r11
+ add x11, x11, x10
+ adr x10, .Lk_mc_forward+48
+
+ ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm4 # round0 key
+ and v1.16b, v7.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1
+ ushr v0.16b, v7.16b, #4 // vpsrlb $4, %xmm0, %xmm0
+ tbl v2.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm2
+ ld1 {v5.2d}, [x10] // vmovdqa .Lk_mc_forward+48(%rip), %xmm5
+ // vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi
+ tbl v0.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm1, %xmm0
+ eor v2.16b, v2.16b, v16.16b // vpxor %xmm4, %xmm2, %xmm2
+ eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0
+ b .Ldec_entry
+
+.align 4
+.Ldec_loop:
+//
+// Inverse mix columns
+//
+ // vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u
+ // vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t
+ tbl v4.16b, {v24.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u
+ tbl v1.16b, {v25.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t
+ eor v0.16b, v4.16b, v16.16b // vpxor %xmm4, %xmm0, %xmm0
+ // vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu
+ eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch
+ // vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt
+
+ tbl v4.16b, {v26.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu
+ tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch
+ tbl v1.16b, {v27.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch
+ // vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu
+ eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch
+ // vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt
+
+ tbl v4.16b, {v28.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu
+ tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch
+ tbl v1.16b, {v29.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch
+ // vmovdqa 0x40(%r10), %xmm4 # 4 : sbeu
+ eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch
+ // vmovdqa 0x50(%r10), %xmm1 # 0 : sbet
+
+ tbl v4.16b, {v30.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu
+ tbl v0.16b, {v0.16b}, v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch
+ tbl v1.16b, {v31.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch
+ ext v5.16b, v5.16b, v5.16b, #12 // vpalignr $12, %xmm5, %xmm5, %xmm5
+ eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch
+ sub w8, w8, #1 // sub $1,%rax # nr--
+
+.Ldec_entry:
+ // top of round
+ and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k
+ ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i
+ tbl v2.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k
+ eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j
+ tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i
+ tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j
+ eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k
+ eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k
+ tbl v2.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak
+ tbl v3.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak
+ eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io
+ eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo
+ ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm0
+ cbnz w8, .Ldec_loop
+
+ // middle of last round
+ // vmovdqa 0x60(%r10), %xmm4 # 3 : sbou
+ tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou
+ // vmovdqa 0x70(%r10), %xmm1 # 0 : sbot
+ ld1 {v2.2d}, [x11] // vmovdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160
+ tbl v1.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t
+ eor v4.16b, v4.16b, v16.16b // vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k
+ eor v0.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm0 # 0 = A
+ tbl v0.16b, {v0.16b}, v2.16b // vpshufb %xmm2, %xmm0, %xmm0
+ ret
+.size _vpaes_decrypt_core,.-_vpaes_decrypt_core
+
+.globl vpaes_decrypt
+.type vpaes_decrypt,%function
+.align 4
+vpaes_decrypt:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ld1 {v7.16b}, [x0]
+ bl _vpaes_decrypt_preheat
+ bl _vpaes_decrypt_core
+ st1 {v0.16b}, [x1]
+
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size vpaes_decrypt,.-vpaes_decrypt
+
+// v14-v15 input, v0-v1 output
+.type _vpaes_decrypt_2x,%function
+.align 4
+_vpaes_decrypt_2x:
+ mov x9, x2
+ ldr w8, [x2,#240] // pull rounds
+
+ // vmovdqa .Lk_dipt(%rip), %xmm2 # iptlo
+ lsl x11, x8, #4 // mov %rax, %r11; shl $4, %r11
+ eor x11, x11, #0x30 // xor $0x30, %r11
+ adr x10, .Lk_sr
+ and x11, x11, #0x30 // and $0x30, %r11
+ add x11, x11, x10
+ adr x10, .Lk_mc_forward+48
+
+ ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm4 # round0 key
+ and v1.16b, v14.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1
+ ushr v0.16b, v14.16b, #4 // vpsrlb $4, %xmm0, %xmm0
+ and v9.16b, v15.16b, v17.16b
+ ushr v8.16b, v15.16b, #4
+ tbl v2.16b, {v20.16b},v1.16b // vpshufb %xmm1, %xmm2, %xmm2
+ tbl v10.16b, {v20.16b},v9.16b
+ ld1 {v5.2d}, [x10] // vmovdqa .Lk_mc_forward+48(%rip), %xmm5
+ // vmovdqa .Lk_dipt+16(%rip), %xmm1 # ipthi
+ tbl v0.16b, {v21.16b},v0.16b // vpshufb %xmm0, %xmm1, %xmm0
+ tbl v8.16b, {v21.16b},v8.16b
+ eor v2.16b, v2.16b, v16.16b // vpxor %xmm4, %xmm2, %xmm2
+ eor v10.16b, v10.16b, v16.16b
+ eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0
+ eor v8.16b, v8.16b, v10.16b
+ b .Ldec_2x_entry
+
+.align 4
+.Ldec_2x_loop:
+//
+// Inverse mix columns
+//
+ // vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u
+ // vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t
+ tbl v4.16b, {v24.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u
+ tbl v12.16b, {v24.16b}, v10.16b
+ tbl v1.16b, {v25.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t
+ tbl v9.16b, {v25.16b}, v11.16b
+ eor v0.16b, v4.16b, v16.16b // vpxor %xmm4, %xmm0, %xmm0
+ eor v8.16b, v12.16b, v16.16b
+ // vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu
+ eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch
+ eor v8.16b, v8.16b, v9.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch
+ // vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt
+
+ tbl v4.16b, {v26.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu
+ tbl v12.16b, {v26.16b}, v10.16b
+ tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch
+ tbl v8.16b, {v8.16b},v5.16b
+ tbl v1.16b, {v27.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt
+ tbl v9.16b, {v27.16b}, v11.16b
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch
+ eor v8.16b, v8.16b, v12.16b
+ // vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu
+ eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch
+ eor v8.16b, v8.16b, v9.16b
+ // vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt
+
+ tbl v4.16b, {v28.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu
+ tbl v12.16b, {v28.16b}, v10.16b
+ tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch
+ tbl v8.16b, {v8.16b},v5.16b
+ tbl v1.16b, {v29.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt
+ tbl v9.16b, {v29.16b}, v11.16b
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch
+ eor v8.16b, v8.16b, v12.16b
+ // vmovdqa 0x40(%r10), %xmm4 # 4 : sbeu
+ eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch
+ eor v8.16b, v8.16b, v9.16b
+ // vmovdqa 0x50(%r10), %xmm1 # 0 : sbet
+
+ tbl v4.16b, {v30.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu
+ tbl v12.16b, {v30.16b}, v10.16b
+ tbl v0.16b, {v0.16b},v5.16b // vpshufb %xmm5, %xmm0, %xmm0 # MC ch
+ tbl v8.16b, {v8.16b},v5.16b
+ tbl v1.16b, {v31.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet
+ tbl v9.16b, {v31.16b}, v11.16b
+ eor v0.16b, v0.16b, v4.16b // vpxor %xmm4, %xmm0, %xmm0 # 4 = ch
+ eor v8.16b, v8.16b, v12.16b
+ ext v5.16b, v5.16b, v5.16b, #12 // vpalignr $12, %xmm5, %xmm5, %xmm5
+ eor v0.16b, v0.16b, v1.16b // vpxor %xmm1, %xmm0, %xmm0 # 0 = ch
+ eor v8.16b, v8.16b, v9.16b
+ sub w8, w8, #1 // sub $1,%rax # nr--
+
+.Ldec_2x_entry:
+ // top of round
+ and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k
+ ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i
+ and v9.16b, v8.16b, v17.16b
+ ushr v8.16b, v8.16b, #4
+ tbl v2.16b, {v19.16b},v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k
+ tbl v10.16b, {v19.16b},v9.16b
+ eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j
+ eor v9.16b, v9.16b, v8.16b
+ tbl v3.16b, {v18.16b},v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i
+ tbl v11.16b, {v18.16b},v8.16b
+ tbl v4.16b, {v18.16b},v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j
+ tbl v12.16b, {v18.16b},v9.16b
+ eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k
+ eor v11.16b, v11.16b, v10.16b
+ eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k
+ eor v12.16b, v12.16b, v10.16b
+ tbl v2.16b, {v18.16b},v3.16b // vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak
+ tbl v10.16b, {v18.16b},v11.16b
+ tbl v3.16b, {v18.16b},v4.16b // vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak
+ tbl v11.16b, {v18.16b},v12.16b
+ eor v2.16b, v2.16b, v1.16b // vpxor %xmm1, %xmm2, %xmm2 # 2 = io
+ eor v10.16b, v10.16b, v9.16b
+ eor v3.16b, v3.16b, v0.16b // vpxor %xmm0, %xmm3, %xmm3 # 3 = jo
+ eor v11.16b, v11.16b, v8.16b
+ ld1 {v16.2d}, [x9],#16 // vmovdqu (%r9), %xmm0
+ cbnz w8, .Ldec_2x_loop
+
+ // middle of last round
+ // vmovdqa 0x60(%r10), %xmm4 # 3 : sbou
+ tbl v4.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou
+ tbl v12.16b, {v22.16b}, v10.16b
+ // vmovdqa 0x70(%r10), %xmm1 # 0 : sbot
+ tbl v1.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t
+ tbl v9.16b, {v23.16b}, v11.16b
+ ld1 {v2.2d}, [x11] // vmovdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160
+ eor v4.16b, v4.16b, v16.16b // vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k
+ eor v12.16b, v12.16b, v16.16b
+ eor v0.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm0 # 0 = A
+ eor v8.16b, v9.16b, v12.16b
+ tbl v0.16b, {v0.16b},v2.16b // vpshufb %xmm2, %xmm0, %xmm0
+ tbl v1.16b, {v8.16b},v2.16b
+ ret
+.size _vpaes_decrypt_2x,.-_vpaes_decrypt_2x
+////////////////////////////////////////////////////////
+// //
+// AES key schedule //
+// //
+////////////////////////////////////////////////////////
+.type _vpaes_key_preheat,%function
+.align 4
+_vpaes_key_preheat:
+ adr x10, .Lk_inv
+ movi v16.16b, #0x5b // .Lk_s63
+ adr x11, .Lk_sb1
+ movi v17.16b, #0x0f // .Lk_s0F
+ ld1 {v18.2d,v19.2d,v20.2d,v21.2d}, [x10] // .Lk_inv, .Lk_ipt
+ adr x10, .Lk_dksd
+ ld1 {v22.2d,v23.2d}, [x11] // .Lk_sb1
+ adr x11, .Lk_mc_forward
+ ld1 {v24.2d,v25.2d,v26.2d,v27.2d}, [x10],#64 // .Lk_dksd, .Lk_dksb
+ ld1 {v28.2d,v29.2d,v30.2d,v31.2d}, [x10],#64 // .Lk_dkse, .Lk_dks9
+ ld1 {v8.2d}, [x10] // .Lk_rcon
+ ld1 {v9.2d}, [x11] // .Lk_mc_forward[0]
+ ret
+.size _vpaes_key_preheat,.-_vpaes_key_preheat
+
+.type _vpaes_schedule_core,%function
+.align 4
+_vpaes_schedule_core:
+.inst 0xd503233f // paciasp
+ stp x29, x30, [sp,#-16]!
+ add x29,sp,#0
+
+ bl _vpaes_key_preheat // load the tables
+
+ ld1 {v0.16b}, [x0],#16 // vmovdqu (%rdi), %xmm0 # load key (unaligned)
+
+ // input transform
+ mov v3.16b, v0.16b // vmovdqa %xmm0, %xmm3
+ bl _vpaes_schedule_transform
+ mov v7.16b, v0.16b // vmovdqa %xmm0, %xmm7
+
+ adr x10, .Lk_sr // lea .Lk_sr(%rip),%r10
+ add x8, x8, x10
+ cbnz w3, .Lschedule_am_decrypting
+
+ // encrypting, output zeroth round key after transform
+ st1 {v0.2d}, [x2] // vmovdqu %xmm0, (%rdx)
+ b .Lschedule_go
+
+.Lschedule_am_decrypting:
+ // decrypting, output zeroth round key after shiftrows
+ ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1
+ tbl v3.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3
+ st1 {v3.2d}, [x2] // vmovdqu %xmm3, (%rdx)
+ eor x8, x8, #0x30 // xor $0x30, %r8
+
+.Lschedule_go:
+ cmp w1, #192 // cmp $192, %esi
+ b.hi .Lschedule_256
+ b.eq .Lschedule_192
+ // 128: fall though
+
+//
+// .schedule_128
+//
+// 128-bit specific part of key schedule.
+//
+// This schedule is really simple, because all its parts
+// are accomplished by the subroutines.
+//
+.Lschedule_128:
+ mov x0, #10 // mov $10, %esi
+
+.Loop_schedule_128:
+ sub x0, x0, #1 // dec %esi
+ bl _vpaes_schedule_round
+ cbz x0, .Lschedule_mangle_last
+ bl _vpaes_schedule_mangle // write output
+ b .Loop_schedule_128
+
+//
+// .aes_schedule_192
+//
+// 192-bit specific part of key schedule.
+//
+// The main body of this schedule is the same as the 128-bit
+// schedule, but with more smearing. The long, high side is
+// stored in %xmm7 as before, and the short, low side is in
+// the high bits of %xmm6.
+//
+// This schedule is somewhat nastier, however, because each
+// round produces 192 bits of key material, or 1.5 round keys.
+// Therefore, on each cycle we do 2 rounds and produce 3 round
+// keys.
+//
+.align 4
+.Lschedule_192:
+ sub x0, x0, #8
+ ld1 {v0.16b}, [x0] // vmovdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned)
+ bl _vpaes_schedule_transform // input transform
+ mov v6.16b, v0.16b // vmovdqa %xmm0, %xmm6 # save short part
+ eor v4.16b, v4.16b, v4.16b // vpxor %xmm4, %xmm4, %xmm4 # clear 4
+ ins v6.d[0], v4.d[0] // vmovhlps %xmm4, %xmm6, %xmm6 # clobber low side with zeros
+ mov x0, #4 // mov $4, %esi
+
+.Loop_schedule_192:
+ sub x0, x0, #1 // dec %esi
+ bl _vpaes_schedule_round
+ ext v0.16b, v6.16b, v0.16b, #8 // vpalignr $8,%xmm6,%xmm0,%xmm0
+ bl _vpaes_schedule_mangle // save key n
+ bl _vpaes_schedule_192_smear
+ bl _vpaes_schedule_mangle // save key n+1
+ bl _vpaes_schedule_round
+ cbz x0, .Lschedule_mangle_last
+ bl _vpaes_schedule_mangle // save key n+2
+ bl _vpaes_schedule_192_smear
+ b .Loop_schedule_192
+
+//
+// .aes_schedule_256
+//
+// 256-bit specific part of key schedule.
+//
+// The structure here is very similar to the 128-bit
+// schedule, but with an additional "low side" in
+// %xmm6. The low side's rounds are the same as the
+// high side's, except no rcon and no rotation.
+//
+.align 4
+.Lschedule_256:
+ ld1 {v0.16b}, [x0] // vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned)
+ bl _vpaes_schedule_transform // input transform
+ mov x0, #7 // mov $7, %esi
+
+.Loop_schedule_256:
+ sub x0, x0, #1 // dec %esi
+ bl _vpaes_schedule_mangle // output low result
+ mov v6.16b, v0.16b // vmovdqa %xmm0, %xmm6 # save cur_lo in xmm6
+
+ // high round
+ bl _vpaes_schedule_round
+ cbz x0, .Lschedule_mangle_last
+ bl _vpaes_schedule_mangle
+
+ // low round. swap xmm7 and xmm6
+ dup v0.4s, v0.s[3] // vpshufd $0xFF, %xmm0, %xmm0
+ movi v4.16b, #0
+ mov v5.16b, v7.16b // vmovdqa %xmm7, %xmm5
+ mov v7.16b, v6.16b // vmovdqa %xmm6, %xmm7
+ bl _vpaes_schedule_low_round
+ mov v7.16b, v5.16b // vmovdqa %xmm5, %xmm7
+
+ b .Loop_schedule_256
+
+//
+// .aes_schedule_mangle_last
+//
+// Mangler for last round of key schedule
+// Mangles %xmm0
+// when encrypting, outputs out(%xmm0) ^ 63
+// when decrypting, outputs unskew(%xmm0)
+//
+// Always called right before return... jumps to cleanup and exits
+//
+.align 4
+.Lschedule_mangle_last:
+ // schedule last round key from xmm0
+ adr x11, .Lk_deskew // lea .Lk_deskew(%rip),%r11 # prepare to deskew
+ cbnz w3, .Lschedule_mangle_last_dec
+
+ // encrypting
+ ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10),%xmm1
+ adr x11, .Lk_opt // lea .Lk_opt(%rip), %r11 # prepare to output transform
+ add x2, x2, #32 // add $32, %rdx
+ tbl v0.16b, {v0.16b}, v1.16b // vpshufb %xmm1, %xmm0, %xmm0 # output permute
+
+.Lschedule_mangle_last_dec:
+ ld1 {v20.2d,v21.2d}, [x11] // reload constants
+ sub x2, x2, #16 // add $-16, %rdx
+ eor v0.16b, v0.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm0, %xmm0
+ bl _vpaes_schedule_transform // output transform
+ st1 {v0.2d}, [x2] // vmovdqu %xmm0, (%rdx) # save last key
+
+ // cleanup
+ eor v0.16b, v0.16b, v0.16b // vpxor %xmm0, %xmm0, %xmm0
+ eor v1.16b, v1.16b, v1.16b // vpxor %xmm1, %xmm1, %xmm1
+ eor v2.16b, v2.16b, v2.16b // vpxor %xmm2, %xmm2, %xmm2
+ eor v3.16b, v3.16b, v3.16b // vpxor %xmm3, %xmm3, %xmm3
+ eor v4.16b, v4.16b, v4.16b // vpxor %xmm4, %xmm4, %xmm4
+ eor v5.16b, v5.16b, v5.16b // vpxor %xmm5, %xmm5, %xmm5
+ eor v6.16b, v6.16b, v6.16b // vpxor %xmm6, %xmm6, %xmm6
+ eor v7.16b, v7.16b, v7.16b // vpxor %xmm7, %xmm7, %xmm7
+ ldp x29, x30, [sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size _vpaes_schedule_core,.-_vpaes_schedule_core
+
+//
+// .aes_schedule_192_smear
+//
+// Smear the short, low side in the 192-bit key schedule.
+//
+// Inputs:
+// %xmm7: high side, b a x y
+// %xmm6: low side, d c 0 0
+// %xmm13: 0
+//
+// Outputs:
+// %xmm6: b+c+d b+c 0 0
+// %xmm0: b+c+d b+c b a
+//
+.type _vpaes_schedule_192_smear,%function
+.align 4
+_vpaes_schedule_192_smear:
+ movi v1.16b, #0
+ dup v0.4s, v7.s[3]
+ ins v1.s[3], v6.s[2] // vpshufd $0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0
+ ins v0.s[0], v7.s[2] // vpshufd $0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a
+ eor v6.16b, v6.16b, v1.16b // vpxor %xmm1, %xmm6, %xmm6 # -> c+d c 0 0
+ eor v1.16b, v1.16b, v1.16b // vpxor %xmm1, %xmm1, %xmm1
+ eor v6.16b, v6.16b, v0.16b // vpxor %xmm0, %xmm6, %xmm6 # -> b+c+d b+c b a
+ mov v0.16b, v6.16b // vmovdqa %xmm6, %xmm0
+ ins v6.d[0], v1.d[0] // vmovhlps %xmm1, %xmm6, %xmm6 # clobber low side with zeros
+ ret
+.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
+
+//
+// .aes_schedule_round
+//
+// Runs one main round of the key schedule on %xmm0, %xmm7
+//
+// Specifically, runs subbytes on the high dword of %xmm0
+// then rotates it by one byte and xors into the low dword of
+// %xmm7.
+//
+// Adds rcon from low byte of %xmm8, then rotates %xmm8 for
+// next rcon.
+//
+// Smears the dwords of %xmm7 by xoring the low into the
+// second low, result into third, result into highest.
+//
+// Returns results in %xmm7 = %xmm0.
+// Clobbers %xmm1-%xmm4, %r11.
+//
+.type _vpaes_schedule_round,%function
+.align 4
+_vpaes_schedule_round:
+ // extract rcon from xmm8
+ movi v4.16b, #0 // vpxor %xmm4, %xmm4, %xmm4
+ ext v1.16b, v8.16b, v4.16b, #15 // vpalignr $15, %xmm8, %xmm4, %xmm1
+ ext v8.16b, v8.16b, v8.16b, #15 // vpalignr $15, %xmm8, %xmm8, %xmm8
+ eor v7.16b, v7.16b, v1.16b // vpxor %xmm1, %xmm7, %xmm7
+
+ // rotate
+ dup v0.4s, v0.s[3] // vpshufd $0xFF, %xmm0, %xmm0
+ ext v0.16b, v0.16b, v0.16b, #1 // vpalignr $1, %xmm0, %xmm0, %xmm0
+
+ // fall through...
+
+ // low round: same as high round, but no rotation and no rcon.
+_vpaes_schedule_low_round:
+ // smear xmm7
+ ext v1.16b, v4.16b, v7.16b, #12 // vpslldq $4, %xmm7, %xmm1
+ eor v7.16b, v7.16b, v1.16b // vpxor %xmm1, %xmm7, %xmm7
+ ext v4.16b, v4.16b, v7.16b, #8 // vpslldq $8, %xmm7, %xmm4
+
+ // subbytes
+ and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1 # 0 = k
+ ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0 # 1 = i
+ eor v7.16b, v7.16b, v4.16b // vpxor %xmm4, %xmm7, %xmm7
+ tbl v2.16b, {v19.16b}, v1.16b // vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k
+ eor v1.16b, v1.16b, v0.16b // vpxor %xmm0, %xmm1, %xmm1 # 0 = j
+ tbl v3.16b, {v18.16b}, v0.16b // vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i
+ eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k
+ tbl v4.16b, {v18.16b}, v1.16b // vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j
+ eor v7.16b, v7.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm7, %xmm7
+ tbl v3.16b, {v18.16b}, v3.16b // vpshufb %xmm3, %xmm10, %xmm3 # 2 = 1/iak
+ eor v4.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k
+ tbl v2.16b, {v18.16b}, v4.16b // vpshufb %xmm4, %xmm10, %xmm2 # 3 = 1/jak
+ eor v3.16b, v3.16b, v1.16b // vpxor %xmm1, %xmm3, %xmm3 # 2 = io
+ eor v2.16b, v2.16b, v0.16b // vpxor %xmm0, %xmm2, %xmm2 # 3 = jo
+ tbl v4.16b, {v23.16b}, v3.16b // vpshufb %xmm3, %xmm13, %xmm4 # 4 = sbou
+ tbl v1.16b, {v22.16b}, v2.16b // vpshufb %xmm2, %xmm12, %xmm1 # 0 = sb1t
+ eor v1.16b, v1.16b, v4.16b // vpxor %xmm4, %xmm1, %xmm1 # 0 = sbox output
+
+ // add in smeared stuff
+ eor v0.16b, v1.16b, v7.16b // vpxor %xmm7, %xmm1, %xmm0
+ eor v7.16b, v1.16b, v7.16b // vmovdqa %xmm0, %xmm7
+ ret
+.size _vpaes_schedule_round,.-_vpaes_schedule_round
+
+//
+// .aes_schedule_transform
+//
+// Linear-transform %xmm0 according to tables at (%r11)
+//
+// Requires that %xmm9 = 0x0F0F... as in preheat
+// Output in %xmm0
+// Clobbers %xmm1, %xmm2
+//
+.type _vpaes_schedule_transform,%function
+.align 4
+_vpaes_schedule_transform:
+ and v1.16b, v0.16b, v17.16b // vpand %xmm9, %xmm0, %xmm1
+ ushr v0.16b, v0.16b, #4 // vpsrlb $4, %xmm0, %xmm0
+ // vmovdqa (%r11), %xmm2 # lo
+ tbl v2.16b, {v20.16b}, v1.16b // vpshufb %xmm1, %xmm2, %xmm2
+ // vmovdqa 16(%r11), %xmm1 # hi
+ tbl v0.16b, {v21.16b}, v0.16b // vpshufb %xmm0, %xmm1, %xmm0
+ eor v0.16b, v0.16b, v2.16b // vpxor %xmm2, %xmm0, %xmm0
+ ret
+.size _vpaes_schedule_transform,.-_vpaes_schedule_transform
+
+//
+// .aes_schedule_mangle
+//
+// Mangle xmm0 from (basis-transformed) standard version
+// to our version.
+//
+// On encrypt,
+// xor with 0x63
+// multiply by circulant 0,1,1,1
+// apply shiftrows transform
+//
+// On decrypt,
+// xor with 0x63
+// multiply by "inverse mixcolumns" circulant E,B,D,9
+// deskew
+// apply shiftrows transform
+//
+//
+// Writes out to (%rdx), and increments or decrements it
+// Keeps track of round number mod 4 in %r8
+// Preserves xmm0
+// Clobbers xmm1-xmm5
+//
+.type _vpaes_schedule_mangle,%function
+.align 4
+_vpaes_schedule_mangle:
+ mov v4.16b, v0.16b // vmovdqa %xmm0, %xmm4 # save xmm0 for later
+ // vmovdqa .Lk_mc_forward(%rip),%xmm5
+ cbnz w3, .Lschedule_mangle_dec
+
+ // encrypting
+ eor v4.16b, v0.16b, v16.16b // vpxor .Lk_s63(%rip), %xmm0, %xmm4
+ add x2, x2, #16 // add $16, %rdx
+ tbl v4.16b, {v4.16b}, v9.16b // vpshufb %xmm5, %xmm4, %xmm4
+ tbl v1.16b, {v4.16b}, v9.16b // vpshufb %xmm5, %xmm4, %xmm1
+ tbl v3.16b, {v1.16b}, v9.16b // vpshufb %xmm5, %xmm1, %xmm3
+ eor v4.16b, v4.16b, v1.16b // vpxor %xmm1, %xmm4, %xmm4
+ ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1
+ eor v3.16b, v3.16b, v4.16b // vpxor %xmm4, %xmm3, %xmm3
+
+ b .Lschedule_mangle_both
+.align 4
+.Lschedule_mangle_dec:
+ // inverse mix columns
+ // lea .Lk_dksd(%rip),%r11
+ ushr v1.16b, v4.16b, #4 // vpsrlb $4, %xmm4, %xmm1 # 1 = hi
+ and v4.16b, v4.16b, v17.16b // vpand %xmm9, %xmm4, %xmm4 # 4 = lo
+
+ // vmovdqa 0x00(%r11), %xmm2
+ tbl v2.16b, {v24.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2
+ // vmovdqa 0x10(%r11), %xmm3
+ tbl v3.16b, {v25.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3
+ eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3
+ tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3
+
+ // vmovdqa 0x20(%r11), %xmm2
+ tbl v2.16b, {v26.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2
+ eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2
+ // vmovdqa 0x30(%r11), %xmm3
+ tbl v3.16b, {v27.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3
+ eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3
+ tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3
+
+ // vmovdqa 0x40(%r11), %xmm2
+ tbl v2.16b, {v28.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2
+ eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2
+ // vmovdqa 0x50(%r11), %xmm3
+ tbl v3.16b, {v29.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3
+ eor v3.16b, v3.16b, v2.16b // vpxor %xmm2, %xmm3, %xmm3
+
+ // vmovdqa 0x60(%r11), %xmm2
+ tbl v2.16b, {v30.16b}, v4.16b // vpshufb %xmm4, %xmm2, %xmm2
+ tbl v3.16b, {v3.16b}, v9.16b // vpshufb %xmm5, %xmm3, %xmm3
+ // vmovdqa 0x70(%r11), %xmm4
+ tbl v4.16b, {v31.16b}, v1.16b // vpshufb %xmm1, %xmm4, %xmm4
+ ld1 {v1.2d}, [x8] // vmovdqa (%r8,%r10), %xmm1
+ eor v2.16b, v2.16b, v3.16b // vpxor %xmm3, %xmm2, %xmm2
+ eor v3.16b, v4.16b, v2.16b // vpxor %xmm2, %xmm4, %xmm3
+
+ sub x2, x2, #16 // add $-16, %rdx
+
+.Lschedule_mangle_both:
+ tbl v3.16b, {v3.16b}, v1.16b // vpshufb %xmm1, %xmm3, %xmm3
+ add x8, x8, #64-16 // add $-16, %r8
+ and x8, x8, #~(1<<6) // and $0x30, %r8
+ st1 {v3.2d}, [x2] // vmovdqu %xmm3, (%rdx)
+ ret
+.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle
+
+.globl vpaes_set_encrypt_key
+.type vpaes_set_encrypt_key,%function
+.align 4
+vpaes_set_encrypt_key:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ stp d8,d9,[sp,#-16]! // ABI spec says so
+
+ lsr w9, w1, #5 // shr $5,%eax
+ add w9, w9, #5 // $5,%eax
+ str w9, [x2,#240] // mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5;
+
+ mov w3, #0 // mov $0,%ecx
+ mov x8, #0x30 // mov $0x30,%r8d
+ bl _vpaes_schedule_core
+ eor x0, x0, x0
+
+ ldp d8,d9,[sp],#16
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key
+
+.globl vpaes_set_decrypt_key
+.type vpaes_set_decrypt_key,%function
+.align 4
+vpaes_set_decrypt_key:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ stp d8,d9,[sp,#-16]! // ABI spec says so
+
+ lsr w9, w1, #5 // shr $5,%eax
+ add w9, w9, #5 // $5,%eax
+ str w9, [x2,#240] // mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5;
+ lsl w9, w9, #4 // shl $4,%eax
+ add x2, x2, #16 // lea 16(%rdx,%rax),%rdx
+ add x2, x2, x9
+
+ mov w3, #1 // mov $1,%ecx
+ lsr w8, w1, #1 // shr $1,%r8d
+ and x8, x8, #32 // and $32,%r8d
+ eor x8, x8, #32 // xor $32,%r8d # nbits==192?0:32
+ bl _vpaes_schedule_core
+
+ ldp d8,d9,[sp],#16
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key
+.globl vpaes_cbc_encrypt
+.type vpaes_cbc_encrypt,%function
+.align 4
+vpaes_cbc_encrypt:
+ cbz x2, .Lcbc_abort
+ cmp w5, #0 // check direction
+ b.eq vpaes_cbc_decrypt
+
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ mov x17, x2 // reassign
+ mov x2, x3 // reassign
+
+ ld1 {v0.16b}, [x4] // load ivec
+ bl _vpaes_encrypt_preheat
+ b .Lcbc_enc_loop
+
+.align 4
+.Lcbc_enc_loop:
+ ld1 {v7.16b}, [x0],#16 // load input
+ eor v7.16b, v7.16b, v0.16b // xor with ivec
+ bl _vpaes_encrypt_core
+ st1 {v0.16b}, [x1],#16 // save output
+ subs x17, x17, #16
+ b.hi .Lcbc_enc_loop
+
+ st1 {v0.16b}, [x4] // write ivec
+
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+.Lcbc_abort:
+ ret
+.size vpaes_cbc_encrypt,.-vpaes_cbc_encrypt
+
+.type vpaes_cbc_decrypt,%function
+.align 4
+vpaes_cbc_decrypt:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ stp d8,d9,[sp,#-16]! // ABI spec says so
+ stp d10,d11,[sp,#-16]!
+ stp d12,d13,[sp,#-16]!
+ stp d14,d15,[sp,#-16]!
+
+ mov x17, x2 // reassign
+ mov x2, x3 // reassign
+ ld1 {v6.16b}, [x4] // load ivec
+ bl _vpaes_decrypt_preheat
+ tst x17, #16
+ b.eq .Lcbc_dec_loop2x
+
+ ld1 {v7.16b}, [x0], #16 // load input
+ bl _vpaes_decrypt_core
+ eor v0.16b, v0.16b, v6.16b // xor with ivec
+ orr v6.16b, v7.16b, v7.16b // next ivec value
+ st1 {v0.16b}, [x1], #16
+ subs x17, x17, #16
+ b.ls .Lcbc_dec_done
+
+.align 4
+.Lcbc_dec_loop2x:
+ ld1 {v14.16b,v15.16b}, [x0], #32
+ bl _vpaes_decrypt_2x
+ eor v0.16b, v0.16b, v6.16b // xor with ivec
+ eor v1.16b, v1.16b, v14.16b
+ orr v6.16b, v15.16b, v15.16b
+ st1 {v0.16b,v1.16b}, [x1], #32
+ subs x17, x17, #32
+ b.hi .Lcbc_dec_loop2x
+
+.Lcbc_dec_done:
+ st1 {v6.16b}, [x4]
+
+ ldp d14,d15,[sp],#16
+ ldp d12,d13,[sp],#16
+ ldp d10,d11,[sp],#16
+ ldp d8,d9,[sp],#16
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size vpaes_cbc_decrypt,.-vpaes_cbc_decrypt
+.globl vpaes_ecb_encrypt
+.type vpaes_ecb_encrypt,%function
+.align 4
+vpaes_ecb_encrypt:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ stp d8,d9,[sp,#-16]! // ABI spec says so
+ stp d10,d11,[sp,#-16]!
+ stp d12,d13,[sp,#-16]!
+ stp d14,d15,[sp,#-16]!
+
+ mov x17, x2
+ mov x2, x3
+ bl _vpaes_encrypt_preheat
+ tst x17, #16
+ b.eq .Lecb_enc_loop
+
+ ld1 {v7.16b}, [x0],#16
+ bl _vpaes_encrypt_core
+ st1 {v0.16b}, [x1],#16
+ subs x17, x17, #16
+ b.ls .Lecb_enc_done
+
+.align 4
+.Lecb_enc_loop:
+ ld1 {v14.16b,v15.16b}, [x0], #32
+ bl _vpaes_encrypt_2x
+ st1 {v0.16b,v1.16b}, [x1], #32
+ subs x17, x17, #32
+ b.hi .Lecb_enc_loop
+
+.Lecb_enc_done:
+ ldp d14,d15,[sp],#16
+ ldp d12,d13,[sp],#16
+ ldp d10,d11,[sp],#16
+ ldp d8,d9,[sp],#16
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size vpaes_ecb_encrypt,.-vpaes_ecb_encrypt
+
+.globl vpaes_ecb_decrypt
+.type vpaes_ecb_decrypt,%function
+.align 4
+vpaes_ecb_decrypt:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ stp d8,d9,[sp,#-16]! // ABI spec says so
+ stp d10,d11,[sp,#-16]!
+ stp d12,d13,[sp,#-16]!
+ stp d14,d15,[sp,#-16]!
+
+ mov x17, x2
+ mov x2, x3
+ bl _vpaes_decrypt_preheat
+ tst x17, #16
+ b.eq .Lecb_dec_loop
+
+ ld1 {v7.16b}, [x0],#16
+ bl _vpaes_encrypt_core
+ st1 {v0.16b}, [x1],#16
+ subs x17, x17, #16
+ b.ls .Lecb_dec_done
+
+.align 4
+.Lecb_dec_loop:
+ ld1 {v14.16b,v15.16b}, [x0], #32
+ bl _vpaes_decrypt_2x
+ st1 {v0.16b,v1.16b}, [x1], #32
+ subs x17, x17, #32
+ b.hi .Lecb_dec_loop
+
+.Lecb_dec_done:
+ ldp d14,d15,[sp],#16
+ ldp d12,d13,[sp],#16
+ ldp d10,d11,[sp],#16
+ ldp d8,d9,[sp],#16
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size vpaes_ecb_decrypt,.-vpaes_ecb_decrypt
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/arm64cpuid.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/arm64cpuid.S
new file mode 100644
index 0000000..297d507
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/arm64cpuid.S
@@ -0,0 +1,129 @@
+#include "arm_arch.h"
+
+.text
+.arch armv8-a+crypto
+
+.align 5
+.globl _armv7_neon_probe
+.type _armv7_neon_probe,%function
+_armv7_neon_probe:
+ orr v15.16b, v15.16b, v15.16b
+ ret
+.size _armv7_neon_probe,.-_armv7_neon_probe
+
+.globl _armv7_tick
+.type _armv7_tick,%function
+_armv7_tick:
+#ifdef __APPLE__
+ mrs x0, CNTPCT_EL0
+#else
+ mrs x0, CNTVCT_EL0
+#endif
+ ret
+.size _armv7_tick,.-_armv7_tick
+
+.globl _armv8_aes_probe
+.type _armv8_aes_probe,%function
+_armv8_aes_probe:
+ aese v0.16b, v0.16b
+ ret
+.size _armv8_aes_probe,.-_armv8_aes_probe
+
+.globl _armv8_sha1_probe
+.type _armv8_sha1_probe,%function
+_armv8_sha1_probe:
+ sha1h s0, s0
+ ret
+.size _armv8_sha1_probe,.-_armv8_sha1_probe
+
+.globl _armv8_sha256_probe
+.type _armv8_sha256_probe,%function
+_armv8_sha256_probe:
+ sha256su0 v0.4s, v0.4s
+ ret
+.size _armv8_sha256_probe,.-_armv8_sha256_probe
+
+.globl _armv8_pmull_probe
+.type _armv8_pmull_probe,%function
+_armv8_pmull_probe:
+ pmull v0.1q, v0.1d, v0.1d
+ ret
+.size _armv8_pmull_probe,.-_armv8_pmull_probe
+
+.globl _armv8_sha512_probe
+.type _armv8_sha512_probe,%function
+_armv8_sha512_probe:
+.long 0xcec08000 // sha512su0 v0.2d,v0.2d
+ ret
+.size _armv8_sha512_probe,.-_armv8_sha512_probe
+
+.globl _armv8_cpuid_probe
+.type _armv8_cpuid_probe,%function
+_armv8_cpuid_probe:
+ mrs x0, midr_el1
+ ret
+.size _armv8_cpuid_probe,.-_armv8_cpuid_probe
+
+.globl OPENSSL_cleanse
+.type OPENSSL_cleanse,%function
+.align 5
+OPENSSL_cleanse:
+ cbz x1,.Lret // len==0?
+ cmp x1,#15
+ b.hi .Lot // len>15
+ nop
+.Little:
+ strb wzr,[x0],#1 // store byte-by-byte
+ subs x1,x1,#1
+ b.ne .Little
+.Lret: ret
+
+.align 4
+.Lot: tst x0,#7
+ b.eq .Laligned // inp is aligned
+ strb wzr,[x0],#1 // store byte-by-byte
+ sub x1,x1,#1
+ b .Lot
+
+.align 4
+.Laligned:
+ str xzr,[x0],#8 // store word-by-word
+ sub x1,x1,#8
+ tst x1,#-8
+ b.ne .Laligned // len>=8
+ cbnz x1,.Little // len!=0?
+ ret
+.size OPENSSL_cleanse,.-OPENSSL_cleanse
+
+.globl CRYPTO_memcmp
+.type CRYPTO_memcmp,%function
+.align 4
+CRYPTO_memcmp:
+ eor w3,w3,w3
+ cbz x2,.Lno_data // len==0?
+ cmp x2,#16
+ b.ne .Loop_cmp
+ ldp x8,x9,[x0]
+ ldp x10,x11,[x1]
+ eor x8,x8,x10
+ eor x9,x9,x11
+ orr x8,x8,x9
+ mov x0,#1
+ cmp x8,#0
+ csel x0,xzr,x0,eq
+ ret
+
+.align 4
+.Loop_cmp:
+ ldrb w4,[x0],#1
+ ldrb w5,[x1],#1
+ eor w4,w4,w5
+ orr w3,w3,w4
+ subs x2,x2,#1
+ b.ne .Loop_cmp
+
+.Lno_data:
+ neg w0,w3
+ lsr w0,w0,#31
+ ret
+.size CRYPTO_memcmp,.-CRYPTO_memcmp
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/bn/armv8-mont.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/bn/armv8-mont.S
new file mode 100644
index 0000000..7448af9
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/bn/armv8-mont.S
@@ -0,0 +1,2124 @@
+#ifndef __KERNEL__
+# include "arm_arch.h"
+
+.hidden OPENSSL_armv8_rsa_neonized
+#endif
+.text
+
+.globl bn_mul_mont
+.type bn_mul_mont,%function
+.align 5
+bn_mul_mont:
+.Lbn_mul_mont:
+ tst x5,#3
+ b.ne .Lmul_mont
+ cmp x5,#32
+ b.le .Lscalar_impl
+#ifndef __KERNEL__
+ adrp x17,OPENSSL_armv8_rsa_neonized
+ ldr w17,[x17,#:lo12:OPENSSL_armv8_rsa_neonized]
+ cbnz w17, bn_mul8x_mont_neon
+#endif
+
+.Lscalar_impl:
+ tst x5,#7
+ b.eq __bn_sqr8x_mont
+ tst x5,#3
+ b.eq __bn_mul4x_mont
+
+.Lmul_mont:
+ stp x29,x30,[sp,#-64]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+
+ ldr x9,[x2],#8 // bp[0]
+ sub x22,sp,x5,lsl#3
+ ldp x7,x8,[x1],#16 // ap[0..1]
+ lsl x5,x5,#3
+ ldr x4,[x4] // *n0
+ and x22,x22,#-16 // ABI says so
+ ldp x13,x14,[x3],#16 // np[0..1]
+
+ mul x6,x7,x9 // ap[0]*bp[0]
+ sub x21,x5,#16 // j=num-2
+ umulh x7,x7,x9
+ mul x10,x8,x9 // ap[1]*bp[0]
+ umulh x11,x8,x9
+
+ mul x15,x6,x4 // "tp[0]"*n0
+ mov sp,x22 // alloca
+
+ // (*) mul x12,x13,x15 // np[0]*m1
+ umulh x13,x13,x15
+ mul x16,x14,x15 // np[1]*m1
+ // (*) adds x12,x12,x6 // discarded
+ // (*) As for removal of first multiplication and addition
+ // instructions. The outcome of first addition is
+ // guaranteed to be zero, which leaves two computationally
+ // significant outcomes: it either carries or not. Then
+ // question is when does it carry? Is there alternative
+ // way to deduce it? If you follow operations, you can
+ // observe that condition for carry is quite simple:
+ // x6 being non-zero. So that carry can be calculated
+ // by adding -1 to x6. That's what next instruction does.
+ subs xzr,x6,#1 // (*)
+ umulh x17,x14,x15
+ adc x13,x13,xzr
+ cbz x21,.L1st_skip
+
+.L1st:
+ ldr x8,[x1],#8
+ adds x6,x10,x7
+ sub x21,x21,#8 // j--
+ adc x7,x11,xzr
+
+ ldr x14,[x3],#8
+ adds x12,x16,x13
+ mul x10,x8,x9 // ap[j]*bp[0]
+ adc x13,x17,xzr
+ umulh x11,x8,x9
+
+ adds x12,x12,x6
+ mul x16,x14,x15 // np[j]*m1
+ adc x13,x13,xzr
+ umulh x17,x14,x15
+ str x12,[x22],#8 // tp[j-1]
+ cbnz x21,.L1st
+
+.L1st_skip:
+ adds x6,x10,x7
+ sub x1,x1,x5 // rewind x1
+ adc x7,x11,xzr
+
+ adds x12,x16,x13
+ sub x3,x3,x5 // rewind x3
+ adc x13,x17,xzr
+
+ adds x12,x12,x6
+ sub x20,x5,#8 // i=num-1
+ adcs x13,x13,x7
+
+ adc x19,xzr,xzr // upmost overflow bit
+ stp x12,x13,[x22]
+
+.Louter:
+ ldr x9,[x2],#8 // bp[i]
+ ldp x7,x8,[x1],#16
+ ldr x23,[sp] // tp[0]
+ add x22,sp,#8
+
+ mul x6,x7,x9 // ap[0]*bp[i]
+ sub x21,x5,#16 // j=num-2
+ umulh x7,x7,x9
+ ldp x13,x14,[x3],#16
+ mul x10,x8,x9 // ap[1]*bp[i]
+ adds x6,x6,x23
+ umulh x11,x8,x9
+ adc x7,x7,xzr
+
+ mul x15,x6,x4
+ sub x20,x20,#8 // i--
+
+ // (*) mul x12,x13,x15 // np[0]*m1
+ umulh x13,x13,x15
+ mul x16,x14,x15 // np[1]*m1
+ // (*) adds x12,x12,x6
+ subs xzr,x6,#1 // (*)
+ umulh x17,x14,x15
+ cbz x21,.Linner_skip
+
+.Linner:
+ ldr x8,[x1],#8
+ adc x13,x13,xzr
+ ldr x23,[x22],#8 // tp[j]
+ adds x6,x10,x7
+ sub x21,x21,#8 // j--
+ adc x7,x11,xzr
+
+ adds x12,x16,x13
+ ldr x14,[x3],#8
+ adc x13,x17,xzr
+
+ mul x10,x8,x9 // ap[j]*bp[i]
+ adds x6,x6,x23
+ umulh x11,x8,x9
+ adc x7,x7,xzr
+
+ mul x16,x14,x15 // np[j]*m1
+ adds x12,x12,x6
+ umulh x17,x14,x15
+ stur x12,[x22,#-16] // tp[j-1]
+ cbnz x21,.Linner
+
+.Linner_skip:
+ ldr x23,[x22],#8 // tp[j]
+ adc x13,x13,xzr
+ adds x6,x10,x7
+ sub x1,x1,x5 // rewind x1
+ adc x7,x11,xzr
+
+ adds x12,x16,x13
+ sub x3,x3,x5 // rewind x3
+ adcs x13,x17,x19
+ adc x19,xzr,xzr
+
+ adds x6,x6,x23
+ adc x7,x7,xzr
+
+ adds x12,x12,x6
+ adcs x13,x13,x7
+ adc x19,x19,xzr // upmost overflow bit
+ stp x12,x13,[x22,#-16]
+
+ cbnz x20,.Louter
+
+ // Final step. We see if result is larger than modulus, and
+ // if it is, subtract the modulus. But comparison implies
+ // subtraction. So we subtract modulus, see if it borrowed,
+ // and conditionally copy original value.
+ ldr x23,[sp] // tp[0]
+ add x22,sp,#8
+ ldr x14,[x3],#8 // np[0]
+ subs x21,x5,#8 // j=num-1 and clear borrow
+ mov x1,x0
+.Lsub:
+ sbcs x8,x23,x14 // tp[j]-np[j]
+ ldr x23,[x22],#8
+ sub x21,x21,#8 // j--
+ ldr x14,[x3],#8
+ str x8,[x1],#8 // rp[j]=tp[j]-np[j]
+ cbnz x21,.Lsub
+
+ sbcs x8,x23,x14
+ sbcs x19,x19,xzr // did it borrow?
+ str x8,[x1],#8 // rp[num-1]
+
+ ldr x23,[sp] // tp[0]
+ add x22,sp,#8
+ ldr x8,[x0],#8 // rp[0]
+ sub x5,x5,#8 // num--
+ nop
+.Lcond_copy:
+ sub x5,x5,#8 // num--
+ csel x14,x23,x8,lo // did it borrow?
+ ldr x23,[x22],#8
+ ldr x8,[x0],#8
+ stur xzr,[x22,#-16] // wipe tp
+ stur x14,[x0,#-16]
+ cbnz x5,.Lcond_copy
+
+ csel x14,x23,x8,lo
+ stur xzr,[x22,#-8] // wipe tp
+ stur x14,[x0,#-8]
+
+ ldp x19,x20,[x29,#16]
+ mov sp,x29
+ ldp x21,x22,[x29,#32]
+ mov x0,#1
+ ldp x23,x24,[x29,#48]
+ ldr x29,[sp],#64
+ ret
+.size bn_mul_mont,.-bn_mul_mont
+.type bn_mul8x_mont_neon,%function
+.align 5
+bn_mul8x_mont_neon:
+ stp x29,x30,[sp,#-80]!
+ mov x16,sp
+ stp d8,d9,[sp,#16]
+ stp d10,d11,[sp,#32]
+ stp d12,d13,[sp,#48]
+ stp d14,d15,[sp,#64]
+ lsl x5,x5,#1
+ eor v14.16b,v14.16b,v14.16b
+
+.align 4
+.LNEON_8n:
+ eor v6.16b,v6.16b,v6.16b
+ sub x7,sp,#128
+ eor v7.16b,v7.16b,v7.16b
+ sub x7,x7,x5,lsl#4
+ eor v8.16b,v8.16b,v8.16b
+ and x7,x7,#-64
+ eor v9.16b,v9.16b,v9.16b
+ mov sp,x7 // alloca
+ eor v10.16b,v10.16b,v10.16b
+ add x7,x7,#256
+ eor v11.16b,v11.16b,v11.16b
+ sub x8,x5,#8
+ eor v12.16b,v12.16b,v12.16b
+ eor v13.16b,v13.16b,v13.16b
+
+.LNEON_8n_init:
+ st1 {v6.2d,v7.2d},[x7],#32
+ subs x8,x8,#8
+ st1 {v8.2d,v9.2d},[x7],#32
+ st1 {v10.2d,v11.2d},[x7],#32
+ st1 {v12.2d,v13.2d},[x7],#32
+ bne .LNEON_8n_init
+
+ add x6,sp,#256
+ ld1 {v0.4s,v1.4s},[x1],#32
+ add x10,sp,#8
+ ldr s30,[x4],#4
+ mov x9,x5
+ b .LNEON_8n_outer
+
+.align 4
+.LNEON_8n_outer:
+ ldr s28,[x2],#4 // *b++
+ uxtl v28.4s,v28.4h
+ add x7,sp,#128
+ ld1 {v2.4s,v3.4s},[x3],#32
+
+ umlal v6.2d,v28.2s,v0.s[0]
+ umlal v7.2d,v28.2s,v0.s[1]
+ umlal v8.2d,v28.2s,v0.s[2]
+ shl v29.2d,v6.2d,#16
+ ext v29.16b,v29.16b,v29.16b,#8
+ umlal v9.2d,v28.2s,v0.s[3]
+ add v29.2d,v29.2d,v6.2d
+ umlal v10.2d,v28.2s,v1.s[0]
+ mul v29.2s,v29.2s,v30.2s
+ umlal v11.2d,v28.2s,v1.s[1]
+ st1 {v28.2s},[sp] // put aside smashed b[8*i+0]
+ umlal v12.2d,v28.2s,v1.s[2]
+ uxtl v29.4s,v29.4h
+ umlal v13.2d,v28.2s,v1.s[3]
+ ldr s28,[x2],#4 // *b++
+ umlal v6.2d,v29.2s,v2.s[0]
+ umlal v7.2d,v29.2s,v2.s[1]
+ uxtl v28.4s,v28.4h
+ umlal v8.2d,v29.2s,v2.s[2]
+ ushr v15.2d,v6.2d,#16
+ umlal v9.2d,v29.2s,v2.s[3]
+ umlal v10.2d,v29.2s,v3.s[0]
+ ext v6.16b,v6.16b,v6.16b,#8
+ add v6.2d,v6.2d,v15.2d
+ umlal v11.2d,v29.2s,v3.s[1]
+ ushr v6.2d,v6.2d,#16
+ umlal v12.2d,v29.2s,v3.s[2]
+ umlal v13.2d,v29.2s,v3.s[3]
+ add v16.2d,v7.2d,v6.2d
+ ins v7.d[0],v16.d[0]
+ st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+0]
+ umlal v7.2d,v28.2s,v0.s[0]
+ ld1 {v6.2d},[x6],#16
+ umlal v8.2d,v28.2s,v0.s[1]
+ umlal v9.2d,v28.2s,v0.s[2]
+ shl v29.2d,v7.2d,#16
+ ext v29.16b,v29.16b,v29.16b,#8
+ umlal v10.2d,v28.2s,v0.s[3]
+ add v29.2d,v29.2d,v7.2d
+ umlal v11.2d,v28.2s,v1.s[0]
+ mul v29.2s,v29.2s,v30.2s
+ umlal v12.2d,v28.2s,v1.s[1]
+ st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+1]
+ umlal v13.2d,v28.2s,v1.s[2]
+ uxtl v29.4s,v29.4h
+ umlal v6.2d,v28.2s,v1.s[3]
+ ldr s28,[x2],#4 // *b++
+ umlal v7.2d,v29.2s,v2.s[0]
+ umlal v8.2d,v29.2s,v2.s[1]
+ uxtl v28.4s,v28.4h
+ umlal v9.2d,v29.2s,v2.s[2]
+ ushr v15.2d,v7.2d,#16
+ umlal v10.2d,v29.2s,v2.s[3]
+ umlal v11.2d,v29.2s,v3.s[0]
+ ext v7.16b,v7.16b,v7.16b,#8
+ add v7.2d,v7.2d,v15.2d
+ umlal v12.2d,v29.2s,v3.s[1]
+ ushr v7.2d,v7.2d,#16
+ umlal v13.2d,v29.2s,v3.s[2]
+ umlal v6.2d,v29.2s,v3.s[3]
+ add v16.2d,v8.2d,v7.2d
+ ins v8.d[0],v16.d[0]
+ st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+1]
+ umlal v8.2d,v28.2s,v0.s[0]
+ ld1 {v7.2d},[x6],#16
+ umlal v9.2d,v28.2s,v0.s[1]
+ umlal v10.2d,v28.2s,v0.s[2]
+ shl v29.2d,v8.2d,#16
+ ext v29.16b,v29.16b,v29.16b,#8
+ umlal v11.2d,v28.2s,v0.s[3]
+ add v29.2d,v29.2d,v8.2d
+ umlal v12.2d,v28.2s,v1.s[0]
+ mul v29.2s,v29.2s,v30.2s
+ umlal v13.2d,v28.2s,v1.s[1]
+ st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+2]
+ umlal v6.2d,v28.2s,v1.s[2]
+ uxtl v29.4s,v29.4h
+ umlal v7.2d,v28.2s,v1.s[3]
+ ldr s28,[x2],#4 // *b++
+ umlal v8.2d,v29.2s,v2.s[0]
+ umlal v9.2d,v29.2s,v2.s[1]
+ uxtl v28.4s,v28.4h
+ umlal v10.2d,v29.2s,v2.s[2]
+ ushr v15.2d,v8.2d,#16
+ umlal v11.2d,v29.2s,v2.s[3]
+ umlal v12.2d,v29.2s,v3.s[0]
+ ext v8.16b,v8.16b,v8.16b,#8
+ add v8.2d,v8.2d,v15.2d
+ umlal v13.2d,v29.2s,v3.s[1]
+ ushr v8.2d,v8.2d,#16
+ umlal v6.2d,v29.2s,v3.s[2]
+ umlal v7.2d,v29.2s,v3.s[3]
+ add v16.2d,v9.2d,v8.2d
+ ins v9.d[0],v16.d[0]
+ st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+2]
+ umlal v9.2d,v28.2s,v0.s[0]
+ ld1 {v8.2d},[x6],#16
+ umlal v10.2d,v28.2s,v0.s[1]
+ umlal v11.2d,v28.2s,v0.s[2]
+ shl v29.2d,v9.2d,#16
+ ext v29.16b,v29.16b,v29.16b,#8
+ umlal v12.2d,v28.2s,v0.s[3]
+ add v29.2d,v29.2d,v9.2d
+ umlal v13.2d,v28.2s,v1.s[0]
+ mul v29.2s,v29.2s,v30.2s
+ umlal v6.2d,v28.2s,v1.s[1]
+ st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+3]
+ umlal v7.2d,v28.2s,v1.s[2]
+ uxtl v29.4s,v29.4h
+ umlal v8.2d,v28.2s,v1.s[3]
+ ldr s28,[x2],#4 // *b++
+ umlal v9.2d,v29.2s,v2.s[0]
+ umlal v10.2d,v29.2s,v2.s[1]
+ uxtl v28.4s,v28.4h
+ umlal v11.2d,v29.2s,v2.s[2]
+ ushr v15.2d,v9.2d,#16
+ umlal v12.2d,v29.2s,v2.s[3]
+ umlal v13.2d,v29.2s,v3.s[0]
+ ext v9.16b,v9.16b,v9.16b,#8
+ add v9.2d,v9.2d,v15.2d
+ umlal v6.2d,v29.2s,v3.s[1]
+ ushr v9.2d,v9.2d,#16
+ umlal v7.2d,v29.2s,v3.s[2]
+ umlal v8.2d,v29.2s,v3.s[3]
+ add v16.2d,v10.2d,v9.2d
+ ins v10.d[0],v16.d[0]
+ st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+3]
+ umlal v10.2d,v28.2s,v0.s[0]
+ ld1 {v9.2d},[x6],#16
+ umlal v11.2d,v28.2s,v0.s[1]
+ umlal v12.2d,v28.2s,v0.s[2]
+ shl v29.2d,v10.2d,#16
+ ext v29.16b,v29.16b,v29.16b,#8
+ umlal v13.2d,v28.2s,v0.s[3]
+ add v29.2d,v29.2d,v10.2d
+ umlal v6.2d,v28.2s,v1.s[0]
+ mul v29.2s,v29.2s,v30.2s
+ umlal v7.2d,v28.2s,v1.s[1]
+ st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+4]
+ umlal v8.2d,v28.2s,v1.s[2]
+ uxtl v29.4s,v29.4h
+ umlal v9.2d,v28.2s,v1.s[3]
+ ldr s28,[x2],#4 // *b++
+ umlal v10.2d,v29.2s,v2.s[0]
+ umlal v11.2d,v29.2s,v2.s[1]
+ uxtl v28.4s,v28.4h
+ umlal v12.2d,v29.2s,v2.s[2]
+ ushr v15.2d,v10.2d,#16
+ umlal v13.2d,v29.2s,v2.s[3]
+ umlal v6.2d,v29.2s,v3.s[0]
+ ext v10.16b,v10.16b,v10.16b,#8
+ add v10.2d,v10.2d,v15.2d
+ umlal v7.2d,v29.2s,v3.s[1]
+ ushr v10.2d,v10.2d,#16
+ umlal v8.2d,v29.2s,v3.s[2]
+ umlal v9.2d,v29.2s,v3.s[3]
+ add v16.2d,v11.2d,v10.2d
+ ins v11.d[0],v16.d[0]
+ st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+4]
+ umlal v11.2d,v28.2s,v0.s[0]
+ ld1 {v10.2d},[x6],#16
+ umlal v12.2d,v28.2s,v0.s[1]
+ umlal v13.2d,v28.2s,v0.s[2]
+ shl v29.2d,v11.2d,#16
+ ext v29.16b,v29.16b,v29.16b,#8
+ umlal v6.2d,v28.2s,v0.s[3]
+ add v29.2d,v29.2d,v11.2d
+ umlal v7.2d,v28.2s,v1.s[0]
+ mul v29.2s,v29.2s,v30.2s
+ umlal v8.2d,v28.2s,v1.s[1]
+ st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+5]
+ umlal v9.2d,v28.2s,v1.s[2]
+ uxtl v29.4s,v29.4h
+ umlal v10.2d,v28.2s,v1.s[3]
+ ldr s28,[x2],#4 // *b++
+ umlal v11.2d,v29.2s,v2.s[0]
+ umlal v12.2d,v29.2s,v2.s[1]
+ uxtl v28.4s,v28.4h
+ umlal v13.2d,v29.2s,v2.s[2]
+ ushr v15.2d,v11.2d,#16
+ umlal v6.2d,v29.2s,v2.s[3]
+ umlal v7.2d,v29.2s,v3.s[0]
+ ext v11.16b,v11.16b,v11.16b,#8
+ add v11.2d,v11.2d,v15.2d
+ umlal v8.2d,v29.2s,v3.s[1]
+ ushr v11.2d,v11.2d,#16
+ umlal v9.2d,v29.2s,v3.s[2]
+ umlal v10.2d,v29.2s,v3.s[3]
+ add v16.2d,v12.2d,v11.2d
+ ins v12.d[0],v16.d[0]
+ st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+5]
+ umlal v12.2d,v28.2s,v0.s[0]
+ ld1 {v11.2d},[x6],#16
+ umlal v13.2d,v28.2s,v0.s[1]
+ umlal v6.2d,v28.2s,v0.s[2]
+ shl v29.2d,v12.2d,#16
+ ext v29.16b,v29.16b,v29.16b,#8
+ umlal v7.2d,v28.2s,v0.s[3]
+ add v29.2d,v29.2d,v12.2d
+ umlal v8.2d,v28.2s,v1.s[0]
+ mul v29.2s,v29.2s,v30.2s
+ umlal v9.2d,v28.2s,v1.s[1]
+ st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+6]
+ umlal v10.2d,v28.2s,v1.s[2]
+ uxtl v29.4s,v29.4h
+ umlal v11.2d,v28.2s,v1.s[3]
+ ldr s28,[x2],#4 // *b++
+ umlal v12.2d,v29.2s,v2.s[0]
+ umlal v13.2d,v29.2s,v2.s[1]
+ uxtl v28.4s,v28.4h
+ umlal v6.2d,v29.2s,v2.s[2]
+ ushr v15.2d,v12.2d,#16
+ umlal v7.2d,v29.2s,v2.s[3]
+ umlal v8.2d,v29.2s,v3.s[0]
+ ext v12.16b,v12.16b,v12.16b,#8
+ add v12.2d,v12.2d,v15.2d
+ umlal v9.2d,v29.2s,v3.s[1]
+ ushr v12.2d,v12.2d,#16
+ umlal v10.2d,v29.2s,v3.s[2]
+ umlal v11.2d,v29.2s,v3.s[3]
+ add v16.2d,v13.2d,v12.2d
+ ins v13.d[0],v16.d[0]
+ st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+6]
+ umlal v13.2d,v28.2s,v0.s[0]
+ ld1 {v12.2d},[x6],#16
+ umlal v6.2d,v28.2s,v0.s[1]
+ umlal v7.2d,v28.2s,v0.s[2]
+ shl v29.2d,v13.2d,#16
+ ext v29.16b,v29.16b,v29.16b,#8
+ umlal v8.2d,v28.2s,v0.s[3]
+ add v29.2d,v29.2d,v13.2d
+ umlal v9.2d,v28.2s,v1.s[0]
+ mul v29.2s,v29.2s,v30.2s
+ umlal v10.2d,v28.2s,v1.s[1]
+ st1 {v28.2s},[x10],#8 // put aside smashed b[8*i+7]
+ umlal v11.2d,v28.2s,v1.s[2]
+ uxtl v29.4s,v29.4h
+ umlal v12.2d,v28.2s,v1.s[3]
+ ld1 {v28.2s},[sp] // pull smashed b[8*i+0]
+ umlal v13.2d,v29.2s,v2.s[0]
+ ld1 {v0.4s,v1.4s},[x1],#32
+ umlal v6.2d,v29.2s,v2.s[1]
+ umlal v7.2d,v29.2s,v2.s[2]
+ mov v5.16b,v13.16b
+ ushr v5.2d,v5.2d,#16
+ ext v13.16b,v13.16b,v13.16b,#8
+ umlal v8.2d,v29.2s,v2.s[3]
+ umlal v9.2d,v29.2s,v3.s[0]
+ add v13.2d,v13.2d,v5.2d
+ umlal v10.2d,v29.2s,v3.s[1]
+ ushr v13.2d,v13.2d,#16
+ eor v15.16b,v15.16b,v15.16b
+ ins v13.d[1],v15.d[0]
+ umlal v11.2d,v29.2s,v3.s[2]
+ umlal v12.2d,v29.2s,v3.s[3]
+ add v6.2d,v6.2d,v13.2d
+ st1 {v29.2s},[x10],#8 // put aside smashed m[8*i+7]
+ add x10,sp,#8 // rewind
+ sub x8,x5,#8
+ b .LNEON_8n_inner
+
+.align 4
+.LNEON_8n_inner:
+ subs x8,x8,#8
+ umlal v6.2d,v28.2s,v0.s[0]
+ ld1 {v13.2d},[x6]
+ umlal v7.2d,v28.2s,v0.s[1]
+ ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+0]
+ umlal v8.2d,v28.2s,v0.s[2]
+ ld1 {v2.4s,v3.4s},[x3],#32
+ umlal v9.2d,v28.2s,v0.s[3]
+ b.eq .LInner_jump
+ add x6,x6,#16 // don't advance in last iteration
+.LInner_jump:
+ umlal v10.2d,v28.2s,v1.s[0]
+ umlal v11.2d,v28.2s,v1.s[1]
+ umlal v12.2d,v28.2s,v1.s[2]
+ umlal v13.2d,v28.2s,v1.s[3]
+ ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+1]
+ umlal v6.2d,v29.2s,v2.s[0]
+ umlal v7.2d,v29.2s,v2.s[1]
+ umlal v8.2d,v29.2s,v2.s[2]
+ umlal v9.2d,v29.2s,v2.s[3]
+ umlal v10.2d,v29.2s,v3.s[0]
+ umlal v11.2d,v29.2s,v3.s[1]
+ umlal v12.2d,v29.2s,v3.s[2]
+ umlal v13.2d,v29.2s,v3.s[3]
+ st1 {v6.2d},[x7],#16
+ umlal v7.2d,v28.2s,v0.s[0]
+ ld1 {v6.2d},[x6]
+ umlal v8.2d,v28.2s,v0.s[1]
+ ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+1]
+ umlal v9.2d,v28.2s,v0.s[2]
+ b.eq .LInner_jump1
+ add x6,x6,#16 // don't advance in last iteration
+.LInner_jump1:
+ umlal v10.2d,v28.2s,v0.s[3]
+ umlal v11.2d,v28.2s,v1.s[0]
+ umlal v12.2d,v28.2s,v1.s[1]
+ umlal v13.2d,v28.2s,v1.s[2]
+ umlal v6.2d,v28.2s,v1.s[3]
+ ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+2]
+ umlal v7.2d,v29.2s,v2.s[0]
+ umlal v8.2d,v29.2s,v2.s[1]
+ umlal v9.2d,v29.2s,v2.s[2]
+ umlal v10.2d,v29.2s,v2.s[3]
+ umlal v11.2d,v29.2s,v3.s[0]
+ umlal v12.2d,v29.2s,v3.s[1]
+ umlal v13.2d,v29.2s,v3.s[2]
+ umlal v6.2d,v29.2s,v3.s[3]
+ st1 {v7.2d},[x7],#16
+ umlal v8.2d,v28.2s,v0.s[0]
+ ld1 {v7.2d},[x6]
+ umlal v9.2d,v28.2s,v0.s[1]
+ ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+2]
+ umlal v10.2d,v28.2s,v0.s[2]
+ b.eq .LInner_jump2
+ add x6,x6,#16 // don't advance in last iteration
+.LInner_jump2:
+ umlal v11.2d,v28.2s,v0.s[3]
+ umlal v12.2d,v28.2s,v1.s[0]
+ umlal v13.2d,v28.2s,v1.s[1]
+ umlal v6.2d,v28.2s,v1.s[2]
+ umlal v7.2d,v28.2s,v1.s[3]
+ ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+3]
+ umlal v8.2d,v29.2s,v2.s[0]
+ umlal v9.2d,v29.2s,v2.s[1]
+ umlal v10.2d,v29.2s,v2.s[2]
+ umlal v11.2d,v29.2s,v2.s[3]
+ umlal v12.2d,v29.2s,v3.s[0]
+ umlal v13.2d,v29.2s,v3.s[1]
+ umlal v6.2d,v29.2s,v3.s[2]
+ umlal v7.2d,v29.2s,v3.s[3]
+ st1 {v8.2d},[x7],#16
+ umlal v9.2d,v28.2s,v0.s[0]
+ ld1 {v8.2d},[x6]
+ umlal v10.2d,v28.2s,v0.s[1]
+ ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+3]
+ umlal v11.2d,v28.2s,v0.s[2]
+ b.eq .LInner_jump3
+ add x6,x6,#16 // don't advance in last iteration
+.LInner_jump3:
+ umlal v12.2d,v28.2s,v0.s[3]
+ umlal v13.2d,v28.2s,v1.s[0]
+ umlal v6.2d,v28.2s,v1.s[1]
+ umlal v7.2d,v28.2s,v1.s[2]
+ umlal v8.2d,v28.2s,v1.s[3]
+ ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+4]
+ umlal v9.2d,v29.2s,v2.s[0]
+ umlal v10.2d,v29.2s,v2.s[1]
+ umlal v11.2d,v29.2s,v2.s[2]
+ umlal v12.2d,v29.2s,v2.s[3]
+ umlal v13.2d,v29.2s,v3.s[0]
+ umlal v6.2d,v29.2s,v3.s[1]
+ umlal v7.2d,v29.2s,v3.s[2]
+ umlal v8.2d,v29.2s,v3.s[3]
+ st1 {v9.2d},[x7],#16
+ umlal v10.2d,v28.2s,v0.s[0]
+ ld1 {v9.2d},[x6]
+ umlal v11.2d,v28.2s,v0.s[1]
+ ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+4]
+ umlal v12.2d,v28.2s,v0.s[2]
+ b.eq .LInner_jump4
+ add x6,x6,#16 // don't advance in last iteration
+.LInner_jump4:
+ umlal v13.2d,v28.2s,v0.s[3]
+ umlal v6.2d,v28.2s,v1.s[0]
+ umlal v7.2d,v28.2s,v1.s[1]
+ umlal v8.2d,v28.2s,v1.s[2]
+ umlal v9.2d,v28.2s,v1.s[3]
+ ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+5]
+ umlal v10.2d,v29.2s,v2.s[0]
+ umlal v11.2d,v29.2s,v2.s[1]
+ umlal v12.2d,v29.2s,v2.s[2]
+ umlal v13.2d,v29.2s,v2.s[3]
+ umlal v6.2d,v29.2s,v3.s[0]
+ umlal v7.2d,v29.2s,v3.s[1]
+ umlal v8.2d,v29.2s,v3.s[2]
+ umlal v9.2d,v29.2s,v3.s[3]
+ st1 {v10.2d},[x7],#16
+ umlal v11.2d,v28.2s,v0.s[0]
+ ld1 {v10.2d},[x6]
+ umlal v12.2d,v28.2s,v0.s[1]
+ ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+5]
+ umlal v13.2d,v28.2s,v0.s[2]
+ b.eq .LInner_jump5
+ add x6,x6,#16 // don't advance in last iteration
+.LInner_jump5:
+ umlal v6.2d,v28.2s,v0.s[3]
+ umlal v7.2d,v28.2s,v1.s[0]
+ umlal v8.2d,v28.2s,v1.s[1]
+ umlal v9.2d,v28.2s,v1.s[2]
+ umlal v10.2d,v28.2s,v1.s[3]
+ ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+6]
+ umlal v11.2d,v29.2s,v2.s[0]
+ umlal v12.2d,v29.2s,v2.s[1]
+ umlal v13.2d,v29.2s,v2.s[2]
+ umlal v6.2d,v29.2s,v2.s[3]
+ umlal v7.2d,v29.2s,v3.s[0]
+ umlal v8.2d,v29.2s,v3.s[1]
+ umlal v9.2d,v29.2s,v3.s[2]
+ umlal v10.2d,v29.2s,v3.s[3]
+ st1 {v11.2d},[x7],#16
+ umlal v12.2d,v28.2s,v0.s[0]
+ ld1 {v11.2d},[x6]
+ umlal v13.2d,v28.2s,v0.s[1]
+ ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+6]
+ umlal v6.2d,v28.2s,v0.s[2]
+ b.eq .LInner_jump6
+ add x6,x6,#16 // don't advance in last iteration
+.LInner_jump6:
+ umlal v7.2d,v28.2s,v0.s[3]
+ umlal v8.2d,v28.2s,v1.s[0]
+ umlal v9.2d,v28.2s,v1.s[1]
+ umlal v10.2d,v28.2s,v1.s[2]
+ umlal v11.2d,v28.2s,v1.s[3]
+ ld1 {v28.2s},[x10],#8 // pull smashed b[8*i+7]
+ umlal v12.2d,v29.2s,v2.s[0]
+ umlal v13.2d,v29.2s,v2.s[1]
+ umlal v6.2d,v29.2s,v2.s[2]
+ umlal v7.2d,v29.2s,v2.s[3]
+ umlal v8.2d,v29.2s,v3.s[0]
+ umlal v9.2d,v29.2s,v3.s[1]
+ umlal v10.2d,v29.2s,v3.s[2]
+ umlal v11.2d,v29.2s,v3.s[3]
+ st1 {v12.2d},[x7],#16
+ umlal v13.2d,v28.2s,v0.s[0]
+ ld1 {v12.2d},[x6]
+ umlal v6.2d,v28.2s,v0.s[1]
+ ld1 {v29.2s},[x10],#8 // pull smashed m[8*i+7]
+ umlal v7.2d,v28.2s,v0.s[2]
+ b.eq .LInner_jump7
+ add x6,x6,#16 // don't advance in last iteration
+.LInner_jump7:
+ umlal v8.2d,v28.2s,v0.s[3]
+ umlal v9.2d,v28.2s,v1.s[0]
+ umlal v10.2d,v28.2s,v1.s[1]
+ umlal v11.2d,v28.2s,v1.s[2]
+ umlal v12.2d,v28.2s,v1.s[3]
+ b.ne .LInner_after_rewind8
+ sub x1,x1,x5,lsl#2 // rewind
+.LInner_after_rewind8:
+ umlal v13.2d,v29.2s,v2.s[0]
+ ld1 {v28.2s},[sp] // pull smashed b[8*i+0]
+ umlal v6.2d,v29.2s,v2.s[1]
+ ld1 {v0.4s,v1.4s},[x1],#32
+ umlal v7.2d,v29.2s,v2.s[2]
+ add x10,sp,#8 // rewind
+ umlal v8.2d,v29.2s,v2.s[3]
+ umlal v9.2d,v29.2s,v3.s[0]
+ umlal v10.2d,v29.2s,v3.s[1]
+ umlal v11.2d,v29.2s,v3.s[2]
+ st1 {v13.2d},[x7],#16
+ umlal v12.2d,v29.2s,v3.s[3]
+
+ bne .LNEON_8n_inner
+ add x6,sp,#128
+ st1 {v6.2d,v7.2d},[x7],#32
+ eor v2.16b,v2.16b,v2.16b // v2
+ st1 {v8.2d,v9.2d},[x7],#32
+ eor v3.16b,v3.16b,v3.16b // v3
+ st1 {v10.2d,v11.2d},[x7],#32
+ st1 {v12.2d},[x7]
+
+ subs x9,x9,#8
+ ld1 {v6.2d,v7.2d},[x6],#32
+ ld1 {v8.2d,v9.2d},[x6],#32
+ ld1 {v10.2d,v11.2d},[x6],#32
+ ld1 {v12.2d,v13.2d},[x6],#32
+
+ b.eq .LInner_8n_jump_2steps
+ sub x3,x3,x5,lsl#2 // rewind
+ b .LNEON_8n_outer
+
+.LInner_8n_jump_2steps:
+ add x7,sp,#128
+ st1 {v2.2d,v3.2d}, [sp],#32 // start wiping stack frame
+ mov v5.16b,v6.16b
+ ushr v15.2d,v6.2d,#16
+ ext v6.16b,v6.16b,v6.16b,#8
+ st1 {v2.2d,v3.2d}, [sp],#32
+ add v6.2d,v6.2d,v15.2d
+ st1 {v2.2d,v3.2d}, [sp],#32
+ ushr v15.2d,v6.2d,#16
+ st1 {v2.2d,v3.2d}, [sp],#32
+ zip1 v6.4h,v5.4h,v6.4h
+ ins v15.d[1],v14.d[0]
+
+ mov x8,x5
+ b .LNEON_tail_entry
+
+.align 4
+.LNEON_tail:
+ add v6.2d,v6.2d,v15.2d
+ mov v5.16b,v6.16b
+ ushr v15.2d,v6.2d,#16
+ ext v6.16b,v6.16b,v6.16b,#8
+ ld1 {v8.2d,v9.2d}, [x6],#32
+ add v6.2d,v6.2d,v15.2d
+ ld1 {v10.2d,v11.2d}, [x6],#32
+ ushr v15.2d,v6.2d,#16
+ ld1 {v12.2d,v13.2d}, [x6],#32
+ zip1 v6.4h,v5.4h,v6.4h
+ ins v15.d[1],v14.d[0]
+
+.LNEON_tail_entry:
+ add v7.2d,v7.2d,v15.2d
+ st1 {v6.s}[0], [x7],#4
+ ushr v15.2d,v7.2d,#16
+ mov v5.16b,v7.16b
+ ext v7.16b,v7.16b,v7.16b,#8
+ add v7.2d,v7.2d,v15.2d
+ ushr v15.2d,v7.2d,#16
+ zip1 v7.4h,v5.4h,v7.4h
+ ins v15.d[1],v14.d[0]
+ add v8.2d,v8.2d,v15.2d
+ st1 {v7.s}[0], [x7],#4
+ ushr v15.2d,v8.2d,#16
+ mov v5.16b,v8.16b
+ ext v8.16b,v8.16b,v8.16b,#8
+ add v8.2d,v8.2d,v15.2d
+ ushr v15.2d,v8.2d,#16
+ zip1 v8.4h,v5.4h,v8.4h
+ ins v15.d[1],v14.d[0]
+ add v9.2d,v9.2d,v15.2d
+ st1 {v8.s}[0], [x7],#4
+ ushr v15.2d,v9.2d,#16
+ mov v5.16b,v9.16b
+ ext v9.16b,v9.16b,v9.16b,#8
+ add v9.2d,v9.2d,v15.2d
+ ushr v15.2d,v9.2d,#16
+ zip1 v9.4h,v5.4h,v9.4h
+ ins v15.d[1],v14.d[0]
+ add v10.2d,v10.2d,v15.2d
+ st1 {v9.s}[0], [x7],#4
+ ushr v15.2d,v10.2d,#16
+ mov v5.16b,v10.16b
+ ext v10.16b,v10.16b,v10.16b,#8
+ add v10.2d,v10.2d,v15.2d
+ ushr v15.2d,v10.2d,#16
+ zip1 v10.4h,v5.4h,v10.4h
+ ins v15.d[1],v14.d[0]
+ add v11.2d,v11.2d,v15.2d
+ st1 {v10.s}[0], [x7],#4
+ ushr v15.2d,v11.2d,#16
+ mov v5.16b,v11.16b
+ ext v11.16b,v11.16b,v11.16b,#8
+ add v11.2d,v11.2d,v15.2d
+ ushr v15.2d,v11.2d,#16
+ zip1 v11.4h,v5.4h,v11.4h
+ ins v15.d[1],v14.d[0]
+ add v12.2d,v12.2d,v15.2d
+ st1 {v11.s}[0], [x7],#4
+ ushr v15.2d,v12.2d,#16
+ mov v5.16b,v12.16b
+ ext v12.16b,v12.16b,v12.16b,#8
+ add v12.2d,v12.2d,v15.2d
+ ushr v15.2d,v12.2d,#16
+ zip1 v12.4h,v5.4h,v12.4h
+ ins v15.d[1],v14.d[0]
+ add v13.2d,v13.2d,v15.2d
+ st1 {v12.s}[0], [x7],#4
+ ushr v15.2d,v13.2d,#16
+ mov v5.16b,v13.16b
+ ext v13.16b,v13.16b,v13.16b,#8
+ add v13.2d,v13.2d,v15.2d
+ ushr v15.2d,v13.2d,#16
+ zip1 v13.4h,v5.4h,v13.4h
+ ins v15.d[1],v14.d[0]
+ ld1 {v6.2d,v7.2d}, [x6],#32
+ subs x8,x8,#8
+ st1 {v13.s}[0], [x7],#4
+ bne .LNEON_tail
+
+ st1 {v15.s}[0], [x7],#4 // top-most bit
+ sub x3,x3,x5,lsl#2 // rewind x3
+ subs x1,sp,#0 // clear carry flag
+ add x2,sp,x5,lsl#2
+
+.LNEON_sub:
+ ldp w4,w5,[x1],#8
+ ldp w6,w7,[x1],#8
+ ldp w8,w9,[x3],#8
+ ldp w10,w11,[x3],#8
+ sbcs w8,w4,w8
+ sbcs w9,w5,w9
+ sbcs w10,w6,w10
+ sbcs w11,w7,w11
+ sub x17,x2,x1
+ stp w8,w9,[x0],#8
+ stp w10,w11,[x0],#8
+ cbnz x17,.LNEON_sub
+
+ ldr w10, [x1] // load top-most bit
+ mov x11,sp
+ eor v0.16b,v0.16b,v0.16b
+ sub x11,x2,x11 // this is num*4
+ eor v1.16b,v1.16b,v1.16b
+ mov x1,sp
+ sub x0,x0,x11 // rewind x0
+ mov x3,x2 // second 3/4th of frame
+ sbcs w10,w10,wzr // result is carry flag
+
+.LNEON_copy_n_zap:
+ ldp w4,w5,[x1],#8
+ ldp w6,w7,[x1],#8
+ ldp w8,w9,[x0],#8
+ ldp w10,w11,[x0]
+ sub x0,x0,#8
+ b.cs .LCopy_1
+ mov w8,w4
+ mov w9,w5
+ mov w10,w6
+ mov w11,w7
+.LCopy_1:
+ st1 {v0.2d,v1.2d}, [x3],#32 // wipe
+ st1 {v0.2d,v1.2d}, [x3],#32 // wipe
+ ldp w4,w5,[x1],#8
+ ldp w6,w7,[x1],#8
+ stp w8,w9,[x0],#8
+ stp w10,w11,[x0],#8
+ sub x1,x1,#32
+ ldp w8,w9,[x0],#8
+ ldp w10,w11,[x0]
+ sub x0,x0,#8
+ b.cs .LCopy_2
+ mov w8, w4
+ mov w9, w5
+ mov w10, w6
+ mov w11, w7
+.LCopy_2:
+ st1 {v0.2d,v1.2d}, [x1],#32 // wipe
+ st1 {v0.2d,v1.2d}, [x3],#32 // wipe
+ sub x17,x2,x1 // preserves carry
+ stp w8,w9,[x0],#8
+ stp w10,w11,[x0],#8
+ cbnz x17,.LNEON_copy_n_zap
+
+ mov sp,x16
+ ldp d14,d15,[sp,#64]
+ ldp d12,d13,[sp,#48]
+ ldp d10,d11,[sp,#32]
+ ldp d8,d9,[sp,#16]
+ ldr x29,[sp],#80
+ ret // bx lr
+
+.size bn_mul8x_mont_neon,.-bn_mul8x_mont_neon
+.type __bn_sqr8x_mont,%function
+.align 5
+__bn_sqr8x_mont:
+ cmp x1,x2
+ b.ne __bn_mul4x_mont
+.Lsqr8x_mont:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ stp x0,x3,[sp,#96] // offload rp and np
+
+ ldp x6,x7,[x1,#8*0]
+ ldp x8,x9,[x1,#8*2]
+ ldp x10,x11,[x1,#8*4]
+ ldp x12,x13,[x1,#8*6]
+
+ sub x2,sp,x5,lsl#4
+ lsl x5,x5,#3
+ ldr x4,[x4] // *n0
+ mov sp,x2 // alloca
+ sub x27,x5,#8*8
+ b .Lsqr8x_zero_start
+
+.Lsqr8x_zero:
+ sub x27,x27,#8*8
+ stp xzr,xzr,[x2,#8*0]
+ stp xzr,xzr,[x2,#8*2]
+ stp xzr,xzr,[x2,#8*4]
+ stp xzr,xzr,[x2,#8*6]
+.Lsqr8x_zero_start:
+ stp xzr,xzr,[x2,#8*8]
+ stp xzr,xzr,[x2,#8*10]
+ stp xzr,xzr,[x2,#8*12]
+ stp xzr,xzr,[x2,#8*14]
+ add x2,x2,#8*16
+ cbnz x27,.Lsqr8x_zero
+
+ add x3,x1,x5
+ add x1,x1,#8*8
+ mov x19,xzr
+ mov x20,xzr
+ mov x21,xzr
+ mov x22,xzr
+ mov x23,xzr
+ mov x24,xzr
+ mov x25,xzr
+ mov x26,xzr
+ mov x2,sp
+ str x4,[x29,#112] // offload n0
+
+ // Multiply everything but a[i]*a[i]
+.align 4
+.Lsqr8x_outer_loop:
+ // a[1]a[0] (i)
+ // a[2]a[0]
+ // a[3]a[0]
+ // a[4]a[0]
+ // a[5]a[0]
+ // a[6]a[0]
+ // a[7]a[0]
+ // a[2]a[1] (ii)
+ // a[3]a[1]
+ // a[4]a[1]
+ // a[5]a[1]
+ // a[6]a[1]
+ // a[7]a[1]
+ // a[3]a[2] (iii)
+ // a[4]a[2]
+ // a[5]a[2]
+ // a[6]a[2]
+ // a[7]a[2]
+ // a[4]a[3] (iv)
+ // a[5]a[3]
+ // a[6]a[3]
+ // a[7]a[3]
+ // a[5]a[4] (v)
+ // a[6]a[4]
+ // a[7]a[4]
+ // a[6]a[5] (vi)
+ // a[7]a[5]
+ // a[7]a[6] (vii)
+
+ mul x14,x7,x6 // lo(a[1..7]*a[0]) (i)
+ mul x15,x8,x6
+ mul x16,x9,x6
+ mul x17,x10,x6
+ adds x20,x20,x14 // t[1]+lo(a[1]*a[0])
+ mul x14,x11,x6
+ adcs x21,x21,x15
+ mul x15,x12,x6
+ adcs x22,x22,x16
+ mul x16,x13,x6
+ adcs x23,x23,x17
+ umulh x17,x7,x6 // hi(a[1..7]*a[0])
+ adcs x24,x24,x14
+ umulh x14,x8,x6
+ adcs x25,x25,x15
+ umulh x15,x9,x6
+ adcs x26,x26,x16
+ umulh x16,x10,x6
+ stp x19,x20,[x2],#8*2 // t[0..1]
+ adc x19,xzr,xzr // t[8]
+ adds x21,x21,x17 // t[2]+lo(a[1]*a[0])
+ umulh x17,x11,x6
+ adcs x22,x22,x14
+ umulh x14,x12,x6
+ adcs x23,x23,x15
+ umulh x15,x13,x6
+ adcs x24,x24,x16
+ mul x16,x8,x7 // lo(a[2..7]*a[1]) (ii)
+ adcs x25,x25,x17
+ mul x17,x9,x7
+ adcs x26,x26,x14
+ mul x14,x10,x7
+ adc x19,x19,x15
+
+ mul x15,x11,x7
+ adds x22,x22,x16
+ mul x16,x12,x7
+ adcs x23,x23,x17
+ mul x17,x13,x7
+ adcs x24,x24,x14
+ umulh x14,x8,x7 // hi(a[2..7]*a[1])
+ adcs x25,x25,x15
+ umulh x15,x9,x7
+ adcs x26,x26,x16
+ umulh x16,x10,x7
+ adcs x19,x19,x17
+ umulh x17,x11,x7
+ stp x21,x22,[x2],#8*2 // t[2..3]
+ adc x20,xzr,xzr // t[9]
+ adds x23,x23,x14
+ umulh x14,x12,x7
+ adcs x24,x24,x15
+ umulh x15,x13,x7
+ adcs x25,x25,x16
+ mul x16,x9,x8 // lo(a[3..7]*a[2]) (iii)
+ adcs x26,x26,x17
+ mul x17,x10,x8
+ adcs x19,x19,x14
+ mul x14,x11,x8
+ adc x20,x20,x15
+
+ mul x15,x12,x8
+ adds x24,x24,x16
+ mul x16,x13,x8
+ adcs x25,x25,x17
+ umulh x17,x9,x8 // hi(a[3..7]*a[2])
+ adcs x26,x26,x14
+ umulh x14,x10,x8
+ adcs x19,x19,x15
+ umulh x15,x11,x8
+ adcs x20,x20,x16
+ umulh x16,x12,x8
+ stp x23,x24,[x2],#8*2 // t[4..5]
+ adc x21,xzr,xzr // t[10]
+ adds x25,x25,x17
+ umulh x17,x13,x8
+ adcs x26,x26,x14
+ mul x14,x10,x9 // lo(a[4..7]*a[3]) (iv)
+ adcs x19,x19,x15
+ mul x15,x11,x9
+ adcs x20,x20,x16
+ mul x16,x12,x9
+ adc x21,x21,x17
+
+ mul x17,x13,x9
+ adds x26,x26,x14
+ umulh x14,x10,x9 // hi(a[4..7]*a[3])
+ adcs x19,x19,x15
+ umulh x15,x11,x9
+ adcs x20,x20,x16
+ umulh x16,x12,x9
+ adcs x21,x21,x17
+ umulh x17,x13,x9
+ stp x25,x26,[x2],#8*2 // t[6..7]
+ adc x22,xzr,xzr // t[11]
+ adds x19,x19,x14
+ mul x14,x11,x10 // lo(a[5..7]*a[4]) (v)
+ adcs x20,x20,x15
+ mul x15,x12,x10
+ adcs x21,x21,x16
+ mul x16,x13,x10
+ adc x22,x22,x17
+
+ umulh x17,x11,x10 // hi(a[5..7]*a[4])
+ adds x20,x20,x14
+ umulh x14,x12,x10
+ adcs x21,x21,x15
+ umulh x15,x13,x10
+ adcs x22,x22,x16
+ mul x16,x12,x11 // lo(a[6..7]*a[5]) (vi)
+ adc x23,xzr,xzr // t[12]
+ adds x21,x21,x17
+ mul x17,x13,x11
+ adcs x22,x22,x14
+ umulh x14,x12,x11 // hi(a[6..7]*a[5])
+ adc x23,x23,x15
+
+ umulh x15,x13,x11
+ adds x22,x22,x16
+ mul x16,x13,x12 // lo(a[7]*a[6]) (vii)
+ adcs x23,x23,x17
+ umulh x17,x13,x12 // hi(a[7]*a[6])
+ adc x24,xzr,xzr // t[13]
+ adds x23,x23,x14
+ sub x27,x3,x1 // done yet?
+ adc x24,x24,x15
+
+ adds x24,x24,x16
+ sub x14,x3,x5 // rewinded ap
+ adc x25,xzr,xzr // t[14]
+ add x25,x25,x17
+
+ cbz x27,.Lsqr8x_outer_break
+
+ mov x4,x6
+ ldp x6,x7,[x2,#8*0]
+ ldp x8,x9,[x2,#8*2]
+ ldp x10,x11,[x2,#8*4]
+ ldp x12,x13,[x2,#8*6]
+ adds x19,x19,x6
+ adcs x20,x20,x7
+ ldp x6,x7,[x1,#8*0]
+ adcs x21,x21,x8
+ adcs x22,x22,x9
+ ldp x8,x9,[x1,#8*2]
+ adcs x23,x23,x10
+ adcs x24,x24,x11
+ ldp x10,x11,[x1,#8*4]
+ adcs x25,x25,x12
+ mov x0,x1
+ adcs x26,xzr,x13
+ ldp x12,x13,[x1,#8*6]
+ add x1,x1,#8*8
+ //adc x28,xzr,xzr // moved below
+ mov x27,#-8*8
+
+ // a[8]a[0]
+ // a[9]a[0]
+ // a[a]a[0]
+ // a[b]a[0]
+ // a[c]a[0]
+ // a[d]a[0]
+ // a[e]a[0]
+ // a[f]a[0]
+ // a[8]a[1]
+ // a[f]a[1]........................
+ // a[8]a[2]
+ // a[f]a[2]........................
+ // a[8]a[3]
+ // a[f]a[3]........................
+ // a[8]a[4]
+ // a[f]a[4]........................
+ // a[8]a[5]
+ // a[f]a[5]........................
+ // a[8]a[6]
+ // a[f]a[6]........................
+ // a[8]a[7]
+ // a[f]a[7]........................
+.Lsqr8x_mul:
+ mul x14,x6,x4
+ adc x28,xzr,xzr // carry bit, modulo-scheduled
+ mul x15,x7,x4
+ add x27,x27,#8
+ mul x16,x8,x4
+ mul x17,x9,x4
+ adds x19,x19,x14
+ mul x14,x10,x4
+ adcs x20,x20,x15
+ mul x15,x11,x4
+ adcs x21,x21,x16
+ mul x16,x12,x4
+ adcs x22,x22,x17
+ mul x17,x13,x4
+ adcs x23,x23,x14
+ umulh x14,x6,x4
+ adcs x24,x24,x15
+ umulh x15,x7,x4
+ adcs x25,x25,x16
+ umulh x16,x8,x4
+ adcs x26,x26,x17
+ umulh x17,x9,x4
+ adc x28,x28,xzr
+ str x19,[x2],#8
+ adds x19,x20,x14
+ umulh x14,x10,x4
+ adcs x20,x21,x15
+ umulh x15,x11,x4
+ adcs x21,x22,x16
+ umulh x16,x12,x4
+ adcs x22,x23,x17
+ umulh x17,x13,x4
+ ldr x4,[x0,x27]
+ adcs x23,x24,x14
+ adcs x24,x25,x15
+ adcs x25,x26,x16
+ adcs x26,x28,x17
+ //adc x28,xzr,xzr // moved above
+ cbnz x27,.Lsqr8x_mul
+ // note that carry flag is guaranteed
+ // to be zero at this point
+ cmp x1,x3 // done yet?
+ b.eq .Lsqr8x_break
+
+ ldp x6,x7,[x2,#8*0]
+ ldp x8,x9,[x2,#8*2]
+ ldp x10,x11,[x2,#8*4]
+ ldp x12,x13,[x2,#8*6]
+ adds x19,x19,x6
+ ldur x4,[x0,#-8*8]
+ adcs x20,x20,x7
+ ldp x6,x7,[x1,#8*0]
+ adcs x21,x21,x8
+ adcs x22,x22,x9
+ ldp x8,x9,[x1,#8*2]
+ adcs x23,x23,x10
+ adcs x24,x24,x11
+ ldp x10,x11,[x1,#8*4]
+ adcs x25,x25,x12
+ mov x27,#-8*8
+ adcs x26,x26,x13
+ ldp x12,x13,[x1,#8*6]
+ add x1,x1,#8*8
+ //adc x28,xzr,xzr // moved above
+ b .Lsqr8x_mul
+
+.align 4
+.Lsqr8x_break:
+ ldp x6,x7,[x0,#8*0]
+ add x1,x0,#8*8
+ ldp x8,x9,[x0,#8*2]
+ sub x14,x3,x1 // is it last iteration?
+ ldp x10,x11,[x0,#8*4]
+ sub x15,x2,x14
+ ldp x12,x13,[x0,#8*6]
+ cbz x14,.Lsqr8x_outer_loop
+
+ stp x19,x20,[x2,#8*0]
+ ldp x19,x20,[x15,#8*0]
+ stp x21,x22,[x2,#8*2]
+ ldp x21,x22,[x15,#8*2]
+ stp x23,x24,[x2,#8*4]
+ ldp x23,x24,[x15,#8*4]
+ stp x25,x26,[x2,#8*6]
+ mov x2,x15
+ ldp x25,x26,[x15,#8*6]
+ b .Lsqr8x_outer_loop
+
+.align 4
+.Lsqr8x_outer_break:
+ // Now multiply above result by 2 and add a[n-1]*a[n-1]|...|a[0]*a[0]
+ ldp x7,x9,[x14,#8*0] // recall that x14 is &a[0]
+ ldp x15,x16,[sp,#8*1]
+ ldp x11,x13,[x14,#8*2]
+ add x1,x14,#8*4
+ ldp x17,x14,[sp,#8*3]
+
+ stp x19,x20,[x2,#8*0]
+ mul x19,x7,x7
+ stp x21,x22,[x2,#8*2]
+ umulh x7,x7,x7
+ stp x23,x24,[x2,#8*4]
+ mul x8,x9,x9
+ stp x25,x26,[x2,#8*6]
+ mov x2,sp
+ umulh x9,x9,x9
+ adds x20,x7,x15,lsl#1
+ extr x15,x16,x15,#63
+ sub x27,x5,#8*4
+
+.Lsqr4x_shift_n_add:
+ adcs x21,x8,x15
+ extr x16,x17,x16,#63
+ sub x27,x27,#8*4
+ adcs x22,x9,x16
+ ldp x15,x16,[x2,#8*5]
+ mul x10,x11,x11
+ ldp x7,x9,[x1],#8*2
+ umulh x11,x11,x11
+ mul x12,x13,x13
+ umulh x13,x13,x13
+ extr x17,x14,x17,#63
+ stp x19,x20,[x2,#8*0]
+ adcs x23,x10,x17
+ extr x14,x15,x14,#63
+ stp x21,x22,[x2,#8*2]
+ adcs x24,x11,x14
+ ldp x17,x14,[x2,#8*7]
+ extr x15,x16,x15,#63
+ adcs x25,x12,x15
+ extr x16,x17,x16,#63
+ adcs x26,x13,x16
+ ldp x15,x16,[x2,#8*9]
+ mul x6,x7,x7
+ ldp x11,x13,[x1],#8*2
+ umulh x7,x7,x7
+ mul x8,x9,x9
+ umulh x9,x9,x9
+ stp x23,x24,[x2,#8*4]
+ extr x17,x14,x17,#63
+ stp x25,x26,[x2,#8*6]
+ add x2,x2,#8*8
+ adcs x19,x6,x17
+ extr x14,x15,x14,#63
+ adcs x20,x7,x14
+ ldp x17,x14,[x2,#8*3]
+ extr x15,x16,x15,#63
+ cbnz x27,.Lsqr4x_shift_n_add
+ ldp x1,x4,[x29,#104] // pull np and n0
+
+ adcs x21,x8,x15
+ extr x16,x17,x16,#63
+ adcs x22,x9,x16
+ ldp x15,x16,[x2,#8*5]
+ mul x10,x11,x11
+ umulh x11,x11,x11
+ stp x19,x20,[x2,#8*0]
+ mul x12,x13,x13
+ umulh x13,x13,x13
+ stp x21,x22,[x2,#8*2]
+ extr x17,x14,x17,#63
+ adcs x23,x10,x17
+ extr x14,x15,x14,#63
+ ldp x19,x20,[sp,#8*0]
+ adcs x24,x11,x14
+ extr x15,x16,x15,#63
+ ldp x6,x7,[x1,#8*0]
+ adcs x25,x12,x15
+ extr x16,xzr,x16,#63
+ ldp x8,x9,[x1,#8*2]
+ adc x26,x13,x16
+ ldp x10,x11,[x1,#8*4]
+
+ // Reduce by 512 bits per iteration
+ mul x28,x4,x19 // t[0]*n0
+ ldp x12,x13,[x1,#8*6]
+ add x3,x1,x5
+ ldp x21,x22,[sp,#8*2]
+ stp x23,x24,[x2,#8*4]
+ ldp x23,x24,[sp,#8*4]
+ stp x25,x26,[x2,#8*6]
+ ldp x25,x26,[sp,#8*6]
+ add x1,x1,#8*8
+ mov x30,xzr // initial top-most carry
+ mov x2,sp
+ mov x27,#8
+
+.Lsqr8x_reduction:
+ // (*) mul x14,x6,x28 // lo(n[0-7])*lo(t[0]*n0)
+ mul x15,x7,x28
+ sub x27,x27,#1
+ mul x16,x8,x28
+ str x28,[x2],#8 // put aside t[0]*n0 for tail processing
+ mul x17,x9,x28
+ // (*) adds xzr,x19,x14
+ subs xzr,x19,#1 // (*)
+ mul x14,x10,x28
+ adcs x19,x20,x15
+ mul x15,x11,x28
+ adcs x20,x21,x16
+ mul x16,x12,x28
+ adcs x21,x22,x17
+ mul x17,x13,x28
+ adcs x22,x23,x14
+ umulh x14,x6,x28 // hi(n[0-7])*lo(t[0]*n0)
+ adcs x23,x24,x15
+ umulh x15,x7,x28
+ adcs x24,x25,x16
+ umulh x16,x8,x28
+ adcs x25,x26,x17
+ umulh x17,x9,x28
+ adc x26,xzr,xzr
+ adds x19,x19,x14
+ umulh x14,x10,x28
+ adcs x20,x20,x15
+ umulh x15,x11,x28
+ adcs x21,x21,x16
+ umulh x16,x12,x28
+ adcs x22,x22,x17
+ umulh x17,x13,x28
+ mul x28,x4,x19 // next t[0]*n0
+ adcs x23,x23,x14
+ adcs x24,x24,x15
+ adcs x25,x25,x16
+ adc x26,x26,x17
+ cbnz x27,.Lsqr8x_reduction
+
+ ldp x14,x15,[x2,#8*0]
+ ldp x16,x17,[x2,#8*2]
+ mov x0,x2
+ sub x27,x3,x1 // done yet?
+ adds x19,x19,x14
+ adcs x20,x20,x15
+ ldp x14,x15,[x2,#8*4]
+ adcs x21,x21,x16
+ adcs x22,x22,x17
+ ldp x16,x17,[x2,#8*6]
+ adcs x23,x23,x14
+ adcs x24,x24,x15
+ adcs x25,x25,x16
+ adcs x26,x26,x17
+ //adc x28,xzr,xzr // moved below
+ cbz x27,.Lsqr8x8_post_condition
+
+ ldur x4,[x2,#-8*8]
+ ldp x6,x7,[x1,#8*0]
+ ldp x8,x9,[x1,#8*2]
+ ldp x10,x11,[x1,#8*4]
+ mov x27,#-8*8
+ ldp x12,x13,[x1,#8*6]
+ add x1,x1,#8*8
+
+.Lsqr8x_tail:
+ mul x14,x6,x4
+ adc x28,xzr,xzr // carry bit, modulo-scheduled
+ mul x15,x7,x4
+ add x27,x27,#8
+ mul x16,x8,x4
+ mul x17,x9,x4
+ adds x19,x19,x14
+ mul x14,x10,x4
+ adcs x20,x20,x15
+ mul x15,x11,x4
+ adcs x21,x21,x16
+ mul x16,x12,x4
+ adcs x22,x22,x17
+ mul x17,x13,x4
+ adcs x23,x23,x14
+ umulh x14,x6,x4
+ adcs x24,x24,x15
+ umulh x15,x7,x4
+ adcs x25,x25,x16
+ umulh x16,x8,x4
+ adcs x26,x26,x17
+ umulh x17,x9,x4
+ adc x28,x28,xzr
+ str x19,[x2],#8
+ adds x19,x20,x14
+ umulh x14,x10,x4
+ adcs x20,x21,x15
+ umulh x15,x11,x4
+ adcs x21,x22,x16
+ umulh x16,x12,x4
+ adcs x22,x23,x17
+ umulh x17,x13,x4
+ ldr x4,[x0,x27]
+ adcs x23,x24,x14
+ adcs x24,x25,x15
+ adcs x25,x26,x16
+ adcs x26,x28,x17
+ //adc x28,xzr,xzr // moved above
+ cbnz x27,.Lsqr8x_tail
+ // note that carry flag is guaranteed
+ // to be zero at this point
+ ldp x6,x7,[x2,#8*0]
+ sub x27,x3,x1 // done yet?
+ sub x16,x3,x5 // rewinded np
+ ldp x8,x9,[x2,#8*2]
+ ldp x10,x11,[x2,#8*4]
+ ldp x12,x13,[x2,#8*6]
+ cbz x27,.Lsqr8x_tail_break
+
+ ldur x4,[x0,#-8*8]
+ adds x19,x19,x6
+ adcs x20,x20,x7
+ ldp x6,x7,[x1,#8*0]
+ adcs x21,x21,x8
+ adcs x22,x22,x9
+ ldp x8,x9,[x1,#8*2]
+ adcs x23,x23,x10
+ adcs x24,x24,x11
+ ldp x10,x11,[x1,#8*4]
+ adcs x25,x25,x12
+ mov x27,#-8*8
+ adcs x26,x26,x13
+ ldp x12,x13,[x1,#8*6]
+ add x1,x1,#8*8
+ //adc x28,xzr,xzr // moved above
+ b .Lsqr8x_tail
+
+.align 4
+.Lsqr8x_tail_break:
+ ldr x4,[x29,#112] // pull n0
+ add x27,x2,#8*8 // end of current t[num] window
+
+ subs xzr,x30,#1 // "move" top-most carry to carry bit
+ adcs x14,x19,x6
+ adcs x15,x20,x7
+ ldp x19,x20,[x0,#8*0]
+ adcs x21,x21,x8
+ ldp x6,x7,[x16,#8*0] // recall that x16 is &n[0]
+ adcs x22,x22,x9
+ ldp x8,x9,[x16,#8*2]
+ adcs x23,x23,x10
+ adcs x24,x24,x11
+ ldp x10,x11,[x16,#8*4]
+ adcs x25,x25,x12
+ adcs x26,x26,x13
+ ldp x12,x13,[x16,#8*6]
+ add x1,x16,#8*8
+ adc x30,xzr,xzr // top-most carry
+ mul x28,x4,x19
+ stp x14,x15,[x2,#8*0]
+ stp x21,x22,[x2,#8*2]
+ ldp x21,x22,[x0,#8*2]
+ stp x23,x24,[x2,#8*4]
+ ldp x23,x24,[x0,#8*4]
+ cmp x27,x29 // did we hit the bottom?
+ stp x25,x26,[x2,#8*6]
+ mov x2,x0 // slide the window
+ ldp x25,x26,[x0,#8*6]
+ mov x27,#8
+ b.ne .Lsqr8x_reduction
+
+ // Final step. We see if result is larger than modulus, and
+ // if it is, subtract the modulus. But comparison implies
+ // subtraction. So we subtract modulus, see if it borrowed,
+ // and conditionally copy original value.
+ ldr x0,[x29,#96] // pull rp
+ add x2,x2,#8*8
+ subs x14,x19,x6
+ sbcs x15,x20,x7
+ sub x27,x5,#8*8
+ mov x3,x0 // x0 copy
+
+.Lsqr8x_sub:
+ sbcs x16,x21,x8
+ ldp x6,x7,[x1,#8*0]
+ sbcs x17,x22,x9
+ stp x14,x15,[x0,#8*0]
+ sbcs x14,x23,x10
+ ldp x8,x9,[x1,#8*2]
+ sbcs x15,x24,x11
+ stp x16,x17,[x0,#8*2]
+ sbcs x16,x25,x12
+ ldp x10,x11,[x1,#8*4]
+ sbcs x17,x26,x13
+ ldp x12,x13,[x1,#8*6]
+ add x1,x1,#8*8
+ ldp x19,x20,[x2,#8*0]
+ sub x27,x27,#8*8
+ ldp x21,x22,[x2,#8*2]
+ ldp x23,x24,[x2,#8*4]
+ ldp x25,x26,[x2,#8*6]
+ add x2,x2,#8*8
+ stp x14,x15,[x0,#8*4]
+ sbcs x14,x19,x6
+ stp x16,x17,[x0,#8*6]
+ add x0,x0,#8*8
+ sbcs x15,x20,x7
+ cbnz x27,.Lsqr8x_sub
+
+ sbcs x16,x21,x8
+ mov x2,sp
+ add x1,sp,x5
+ ldp x6,x7,[x3,#8*0]
+ sbcs x17,x22,x9
+ stp x14,x15,[x0,#8*0]
+ sbcs x14,x23,x10
+ ldp x8,x9,[x3,#8*2]
+ sbcs x15,x24,x11
+ stp x16,x17,[x0,#8*2]
+ sbcs x16,x25,x12
+ ldp x19,x20,[x1,#8*0]
+ sbcs x17,x26,x13
+ ldp x21,x22,[x1,#8*2]
+ sbcs xzr,x30,xzr // did it borrow?
+ ldr x30,[x29,#8] // pull return address
+ stp x14,x15,[x0,#8*4]
+ stp x16,x17,[x0,#8*6]
+
+ sub x27,x5,#8*4
+.Lsqr4x_cond_copy:
+ sub x27,x27,#8*4
+ csel x14,x19,x6,lo
+ stp xzr,xzr,[x2,#8*0]
+ csel x15,x20,x7,lo
+ ldp x6,x7,[x3,#8*4]
+ ldp x19,x20,[x1,#8*4]
+ csel x16,x21,x8,lo
+ stp xzr,xzr,[x2,#8*2]
+ add x2,x2,#8*4
+ csel x17,x22,x9,lo
+ ldp x8,x9,[x3,#8*6]
+ ldp x21,x22,[x1,#8*6]
+ add x1,x1,#8*4
+ stp x14,x15,[x3,#8*0]
+ stp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+ stp xzr,xzr,[x1,#8*0]
+ stp xzr,xzr,[x1,#8*2]
+ cbnz x27,.Lsqr4x_cond_copy
+
+ csel x14,x19,x6,lo
+ stp xzr,xzr,[x2,#8*0]
+ csel x15,x20,x7,lo
+ stp xzr,xzr,[x2,#8*2]
+ csel x16,x21,x8,lo
+ csel x17,x22,x9,lo
+ stp x14,x15,[x3,#8*0]
+ stp x16,x17,[x3,#8*2]
+
+ b .Lsqr8x_done
+
+.align 4
+.Lsqr8x8_post_condition:
+ adc x28,xzr,xzr
+ ldr x30,[x29,#8] // pull return address
+ // x19-7,x28 hold result, x6-7 hold modulus
+ subs x6,x19,x6
+ ldr x1,[x29,#96] // pull rp
+ sbcs x7,x20,x7
+ stp xzr,xzr,[sp,#8*0]
+ sbcs x8,x21,x8
+ stp xzr,xzr,[sp,#8*2]
+ sbcs x9,x22,x9
+ stp xzr,xzr,[sp,#8*4]
+ sbcs x10,x23,x10
+ stp xzr,xzr,[sp,#8*6]
+ sbcs x11,x24,x11
+ stp xzr,xzr,[sp,#8*8]
+ sbcs x12,x25,x12
+ stp xzr,xzr,[sp,#8*10]
+ sbcs x13,x26,x13
+ stp xzr,xzr,[sp,#8*12]
+ sbcs x28,x28,xzr // did it borrow?
+ stp xzr,xzr,[sp,#8*14]
+
+ // x6-7 hold result-modulus
+ csel x6,x19,x6,lo
+ csel x7,x20,x7,lo
+ csel x8,x21,x8,lo
+ csel x9,x22,x9,lo
+ stp x6,x7,[x1,#8*0]
+ csel x10,x23,x10,lo
+ csel x11,x24,x11,lo
+ stp x8,x9,[x1,#8*2]
+ csel x12,x25,x12,lo
+ csel x13,x26,x13,lo
+ stp x10,x11,[x1,#8*4]
+ stp x12,x13,[x1,#8*6]
+
+.Lsqr8x_done:
+ ldp x19,x20,[x29,#16]
+ mov sp,x29
+ ldp x21,x22,[x29,#32]
+ mov x0,#1
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldr x29,[sp],#128
+.inst 0xd50323bf // autiasp
+ ret
+.size __bn_sqr8x_mont,.-__bn_sqr8x_mont
+.type __bn_mul4x_mont,%function
+.align 5
+__bn_mul4x_mont:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+
+ sub x26,sp,x5,lsl#3
+ lsl x5,x5,#3
+ ldr x4,[x4] // *n0
+ sub sp,x26,#8*4 // alloca
+
+ add x10,x2,x5
+ add x27,x1,x5
+ stp x0,x10,[x29,#96] // offload rp and &b[num]
+
+ ldr x24,[x2,#8*0] // b[0]
+ ldp x6,x7,[x1,#8*0] // a[0..3]
+ ldp x8,x9,[x1,#8*2]
+ add x1,x1,#8*4
+ mov x19,xzr
+ mov x20,xzr
+ mov x21,xzr
+ mov x22,xzr
+ ldp x14,x15,[x3,#8*0] // n[0..3]
+ ldp x16,x17,[x3,#8*2]
+ adds x3,x3,#8*4 // clear carry bit
+ mov x0,xzr
+ mov x28,#0
+ mov x26,sp
+
+.Loop_mul4x_1st_reduction:
+ mul x10,x6,x24 // lo(a[0..3]*b[0])
+ adc x0,x0,xzr // modulo-scheduled
+ mul x11,x7,x24
+ add x28,x28,#8
+ mul x12,x8,x24
+ and x28,x28,#31
+ mul x13,x9,x24
+ adds x19,x19,x10
+ umulh x10,x6,x24 // hi(a[0..3]*b[0])
+ adcs x20,x20,x11
+ mul x25,x19,x4 // t[0]*n0
+ adcs x21,x21,x12
+ umulh x11,x7,x24
+ adcs x22,x22,x13
+ umulh x12,x8,x24
+ adc x23,xzr,xzr
+ umulh x13,x9,x24
+ ldr x24,[x2,x28] // next b[i] (or b[0])
+ adds x20,x20,x10
+ // (*) mul x10,x14,x25 // lo(n[0..3]*t[0]*n0)
+ str x25,[x26],#8 // put aside t[0]*n0 for tail processing
+ adcs x21,x21,x11
+ mul x11,x15,x25
+ adcs x22,x22,x12
+ mul x12,x16,x25
+ adc x23,x23,x13 // can't overflow
+ mul x13,x17,x25
+ // (*) adds xzr,x19,x10
+ subs xzr,x19,#1 // (*)
+ umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0)
+ adcs x19,x20,x11
+ umulh x11,x15,x25
+ adcs x20,x21,x12
+ umulh x12,x16,x25
+ adcs x21,x22,x13
+ umulh x13,x17,x25
+ adcs x22,x23,x0
+ adc x0,xzr,xzr
+ adds x19,x19,x10
+ sub x10,x27,x1
+ adcs x20,x20,x11
+ adcs x21,x21,x12
+ adcs x22,x22,x13
+ //adc x0,x0,xzr
+ cbnz x28,.Loop_mul4x_1st_reduction
+
+ cbz x10,.Lmul4x4_post_condition
+
+ ldp x6,x7,[x1,#8*0] // a[4..7]
+ ldp x8,x9,[x1,#8*2]
+ add x1,x1,#8*4
+ ldr x25,[sp] // a[0]*n0
+ ldp x14,x15,[x3,#8*0] // n[4..7]
+ ldp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+
+.Loop_mul4x_1st_tail:
+ mul x10,x6,x24 // lo(a[4..7]*b[i])
+ adc x0,x0,xzr // modulo-scheduled
+ mul x11,x7,x24
+ add x28,x28,#8
+ mul x12,x8,x24
+ and x28,x28,#31
+ mul x13,x9,x24
+ adds x19,x19,x10
+ umulh x10,x6,x24 // hi(a[4..7]*b[i])
+ adcs x20,x20,x11
+ umulh x11,x7,x24
+ adcs x21,x21,x12
+ umulh x12,x8,x24
+ adcs x22,x22,x13
+ umulh x13,x9,x24
+ adc x23,xzr,xzr
+ ldr x24,[x2,x28] // next b[i] (or b[0])
+ adds x20,x20,x10
+ mul x10,x14,x25 // lo(n[4..7]*a[0]*n0)
+ adcs x21,x21,x11
+ mul x11,x15,x25
+ adcs x22,x22,x12
+ mul x12,x16,x25
+ adc x23,x23,x13 // can't overflow
+ mul x13,x17,x25
+ adds x19,x19,x10
+ umulh x10,x14,x25 // hi(n[4..7]*a[0]*n0)
+ adcs x20,x20,x11
+ umulh x11,x15,x25
+ adcs x21,x21,x12
+ umulh x12,x16,x25
+ adcs x22,x22,x13
+ adcs x23,x23,x0
+ umulh x13,x17,x25
+ adc x0,xzr,xzr
+ ldr x25,[sp,x28] // next t[0]*n0
+ str x19,[x26],#8 // result!!!
+ adds x19,x20,x10
+ sub x10,x27,x1 // done yet?
+ adcs x20,x21,x11
+ adcs x21,x22,x12
+ adcs x22,x23,x13
+ //adc x0,x0,xzr
+ cbnz x28,.Loop_mul4x_1st_tail
+
+ sub x11,x27,x5 // rewinded x1
+ cbz x10,.Lmul4x_proceed
+
+ ldp x6,x7,[x1,#8*0]
+ ldp x8,x9,[x1,#8*2]
+ add x1,x1,#8*4
+ ldp x14,x15,[x3,#8*0]
+ ldp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+ b .Loop_mul4x_1st_tail
+
+.align 5
+.Lmul4x_proceed:
+ ldr x24,[x2,#8*4]! // *++b
+ adc x30,x0,xzr
+ ldp x6,x7,[x11,#8*0] // a[0..3]
+ sub x3,x3,x5 // rewind np
+ ldp x8,x9,[x11,#8*2]
+ add x1,x11,#8*4
+
+ stp x19,x20,[x26,#8*0] // result!!!
+ ldp x19,x20,[sp,#8*4] // t[0..3]
+ stp x21,x22,[x26,#8*2] // result!!!
+ ldp x21,x22,[sp,#8*6]
+
+ ldp x14,x15,[x3,#8*0] // n[0..3]
+ mov x26,sp
+ ldp x16,x17,[x3,#8*2]
+ adds x3,x3,#8*4 // clear carry bit
+ mov x0,xzr
+
+.align 4
+.Loop_mul4x_reduction:
+ mul x10,x6,x24 // lo(a[0..3]*b[4])
+ adc x0,x0,xzr // modulo-scheduled
+ mul x11,x7,x24
+ add x28,x28,#8
+ mul x12,x8,x24
+ and x28,x28,#31
+ mul x13,x9,x24
+ adds x19,x19,x10
+ umulh x10,x6,x24 // hi(a[0..3]*b[4])
+ adcs x20,x20,x11
+ mul x25,x19,x4 // t[0]*n0
+ adcs x21,x21,x12
+ umulh x11,x7,x24
+ adcs x22,x22,x13
+ umulh x12,x8,x24
+ adc x23,xzr,xzr
+ umulh x13,x9,x24
+ ldr x24,[x2,x28] // next b[i]
+ adds x20,x20,x10
+ // (*) mul x10,x14,x25
+ str x25,[x26],#8 // put aside t[0]*n0 for tail processing
+ adcs x21,x21,x11
+ mul x11,x15,x25 // lo(n[0..3]*t[0]*n0
+ adcs x22,x22,x12
+ mul x12,x16,x25
+ adc x23,x23,x13 // can't overflow
+ mul x13,x17,x25
+ // (*) adds xzr,x19,x10
+ subs xzr,x19,#1 // (*)
+ umulh x10,x14,x25 // hi(n[0..3]*t[0]*n0
+ adcs x19,x20,x11
+ umulh x11,x15,x25
+ adcs x20,x21,x12
+ umulh x12,x16,x25
+ adcs x21,x22,x13
+ umulh x13,x17,x25
+ adcs x22,x23,x0
+ adc x0,xzr,xzr
+ adds x19,x19,x10
+ adcs x20,x20,x11
+ adcs x21,x21,x12
+ adcs x22,x22,x13
+ //adc x0,x0,xzr
+ cbnz x28,.Loop_mul4x_reduction
+
+ adc x0,x0,xzr
+ ldp x10,x11,[x26,#8*4] // t[4..7]
+ ldp x12,x13,[x26,#8*6]
+ ldp x6,x7,[x1,#8*0] // a[4..7]
+ ldp x8,x9,[x1,#8*2]
+ add x1,x1,#8*4
+ adds x19,x19,x10
+ adcs x20,x20,x11
+ adcs x21,x21,x12
+ adcs x22,x22,x13
+ //adc x0,x0,xzr
+
+ ldr x25,[sp] // t[0]*n0
+ ldp x14,x15,[x3,#8*0] // n[4..7]
+ ldp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+
+.align 4
+.Loop_mul4x_tail:
+ mul x10,x6,x24 // lo(a[4..7]*b[4])
+ adc x0,x0,xzr // modulo-scheduled
+ mul x11,x7,x24
+ add x28,x28,#8
+ mul x12,x8,x24
+ and x28,x28,#31
+ mul x13,x9,x24
+ adds x19,x19,x10
+ umulh x10,x6,x24 // hi(a[4..7]*b[4])
+ adcs x20,x20,x11
+ umulh x11,x7,x24
+ adcs x21,x21,x12
+ umulh x12,x8,x24
+ adcs x22,x22,x13
+ umulh x13,x9,x24
+ adc x23,xzr,xzr
+ ldr x24,[x2,x28] // next b[i]
+ adds x20,x20,x10
+ mul x10,x14,x25 // lo(n[4..7]*t[0]*n0)
+ adcs x21,x21,x11
+ mul x11,x15,x25
+ adcs x22,x22,x12
+ mul x12,x16,x25
+ adc x23,x23,x13 // can't overflow
+ mul x13,x17,x25
+ adds x19,x19,x10
+ umulh x10,x14,x25 // hi(n[4..7]*t[0]*n0)
+ adcs x20,x20,x11
+ umulh x11,x15,x25
+ adcs x21,x21,x12
+ umulh x12,x16,x25
+ adcs x22,x22,x13
+ umulh x13,x17,x25
+ adcs x23,x23,x0
+ ldr x25,[sp,x28] // next a[0]*n0
+ adc x0,xzr,xzr
+ str x19,[x26],#8 // result!!!
+ adds x19,x20,x10
+ sub x10,x27,x1 // done yet?
+ adcs x20,x21,x11
+ adcs x21,x22,x12
+ adcs x22,x23,x13
+ //adc x0,x0,xzr
+ cbnz x28,.Loop_mul4x_tail
+
+ sub x11,x3,x5 // rewinded np?
+ adc x0,x0,xzr
+ cbz x10,.Loop_mul4x_break
+
+ ldp x10,x11,[x26,#8*4]
+ ldp x12,x13,[x26,#8*6]
+ ldp x6,x7,[x1,#8*0]
+ ldp x8,x9,[x1,#8*2]
+ add x1,x1,#8*4
+ adds x19,x19,x10
+ adcs x20,x20,x11
+ adcs x21,x21,x12
+ adcs x22,x22,x13
+ //adc x0,x0,xzr
+ ldp x14,x15,[x3,#8*0]
+ ldp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+ b .Loop_mul4x_tail
+
+.align 4
+.Loop_mul4x_break:
+ ldp x12,x13,[x29,#96] // pull rp and &b[num]
+ adds x19,x19,x30
+ add x2,x2,#8*4 // bp++
+ adcs x20,x20,xzr
+ sub x1,x1,x5 // rewind ap
+ adcs x21,x21,xzr
+ stp x19,x20,[x26,#8*0] // result!!!
+ adcs x22,x22,xzr
+ ldp x19,x20,[sp,#8*4] // t[0..3]
+ adc x30,x0,xzr
+ stp x21,x22,[x26,#8*2] // result!!!
+ cmp x2,x13 // done yet?
+ ldp x21,x22,[sp,#8*6]
+ ldp x14,x15,[x11,#8*0] // n[0..3]
+ ldp x16,x17,[x11,#8*2]
+ add x3,x11,#8*4
+ b.eq .Lmul4x_post
+
+ ldr x24,[x2]
+ ldp x6,x7,[x1,#8*0] // a[0..3]
+ ldp x8,x9,[x1,#8*2]
+ adds x1,x1,#8*4 // clear carry bit
+ mov x0,xzr
+ mov x26,sp
+ b .Loop_mul4x_reduction
+
+.align 4
+.Lmul4x_post:
+ // Final step. We see if result is larger than modulus, and
+ // if it is, subtract the modulus. But comparison implies
+ // subtraction. So we subtract modulus, see if it borrowed,
+ // and conditionally copy original value.
+ mov x0,x12
+ mov x27,x12 // x0 copy
+ subs x10,x19,x14
+ add x26,sp,#8*8
+ sbcs x11,x20,x15
+ sub x28,x5,#8*4
+
+.Lmul4x_sub:
+ sbcs x12,x21,x16
+ ldp x14,x15,[x3,#8*0]
+ sub x28,x28,#8*4
+ ldp x19,x20,[x26,#8*0]
+ sbcs x13,x22,x17
+ ldp x16,x17,[x3,#8*2]
+ add x3,x3,#8*4
+ ldp x21,x22,[x26,#8*2]
+ add x26,x26,#8*4
+ stp x10,x11,[x0,#8*0]
+ sbcs x10,x19,x14
+ stp x12,x13,[x0,#8*2]
+ add x0,x0,#8*4
+ sbcs x11,x20,x15
+ cbnz x28,.Lmul4x_sub
+
+ sbcs x12,x21,x16
+ mov x26,sp
+ add x1,sp,#8*4
+ ldp x6,x7,[x27,#8*0]
+ sbcs x13,x22,x17
+ stp x10,x11,[x0,#8*0]
+ ldp x8,x9,[x27,#8*2]
+ stp x12,x13,[x0,#8*2]
+ ldp x19,x20,[x1,#8*0]
+ ldp x21,x22,[x1,#8*2]
+ sbcs xzr,x30,xzr // did it borrow?
+ ldr x30,[x29,#8] // pull return address
+
+ sub x28,x5,#8*4
+.Lmul4x_cond_copy:
+ sub x28,x28,#8*4
+ csel x10,x19,x6,lo
+ stp xzr,xzr,[x26,#8*0]
+ csel x11,x20,x7,lo
+ ldp x6,x7,[x27,#8*4]
+ ldp x19,x20,[x1,#8*4]
+ csel x12,x21,x8,lo
+ stp xzr,xzr,[x26,#8*2]
+ add x26,x26,#8*4
+ csel x13,x22,x9,lo
+ ldp x8,x9,[x27,#8*6]
+ ldp x21,x22,[x1,#8*6]
+ add x1,x1,#8*4
+ stp x10,x11,[x27,#8*0]
+ stp x12,x13,[x27,#8*2]
+ add x27,x27,#8*4
+ cbnz x28,.Lmul4x_cond_copy
+
+ csel x10,x19,x6,lo
+ stp xzr,xzr,[x26,#8*0]
+ csel x11,x20,x7,lo
+ stp xzr,xzr,[x26,#8*2]
+ csel x12,x21,x8,lo
+ stp xzr,xzr,[x26,#8*3]
+ csel x13,x22,x9,lo
+ stp xzr,xzr,[x26,#8*4]
+ stp x10,x11,[x27,#8*0]
+ stp x12,x13,[x27,#8*2]
+
+ b .Lmul4x_done
+
+.align 4
+.Lmul4x4_post_condition:
+ adc x0,x0,xzr
+ ldr x1,[x29,#96] // pull rp
+ // x19-3,x0 hold result, x14-7 hold modulus
+ subs x6,x19,x14
+ ldr x30,[x29,#8] // pull return address
+ sbcs x7,x20,x15
+ stp xzr,xzr,[sp,#8*0]
+ sbcs x8,x21,x16
+ stp xzr,xzr,[sp,#8*2]
+ sbcs x9,x22,x17
+ stp xzr,xzr,[sp,#8*4]
+ sbcs xzr,x0,xzr // did it borrow?
+ stp xzr,xzr,[sp,#8*6]
+
+ // x6-3 hold result-modulus
+ csel x6,x19,x6,lo
+ csel x7,x20,x7,lo
+ csel x8,x21,x8,lo
+ csel x9,x22,x9,lo
+ stp x6,x7,[x1,#8*0]
+ stp x8,x9,[x1,#8*2]
+
+.Lmul4x_done:
+ ldp x19,x20,[x29,#16]
+ mov sp,x29
+ ldp x21,x22,[x29,#32]
+ mov x0,#1
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldr x29,[sp],#128
+.inst 0xd50323bf // autiasp
+ ret
+.size __bn_mul4x_mont,.-__bn_mul4x_mont
+.byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 2
+.align 4
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/ec/ecp_nistz256-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/ec/ecp_nistz256-armv8.S
new file mode 100644
index 0000000..efd46af
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/ec/ecp_nistz256-armv8.S
@@ -0,0 +1,4242 @@
+#include "arm_arch.h"
+
+.text
+.globl ecp_nistz256_precomputed
+.type ecp_nistz256_precomputed,%object
+.align 12
+ecp_nistz256_precomputed:
+.byte 0x3c,0x4d,0x27,0xcc,0xf5,0x4a,0x4f,0x8f,0xe8,0xc8,0x04,0x68,0x09,0x4a,0x5b,0x80,0x9d,0x7a,0xe8,0x31,0x08,0x76,0x68,0x19,0x9f,0x08,0xb4,0x1f,0x32,0x43,0x89,0xd8,0x34,0xd3,0xf5,0xb7,0xb5,0xee,0x42,0x3e,0x91,0x01,0x06,0x7c,0xbf,0xd9,0x97,0x12,0xd3,0x1a,0xc9,0x04,0x8d,0x53,0x83,0x14,0x28,0xf0,0x8e,0x19,0xcc,0x91,0xe5,0x80
+.byte 0x14,0xd6,0xc1,0x8d,0x61,0x66,0x3b,0xa7,0x20,0x1e,0xe4,0x77,0xd7,0x66,0x05,0xfb,0x5c,0xa9,0x9a,0x7a,0xb2,0x30,0x50,0x28,0x87,0x80,0xfe,0xcd,0xe1,0xb3,0xff,0xa3,0x45,0x3c,0x7e,0x9b,0x08,0xc0,0xc1,0x9f,0x2e,0xad,0x7d,0x89,0x79,0x90,0x60,0xc6,0xac,0x17,0x64,0x59,0x4d,0xcf,0x56,0x7a,0xca,0x82,0xaa,0x6e,0x04,0x2f,0x1f,0x8b
+.byte 0xa9,0xdd,0xeb,0x91,0x5c,0x77,0x17,0x99,0x4e,0xc2,0x45,0x69,0x2e,0xcf,0x60,0xc6,0x3c,0xad,0x65,0x33,0x35,0x6f,0xe4,0xd0,0x37,0x1f,0xe2,0x2c,0x66,0x98,0x55,0xe3,0x66,0xa2,0xc6,0x21,0xce,0x63,0x59,0x2e,0xd2,0x2b,0x8a,0x5a,0xcd,0xee,0xa7,0xad,0xf6,0x8c,0x3f,0x44,0x6c,0x12,0x30,0x8d,0xca,0xea,0x46,0x8a,0x4c,0x96,0xf9,0x96
+.byte 0x18,0x10,0x4e,0x46,0xc4,0x3e,0xa0,0x94,0x26,0x9d,0x62,0xd2,0x4b,0xb0,0xbc,0x0b,0xd5,0x56,0xa5,0xd2,0xc1,0x2f,0x2d,0x15,0xd8,0xed,0x97,0x17,0xcb,0x32,0x67,0xc5,0x0f,0x7c,0xde,0xa8,0x8c,0x4d,0xa0,0xb8,0x2e,0xed,0x24,0xd5,0xd5,0x49,0xca,0x77,0x1f,0x48,0x3b,0x83,0x54,0xb2,0xe7,0x7e,0x7a,0xa7,0x5c,0xed,0x7f,0xa1,0x9f,0x05
+.byte 0xd4,0xd4,0x90,0x0d,0xae,0x37,0x4e,0xd1,0x8f,0xd1,0x0a,0xa7,0x63,0x5b,0xb7,0x65,0xcb,0xc8,0xba,0x29,0xec,0x35,0x53,0xb2,0xac,0x32,0xf4,0xb7,0x6a,0xb1,0x69,0xcf,0x56,0x14,0x7f,0xd6,0xc5,0xca,0x88,0x1d,0x49,0xcf,0xfd,0x1f,0xcc,0xb1,0x13,0x30,0x42,0xd0,0x1c,0x6e,0x38,0x8e,0xf9,0x40,0xe7,0xe8,0xd6,0x28,0x1a,0x75,0x31,0xf3
+.byte 0x30,0x46,0x3f,0xb5,0x8a,0x47,0x35,0x4c,0x6e,0xdb,0x26,0x1a,0x25,0xa3,0xd8,0x0b,0x1d,0x51,0x12,0x91,0x4c,0x11,0x76,0x83,0x19,0xad,0x2a,0x3e,0xb4,0x1c,0x3c,0xfc,0x14,0x20,0x84,0x58,0x7b,0xc3,0x94,0x68,0x60,0x5c,0x3f,0x7c,0x26,0xb5,0x75,0x41,0x0b,0xc2,0xec,0xf3,0x96,0x5b,0xbb,0x41,0x32,0x00,0x4e,0x68,0xeb,0xf1,0xd9,0x96
+.byte 0xe7,0x00,0xac,0xb0,0x1b,0x39,0x46,0xf1,0xc9,0x18,0x7d,0xb7,0xc4,0x42,0xbc,0x8b,0x09,0x3e,0xa9,0x97,0x2e,0xc6,0xf8,0x38,0xa3,0xe4,0x2c,0x52,0x5d,0x24,0xf7,0xc5,0x15,0xab,0x16,0x5e,0x46,0x2c,0xd8,0xd7,0x4d,0xb3,0xf2,0xfd,0xe4,0x75,0x3c,0x34,0x95,0xb9,0x8c,0x92,0x35,0x42,0x8b,0xc4,0xc8,0x6c,0xd4,0x1e,0x67,0x35,0xd3,0x6d
+.byte 0x79,0x85,0xff,0x74,0xbe,0x40,0x07,0x27,0x75,0x2c,0xea,0x04,0xcc,0xa2,0x72,0x80,0x97,0x5f,0xfe,0x8a,0x56,0x0f,0xf4,0x6d,0xa4,0x61,0x04,0x4b,0x5e,0xb4,0xe2,0xd8,0x87,0xb6,0xfd,0x3d,0x00,0x8a,0xa9,0xe4,0x62,0x5f,0x4f,0xec,0x1e,0x40,0x28,0x6b,0x21,0x0f,0x50,0x26,0x97,0xa0,0x25,0x8f,0x3e,0xf2,0x69,0xdc,0x36,0xe5,0xb8,0xdb
+.byte 0x01,0x7d,0xfb,0x73,0x7d,0x3e,0xf7,0x55,0x41,0x39,0xe0,0x33,0x0d,0xe3,0x4b,0x6b,0x7b,0x3e,0x6e,0xdc,0x7d,0x9a,0x6e,0x35,0xb0,0x38,0x13,0x92,0x80,0xa1,0xe6,0xbf,0x03,0x9d,0xb7,0x7f,0x55,0xce,0x46,0x3c,0x22,0xc7,0xfa,0xfb,0x18,0xba,0x06,0xa0,0x09,0x78,0x3f,0xc0,0x79,0x5f,0xe6,0x6a,0x29,0xaf,0xd1,0xc7,0x84,0xa7,0xed,0xb9
+.byte 0xb6,0x82,0x81,0xc1,0x53,0xee,0x00,0x34,0xa8,0x81,0xdf,0x5a,0xd3,0x07,0x7e,0x2e,0x17,0x40,0xa1,0x2b,0xf4,0x2a,0x1f,0x9a,0x67,0x75,0x73,0xa8,0x58,0x65,0x17,0xdf,0xf1,0x84,0x76,0xc5,0x8d,0x48,0x93,0xe1,0x28,0xa5,0x73,0x10,0x6e,0x9e,0x39,0x03,0x69,0x52,0xdf,0xf9,0x46,0x7c,0x5b,0xf3,0x5b,0x9a,0x63,0xd9,0x4f,0xf5,0x8e,0x73
+.byte 0xed,0x33,0x7d,0x23,0xb9,0x6c,0x3c,0x9b,0xa7,0xcf,0x7f,0x34,0x6f,0x97,0xe2,0xfe,0x0a,0x8b,0xe1,0x86,0x83,0x91,0x2e,0xdd,0x6b,0xb1,0xbf,0xa6,0x92,0x4f,0x30,0x79,0x68,0x91,0x3e,0x06,0x17,0xe9,0x0b,0x25,0x07,0xa6,0x88,0x91,0x6c,0x6e,0xc8,0xd8,0xdc,0x68,0x5e,0x45,0xf2,0x55,0xef,0x56,0x38,0x29,0xd0,0x89,0x40,0x58,0x51,0x9f
+.byte 0x5f,0xa4,0x08,0xc6,0x94,0x34,0xd2,0x6f,0x59,0x0f,0x6e,0xca,0x85,0x7f,0x56,0x3f,0xac,0x8f,0x25,0x0f,0x47,0xe3,0x9e,0x40,0xed,0xd8,0xae,0x30,0x0d,0xb4,0x47,0x40,0x4b,0xa3,0x23,0x1b,0x7f,0x0f,0xff,0xdf,0x6f,0x1d,0x87,0xb2,0x94,0xa0,0x36,0xbb,0x53,0x13,0x1e,0xaf,0x92,0xf8,0x07,0x95,0xc7,0xe4,0xa8,0x41,0xa9,0xed,0xf0,0x08
+.byte 0xfc,0xc1,0x4a,0xed,0x9a,0x4f,0x13,0xc5,0xed,0x8a,0x95,0xf5,0x69,0xf7,0xee,0x75,0xb6,0x4d,0xba,0x8f,0x65,0x23,0xe8,0x50,0x9e,0x7a,0xd7,0x28,0x3a,0x49,0xe7,0x4c,0x7c,0xc6,0x64,0xbd,0x8c,0x17,0x14,0x0b,0xb5,0xe3,0xb4,0xab,0x0b,0x9a,0xa9,0x29,0x84,0xaa,0xba,0x69,0xc4,0x2e,0xbf,0xca,0x57,0x0d,0xd3,0x36,0x21,0x61,0x00,0x13
+.byte 0x95,0xe3,0xf8,0xa6,0x64,0x74,0x02,0xb5,0xbf,0x86,0x07,0xde,0x67,0x48,0x23,0xe0,0x24,0x96,0x3a,0x86,0xb2,0xfa,0xa7,0x75,0xb4,0x26,0x42,0xcb,0x96,0x4e,0xf7,0x90,0xae,0xa5,0xe4,0xd0,0x45,0x31,0xe7,0x0f,0xe0,0xcb,0xbf,0x94,0x94,0x33,0x4f,0x65,0x04,0xfb,0xc0,0xc4,0x3f,0x51,0xa5,0xf3,0xea,0xc8,0xd5,0x23,0x66,0xe0,0x48,0x09
+.byte 0xba,0x6a,0x27,0x50,0xec,0xae,0xd2,0x2a,0xe6,0xf9,0xe4,0xde,0x35,0x6e,0xcc,0x82,0x76,0xfc,0x36,0x16,0xe1,0x9f,0xc7,0x0d,0xc1,0xc9,0x6a,0x23,0xbe,0xa1,0x3c,0xfd,0xce,0xa7,0x2e,0x91,0x36,0x23,0x5a,0x20,0xdf,0x55,0xc5,0x91,0x32,0x5c,0x62,0x49,0xe7,0x8b,0x0b,0x0e,0x9c,0x2e,0xee,0x1f,0xfe,0xca,0x00,0xfc,0x55,0xd7,0x9c,0x0a
+.byte 0x75,0xaa,0xb0,0x46,0x90,0x55,0x2b,0x46,0xab,0x98,0x9d,0xab,0x0e,0x12,0x03,0x58,0xf1,0x4a,0x68,0x59,0x74,0xc9,0x37,0x6d,0x6f,0xe6,0xd3,0x73,0xf1,0xa3,0xdd,0xbe,0x85,0xca,0x74,0xc6,0xb6,0x51,0x6f,0x83,0x6f,0xa1,0x80,0x00,0x00,0x78,0x0a,0xa7,0xff,0xa7,0xe2,0x2e,0x5f,0x4f,0x31,0xbb,0x1b,0x99,0x21,0x33,0x59,0x6e,0x03,0x38
+.byte 0x10,0xd9,0x98,0xf2,0x0c,0xad,0x08,0x6b,0x00,0x49,0xb5,0x5e,0x11,0x60,0x70,0x49,0xff,0x79,0xac,0xba,0x30,0x3d,0x69,0x9f,0xaf,0xfb,0xd7,0xeb,0xe2,0xcd,0x0d,0x97,0xb9,0x94,0xc8,0x6e,0x06,0x3b,0x64,0x80,0x71,0x8f,0x81,0xb0,0x58,0xe0,0xc7,0xbd,0x27,0x6a,0xd4,0xb7,0xd9,0x6c,0xc1,0x44,0x38,0xe1,0x36,0xbc,0x0a,0x33,0x26,0x01
+.byte 0x25,0x90,0xbc,0x0a,0xc2,0xa3,0xbb,0xfc,0xeb,0x0b,0x1a,0x38,0x98,0x26,0x93,0xf5,0x2d,0x29,0x41,0x83,0x3b,0xba,0x40,0x46,0xf3,0xf6,0xfd,0x53,0xb9,0x7a,0x60,0x01,0x8a,0x8d,0xb4,0x57,0xd8,0xf3,0x36,0x72,0x22,0x2f,0x59,0xd3,0x7f,0x25,0xf2,0x05,0x61,0xfa,0x18,0x28,0xac,0xd5,0x14,0x00,0xaf,0x8b,0x7c,0x39,0xb5,0xa2,0xcb,0x1e
+.byte 0x62,0x14,0xcb,0x10,0x76,0x17,0x23,0x2c,0xc8,0x25,0xac,0x37,0x9e,0x83,0x81,0x83,0xfe,0x2e,0x2c,0xd2,0x3f,0xf8,0x58,0x2b,0xf1,0x7f,0x4f,0xe1,0x17,0xc7,0xf7,0xad,0x57,0x67,0xc2,0x57,0x77,0x2e,0xfb,0xf2,0xce,0xa9,0x74,0x81,0x47,0xf8,0x5a,0x88,0x76,0xb1,0x43,0x75,0xc8,0xc4,0xc8,0x60,0x1e,0xd7,0xd1,0x1c,0xce,0x89,0x82,0xc6
+.byte 0x77,0x8d,0x87,0xe8,0xd0,0x5b,0x0c,0xf0,0x44,0x48,0x8d,0xee,0x55,0xc6,0xe4,0x2c,0x2c,0x41,0x75,0x5d,0x5a,0xd2,0xa3,0x1d,0x32,0x85,0x08,0xcf,0x03,0x3a,0x3c,0xfe,0x65,0x75,0xef,0xd2,0xa6,0x22,0x16,0x66,0x39,0x30,0x05,0xe3,0x57,0xab,0x71,0x6d,0x28,0xd5,0x2f,0xc6,0xa8,0x25,0x46,0x14,0xfd,0x7e,0xa2,0x67,0x7e,0x20,0x91,0xc2
+.byte 0x2b,0x03,0xdd,0xac,0xaa,0x1a,0xb5,0x2a,0x04,0xd6,0x15,0x9d,0x3f,0x54,0x24,0x7c,0x75,0xab,0x77,0xd9,0x6c,0x85,0xa2,0xf9,0x33,0xeb,0xeb,0xc0,0x27,0xcd,0x9d,0x58,0xae,0xa3,0x34,0x10,0xae,0x85,0x7d,0x4c,0x15,0x4c,0x90,0x46,0xe0,0x5b,0xec,0xa7,0xb2,0x68,0x85,0x01,0xed,0xf9,0x4a,0x85,0xe3,0xb6,0xea,0xe2,0x53,0xc0,0x32,0x83
+.byte 0x73,0x05,0x77,0xac,0xb5,0x96,0xaa,0xf0,0x9c,0x2c,0xa4,0xd2,0xd4,0xbf,0x74,0x2f,0x39,0x47,0x22,0x99,0x50,0x06,0x5f,0xcb,0x99,0xc5,0xc9,0x2e,0x70,0xd6,0x68,0x6a,0xc4,0x73,0x41,0xcb,0x8b,0xfd,0x23,0x98,0x11,0x59,0xad,0x20,0x8a,0x0d,0xaf,0xaa,0xd0,0xe2,0xeb,0x32,0x8b,0x6f,0x0e,0x43,0x12,0xe3,0x27,0x8f,0xf6,0xa4,0x76,0x0b
+.byte 0xfb,0x22,0xad,0xda,0x1c,0x0a,0x3e,0x90,0xc0,0x7d,0xf3,0x09,0xbc,0x17,0x33,0xef,0xf1,0xf2,0x84,0x80,0x2a,0x0b,0x82,0xd7,0x95,0xc7,0xd2,0x08,0x4a,0xf4,0xf5,0x6d,0x09,0x06,0x8e,0xe4,0x74,0x63,0x8f,0x09,0xca,0xe2,0xd9,0x0e,0x1e,0x03,0x20,0x1b,0x4c,0xfb,0x1d,0x5a,0x2e,0x28,0xeb,0x84,0x82,0x6f,0x97,0x6f,0xcd,0x7a,0xc3,0xa7
+.byte 0x79,0x73,0x66,0x0c,0x94,0xd5,0xf4,0x8f,0x2c,0x73,0x1f,0x24,0xbc,0x17,0xee,0xd5,0xb0,0xa6,0xb8,0x04,0x6d,0x6a,0xd0,0x61,0xe3,0x1a,0x49,0x97,0x94,0xc5,0x8e,0xbc,0xac,0x5b,0x0b,0x0a,0xc5,0x74,0x06,0x89,0xee,0xc2,0xb7,0x5f,0x1b,0xa1,0x6b,0x1a,0xff,0xed,0xda,0x90,0x91,0xc1,0x0d,0x6a,0x06,0xd6,0xcb,0x02,0x71,0x17,0x95,0x7d
+.byte 0xc6,0x3b,0x7e,0x6b,0xc8,0x73,0x03,0x0d,0x6b,0x8f,0x73,0x56,0x59,0x2e,0x09,0x23,0x4e,0xda,0xfc,0x4e,0xfc,0xa4,0x42,0x15,0x2e,0x10,0x6a,0x97,0x48,0x3c,0xb4,0xa4,0x0c,0x64,0x21,0xc3,0xeb,0x6c,0xac,0x27,0x4f,0x43,0x94,0x91,0x78,0xdc,0xfd,0xad,0x2b,0xa7,0x43,0x42,0xb0,0x51,0xdd,0x63,0xcc,0xcd,0xb7,0x15,0xfa,0x13,0x8d,0xc7
+.byte 0x55,0x3a,0x74,0x17,0x23,0x36,0x3e,0x23,0xe1,0x42,0x90,0xe1,0xb7,0xc7,0xda,0xb7,0x57,0xeb,0xc3,0xfb,0x62,0x58,0xbf,0x31,0x2a,0xfb,0xc7,0xdb,0x3d,0xfc,0x87,0x32,0xb1,0x3e,0xe5,0x3d,0x94,0x3d,0x86,0x32,0x61,0xfe,0x19,0xd2,0x32,0x31,0x8b,0x43,0xdb,0xab,0xa4,0xe5,0x34,0xc8,0x30,0xae,0x8c,0x02,0x53,0x99,0x35,0xb4,0x56,0x38
+.byte 0x37,0xcf,0xff,0xb0,0x05,0x21,0x12,0x65,0xc4,0xb3,0x9c,0x83,0x95,0x12,0xd3,0x03,0x7a,0x80,0x97,0x5b,0x67,0x33,0x27,0xfc,0x43,0xf2,0xf7,0xaa,0x60,0xb6,0xfc,0x55,0x44,0x30,0xa3,0x4a,0xa3,0x60,0x31,0xf7,0x01,0xfa,0xb0,0x8d,0x82,0x29,0xa7,0x03,0xb7,0x7e,0x3f,0xe5,0x66,0x26,0xb7,0x51,0xcf,0x8d,0xdd,0x6f,0x83,0x39,0xfc,0x9b
+.byte 0xa5,0x3d,0xb6,0x41,0x89,0x54,0xc3,0xb2,0xf0,0x24,0x64,0xcb,0x53,0xfd,0x0a,0x91,0x6c,0x6f,0x28,0xfe,0xc1,0xe9,0x17,0x2e,0x65,0x55,0x2e,0xf2,0x48,0x52,0xb1,0x69,0xf0,0xdd,0x42,0xd5,0xdf,0x7c,0x36,0x75,0xdb,0x5b,0x3d,0xa9,0x6d,0xa4,0xeb,0x47,0x4f,0x2b,0x5c,0xd0,0x30,0xee,0xa7,0x74,0x6a,0x64,0x8a,0xbc,0x9b,0xe5,0x82,0x56
+.byte 0x76,0xe4,0x3f,0xf5,0x05,0x59,0x19,0x1e,0x80,0x47,0xf1,0x77,0xac,0x32,0x43,0x80,0x0a,0x1b,0x28,0xb6,0xf4,0xe8,0x7c,0x2f,0xeb,0xa8,0x4b,0x6a,0x59,0xb5,0xf8,0x77,0x68,0xd4,0x86,0x6c,0x87,0xdc,0xc4,0x00,0x4f,0xce,0xdb,0xf6,0x34,0xc3,0x74,0x02,0x08,0xdb,0x0d,0x34,0x8d,0xea,0x49,0x4a,0x30,0x5f,0x1b,0xcd,0xa6,0x3a,0x34,0x94
+.byte 0x5f,0x32,0x6a,0x62,0x96,0x4b,0x51,0x89,0x30,0xc9,0x90,0xdf,0x77,0x73,0x0e,0x3c,0x5c,0xbd,0x5c,0xee,0xd9,0x77,0xea,0x23,0x42,0xaa,0xa5,0x6b,0xf9,0x8c,0xc4,0x70,0x68,0xdd,0x0b,0x65,0xa3,0xc7,0xe4,0x7b,0x0a,0x89,0x85,0x25,0x7d,0x84,0x99,0x39,0xe6,0xb8,0xbe,0x7f,0x31,0x0f,0x84,0x0c,0x98,0x72,0xab,0x4c,0x44,0xb0,0xa4,0x83
+.byte 0x90,0xbb,0x93,0x73,0x07,0x07,0xba,0x63,0x5b,0x61,0x70,0xe1,0x84,0xae,0xaa,0xd6,0xa3,0x5a,0x54,0xd1,0xea,0xc7,0x2c,0x7b,0x67,0x4b,0x8a,0x7f,0x66,0x28,0x8d,0x22,0xec,0x82,0x64,0x69,0x63,0xf0,0x53,0x2d,0x10,0x9c,0x9c,0x34,0x4f,0xc6,0x96,0x40,0xdb,0xce,0x0e,0xf7,0x3a,0x8a,0xee,0x3f,0x32,0x5f,0x2b,0x0c,0x4a,0xbc,0x63,0xfb
+.byte 0x18,0xf6,0x26,0x57,0xc9,0x13,0x13,0xb7,0xe0,0xcc,0x3e,0x4e,0x73,0xfa,0xe2,0x54,0xc1,0x67,0xfe,0xe2,0xec,0xfd,0xaf,0xf9,0x96,0x99,0x9f,0xe9,0xe2,0xd0,0x94,0x39,0x33,0xc9,0xca,0x35,0x27,0xad,0x58,0x46,0x98,0x64,0x17,0x5f,0xe9,0xce,0x4b,0xc8,0xab,0x0d,0xd2,0x88,0xec,0xbb,0x5c,0xba,0xc1,0x30,0x4c,0xd4,0x99,0x0d,0x07,0x95
+.byte 0x0a,0xa5,0xeb,0xa6,0x10,0x4b,0x4d,0x77,0x14,0x76,0x88,0x43,0x7f,0x6b,0x5d,0x9b,0x87,0x1d,0x6b,0x5d,0xb9,0x04,0xa9,0xc7,0x28,0x18,0x70,0xa1,0x99,0xbc,0x99,0xf5,0xf1,0x71,0xa9,0x3a,0xb6,0xe5,0x98,0x98,0x8f,0x7a,0x6c,0xda,0x1a,0x63,0x0e,0xf1,0xe8,0x10,0xa3,0x7c,0x64,0x7e,0xde,0x2a,0x59,0x1b,0x04,0xca,0x69,0x8e,0xba,0x2f
+.byte 0x56,0xe1,0xa7,0xab,0x4f,0xe4,0x9d,0x49,0x33,0x9e,0x4e,0x5b,0xe1,0x58,0xc4,0x3f,0x99,0x5a,0x69,0x00,0xe5,0x5f,0x85,0xcb,0x62,0x80,0x5e,0x3d,0x88,0x0a,0x32,0x42,0xc1,0xf9,0x6a,0xa0,0xeb,0x65,0x2f,0x17,0x62,0x25,0x96,0x50,0xa2,0x6e,0xd6,0xdf,0x09,0xb7,0x1e,0x68,0xb2,0x10,0x2b,0xf3,0x9e,0xb2,0x67,0x75,0x9b,0xe3,0x76,0xfe
+.byte 0x95,0xbe,0x83,0xcb,0xba,0x77,0x5b,0x2d,0x5f,0xdd,0x94,0xbb,0x0e,0x5d,0x83,0xa2,0xe7,0x48,0x4c,0x84,0x86,0x41,0x47,0x4b,0x96,0x24,0x89,0xa8,0x20,0x04,0xa5,0xef,0x8e,0xb6,0xeb,0xcd,0x3c,0x77,0xc5,0x65,0x5c,0xff,0xa6,0x0d,0x2b,0x58,0x21,0x5a,0x11,0xe2,0x24,0x64,0x1c,0xd6,0x18,0x9a,0xac,0x3f,0x42,0x0e,0xeb,0x32,0x3e,0xed
+.byte 0xce,0x61,0xc9,0xe4,0xe7,0xd3,0x3f,0x53,0xa4,0x80,0x2b,0x1c,0xc0,0x99,0x63,0x52,0x93,0x5e,0xdc,0x78,0xe2,0x35,0x9e,0xb2,0xb4,0x1d,0x09,0xd1,0x5c,0x1c,0x4e,0xdb,0x3a,0x5d,0x8c,0x94,0x7d,0xfe,0x63,0xf2,0xa3,0xe9,0x61,0x73,0x78,0xc1,0xd9,0x17,0x5e,0x9a,0x73,0x58,0xc3,0xe7,0xa0,0x1f,0x2a,0x62,0x15,0xf8,0xdb,0xbb,0x38,0x80
+.byte 0x57,0xd3,0x1f,0x4c,0x4a,0x20,0x30,0xa9,0x7a,0x78,0x61,0xd9,0x90,0xb7,0x4f,0xd6,0x46,0x72,0xe7,0x41,0xb2,0xbb,0xfb,0x50,0xfe,0xe1,0xba,0x3e,0x73,0x2f,0x81,0x6d,0x2b,0x0b,0x90,0xbd,0x8a,0x3b,0x23,0x88,0xa2,0x7d,0x62,0x87,0x96,0xc9,0xcc,0x66,0x28,0x89,0xa7,0x29,0x41,0xd2,0xc5,0x5b,0xdb,0xc4,0x0c,0xbb,0x19,0x4e,0xd5,0x12
+.byte 0x53,0x48,0x5c,0xf2,0x9b,0x62,0xd0,0xa3,0x77,0x40,0x85,0x12,0x2b,0x2d,0x52,0x1b,0x31,0xbd,0xe9,0x1c,0xd4,0x87,0xa4,0xd7,0xc9,0x14,0xb7,0x39,0x66,0x8c,0xfe,0x3e,0x83,0x00,0x01,0xae,0x44,0x2d,0x7d,0xa1,0xda,0x66,0xb0,0x66,0xcb,0x62,0x55,0x9f,0x92,0x80,0x4e,0x8d,0x7f,0x70,0x95,0xc2,0xf2,0x1b,0xe9,0x35,0xf8,0x42,0x04,0x65
+.byte 0xf2,0x36,0x4c,0x96,0x30,0xd3,0x47,0x9d,0xb7,0x2b,0x76,0xac,0x75,0xb5,0xb8,0xf1,0x7d,0xa2,0x36,0xef,0x9d,0xa7,0x60,0x51,0x8d,0xcf,0x00,0x3d,0xdb,0xcc,0xe9,0xe2,0xc4,0x7b,0x3a,0xeb,0x2b,0xc3,0xd8,0x0b,0xb0,0x58,0x41,0xa0,0x47,0xab,0x07,0xf5,0x7c,0x9e,0x0b,0x7a,0x16,0x8f,0xb4,0xca,0x09,0xed,0x84,0xa1,0xfa,0xdc,0x7c,0x3c
+.byte 0xdd,0x2f,0xb0,0x2d,0xeb,0x93,0x28,0xf5,0x1e,0x0c,0x1a,0x0c,0x35,0x27,0x40,0xf2,0x22,0x66,0x2d,0x82,0xf2,0x94,0x03,0xa5,0x4b,0x84,0x92,0x1d,0x98,0xd5,0xd9,0x09,0x6a,0xfd,0x65,0xe5,0xa1,0x0e,0xe2,0xd9,0xb6,0xd1,0xba,0xbf,0xc7,0x42,0x22,0x39,0x83,0xbf,0x37,0xf6,0x80,0xc2,0xea,0xdf,0xb9,0x33,0xa0,0xaf,0xd7,0xe3,0x70,0x9a
+.byte 0x5c,0xf8,0x1a,0x47,0x2b,0xb5,0xdd,0x15,0xe3,0x08,0xc8,0x37,0xe3,0xc2,0x25,0x87,0x0e,0x3c,0xc5,0xae,0x61,0xa4,0x4a,0x56,0x50,0x08,0x58,0x68,0xa3,0x4a,0x28,0x08,0xef,0x92,0xd5,0x13,0x50,0x09,0x76,0x34,0x47,0xae,0xa8,0x7f,0xa5,0x2b,0x13,0xb7,0x5a,0x96,0x65,0x62,0xf2,0xaa,0xb4,0x4b,0x2a,0xad,0xea,0x2c,0x0d,0x1e,0x97,0x82
+.byte 0xe4,0x6f,0xfe,0xf4,0x88,0x14,0x7b,0xba,0x45,0xbe,0x61,0x56,0xd2,0x37,0x1b,0x65,0xb8,0x0b,0x77,0xcb,0x3c,0xfe,0x9f,0xe3,0x39,0xc5,0xfb,0x2a,0x18,0x9b,0x60,0x99,0xd5,0x6f,0x52,0xfe,0xd8,0x04,0x88,0x1c,0x9a,0x50,0xe5,0x3b,0x33,0x3f,0xca,0xc5,0x5b,0x9c,0x5f,0x35,0x13,0x65,0xa6,0x21,0x78,0x19,0xeb,0xff,0x35,0x70,0x81,0xaf
+.byte 0x19,0x23,0x61,0xd6,0xeb,0xff,0xa6,0x9e,0x5d,0x3f,0x7f,0x89,0x2e,0x22,0xa4,0x0b,0x9c,0x4f,0xa9,0xff,0xbb,0x23,0x29,0xa1,0xf4,0x8a,0xb7,0x4b,0xfb,0xbf,0xeb,0x0a,0x47,0x87,0x78,0x2b,0x20,0x38,0x82,0xab,0x7e,0x2c,0xdc,0x08,0x2b,0xb4,0xae,0xd8,0x64,0x44,0x1a,0xdf,0x21,0x62,0x27,0xf2,0x61,0x63,0x37,0xad,0xd4,0x06,0x4e,0xae
+.byte 0xba,0xeb,0x08,0xfa,0xe5,0xad,0x5d,0xcf,0xce,0x38,0xe5,0xca,0x74,0x83,0x42,0x4b,0xe8,0x8f,0xfb,0xff,0x83,0x4d,0x27,0x88,0x43,0x62,0xdd,0x80,0xa2,0x06,0x98,0x48,0x58,0x6f,0x54,0x16,0x6f,0xbf,0x81,0x36,0xc8,0xf3,0xea,0x4b,0xf7,0x5a,0x7b,0xb7,0xf4,0xa4,0x5e,0x22,0x52,0xe7,0x9e,0xb1,0xb6,0x7a,0xa8,0x22,0xee,0x68,0x82,0x8f
+.byte 0xe4,0xcb,0xad,0x71,0xef,0x53,0xf2,0x7d,0xed,0x91,0x9e,0xf6,0x90,0x9e,0x54,0x19,0x30,0xaf,0x4a,0x17,0xc0,0x6a,0x9c,0x49,0x12,0x8b,0x6f,0xc7,0x47,0x1e,0xa2,0x64,0x28,0x1f,0x0c,0xd3,0x3e,0x59,0x66,0x8c,0x2e,0x11,0x52,0x6c,0x69,0x66,0x10,0xfb,0x27,0xe6,0x1c,0xae,0x6f,0x44,0x87,0x86,0x0d,0x3e,0xd3,0xa0,0x80,0xef,0x30,0xb9
+.byte 0xb8,0xd7,0x47,0x84,0x68,0x2b,0xf2,0x32,0x7b,0x89,0x93,0xd2,0x83,0x56,0x35,0xc3,0xbf,0x5c,0x24,0xec,0xad,0x2d,0xa4,0x49,0x63,0x89,0xc6,0xf9,0x24,0x51,0x1c,0x9b,0xd1,0xcb,0x30,0x82,0xda,0xb3,0xa7,0xe1,0x4d,0x96,0xd0,0x44,0x44,0x1d,0x4e,0xd7,0x7d,0x7a,0x51,0x2e,0x2f,0xc4,0x9f,0xdb,0x06,0x53,0xfc,0x51,0x56,0xe5,0xb9,0x6b
+.byte 0x4a,0x2c,0x3e,0x62,0xc5,0x9c,0x42,0xe3,0xaf,0x3a,0x0f,0x0e,0x74,0x29,0x66,0x70,0x75,0x2a,0x06,0xd4,0x0f,0x0c,0xfd,0xea,0xcc,0x39,0xd0,0xa7,0x47,0x75,0x92,0x44,0x09,0xa2,0x3c,0x4e,0xad,0xaa,0xc4,0xc6,0xf9,0x35,0x82,0x23,0x25,0x43,0x94,0x26,0x14,0xde,0xf1,0xb9,0xb8,0xe0,0x75,0xe0,0x48,0x70,0x8a,0xc6,0x3c,0x72,0x98,0x72
+.byte 0x8b,0x15,0x58,0x17,0x73,0x29,0x67,0x21,0x56,0xc4,0x25,0x17,0x68,0xbe,0xd7,0x36,0x05,0x4b,0x58,0xa2,0x1b,0x64,0xe5,0x11,0x96,0x5a,0x3b,0xa6,0x90,0xb6,0x2d,0x7e,0x55,0xbb,0x31,0x93,0xe7,0xcc,0x2e,0x74,0xb6,0x9b,0x4d,0x04,0xc5,0x45,0x9b,0x0b,0x26,0xef,0x61,0x23,0x3d,0x7e,0xee,0x01,0x57,0xfa,0x77,0x12,0x47,0x64,0xac,0x8f
+.byte 0x25,0xbe,0x8e,0x2e,0x68,0x11,0x95,0xf0,0x1a,0xd2,0x3d,0x66,0xc1,0xdb,0x97,0x9e,0xbb,0xba,0xc1,0x66,0xa4,0xb5,0x71,0x01,0xee,0xf5,0xbb,0x1e,0x9f,0x41,0xfc,0x40,0x74,0x26,0xf7,0xc6,0x2c,0x9c,0x1c,0x59,0xce,0xcf,0x18,0x17,0x81,0x5d,0xd4,0xe3,0xd8,0x46,0x62,0x9e,0x97,0xb1,0xca,0xac,0x01,0x3e,0xf8,0x96,0xa2,0xee,0xe0,0xf8
+.byte 0xf3,0x2d,0xe9,0xd2,0x1f,0x9f,0x41,0xbb,0x2f,0xe5,0x64,0x6d,0x5b,0xe7,0x47,0x0e,0x83,0x7b,0x08,0x5e,0x29,0x35,0x2f,0x75,0x31,0x44,0x4c,0xb7,0x61,0xa4,0x03,0x2e,0x15,0x94,0x7a,0xa0,0x46,0x31,0x7b,0x43,0xd9,0x14,0xa3,0x34,0x0c,0x83,0x93,0x75,0x8e,0x3a,0x1c,0xc3,0xe1,0x36,0x18,0x96,0x7a,0xfb,0x77,0xad,0xbb,0xe9,0x0d,0x4b
+.byte 0x21,0x04,0x2e,0xdd,0x7a,0x63,0xc9,0x60,0xb1,0x9b,0xad,0xde,0x1f,0x65,0x8a,0x58,0x18,0x84,0x95,0xa9,0xac,0x3a,0xac,0xcb,0xb7,0xa9,0xeb,0x0c,0x7c,0x3a,0x98,0x9a,0x3f,0x56,0x23,0x51,0x58,0x59,0x4e,0xf5,0x57,0x60,0xe6,0x9d,0xf8,0xf7,0xed,0x9d,0x81,0x14,0x68,0xbe,0xaf,0x19,0xe5,0xb5,0x9b,0x5f,0xe4,0x51,0x44,0x4b,0x23,0x42
+.byte 0xdd,0x92,0x1a,0xe5,0x7e,0xef,0x77,0xbe,0x88,0x77,0x1e,0x8a,0xbd,0x2a,0x77,0xb1,0x0d,0x1b,0xe3,0x8a,0x7f,0x15,0x71,0x93,0xc9,0x5f,0x78,0x2d,0x77,0x9b,0x0c,0xad,0x76,0x3c,0x6b,0xe2,0x15,0x8e,0xe1,0x5e,0x1d,0x90,0xa5,0xd6,0xc7,0x55,0x5d,0x52,0xf7,0xcc,0x82,0x9b,0xdc,0x1d,0x80,0xa4,0xc7,0xbe,0x7c,0x4f,0xda,0x81,0x91,0x78
+.byte 0x88,0x0e,0x31,0xde,0x87,0x4c,0xdc,0x84,0x9a,0x65,0x89,0xfa,0x22,0x3e,0xde,0x3b,0x7f,0x7f,0x9b,0x3f,0x3e,0xda,0x13,0x31,0x59,0x7b,0x08,0x48,0x39,0x37,0xfd,0x1a,0x4f,0xa3,0x12,0xba,0xe5,0xd6,0xfa,0xa3,0x59,0x0b,0x3b,0x7d,0xde,0xc0,0x51,0xce,0x92,0x6b,0x3d,0x4b,0xd2,0xa4,0x68,0xc2,0x32,0x2d,0x01,0xbd,0x66,0x98,0x8f,0xa0
+.byte 0x86,0xfb,0x08,0x36,0xa9,0xd4,0x3b,0x7b,0x01,0x2d,0xaa,0x8c,0x64,0x19,0xa6,0x62,0x24,0x92,0x5e,0xc5,0x02,0x17,0x8e,0xf0,0x88,0xe9,0xd1,0x8b,0x69,0xda,0xed,0x9c,0x60,0x32,0xab,0xc0,0xbc,0x84,0x64,0x6e,0x32,0xb2,0xcd,0x24,0xf6,0xb2,0x9d,0xf5,0xf5,0x71,0xe2,0x01,0xbc,0x77,0x6a,0x5b,0x26,0x56,0xf7,0x04,0x84,0xff,0x7c,0xa4
+.byte 0xe8,0xa8,0x82,0x6c,0x40,0x24,0x93,0x3c,0x6e,0x7d,0x0d,0x22,0xd0,0xe4,0xef,0xc4,0x4e,0x26,0x66,0x61,0x75,0xe9,0x06,0x69,0x06,0xfd,0x97,0x68,0x96,0x67,0xec,0x96,0x09,0x73,0xe4,0x0a,0x3e,0xaa,0xb8,0x25,0x77,0x00,0x91,0x7a,0x2e,0xc8,0x81,0x75,0x78,0xb7,0xa5,0x27,0x55,0xf2,0xcf,0x9a,0xab,0xab,0x51,0x0a,0x65,0x47,0xbf,0x10
+.byte 0xd2,0x19,0x78,0x6b,0x35,0xf4,0xef,0x12,0x2b,0x5f,0x0c,0x28,0x7c,0xe8,0x64,0x55,0x2f,0x26,0x85,0x91,0x7a,0x9d,0x48,0x76,0x12,0x14,0x2d,0x4a,0x8a,0xd6,0xfa,0x7b,0xf9,0xc7,0x24,0x45,0xf6,0xbd,0x47,0xab,0xc6,0x4b,0x9e,0x39,0x77,0x57,0x04,0xa8,0x4d,0x43,0x99,0x5c,0xb1,0x3d,0xc2,0x4e,0xc5,0x17,0x66,0xc4,0xb6,0xdd,0x92,0x80
+.byte 0x85,0x3b,0x07,0x63,0x16,0x5f,0x67,0x76,0x9b,0xb5,0x8e,0xca,0x97,0xbb,0xf4,0x20,0xd0,0x4d,0x7b,0xd0,0xa3,0x74,0x6f,0x8a,0x68,0xc7,0x31,0x78,0x1b,0x72,0x45,0xa4,0xc4,0xf8,0xf8,0x26,0xa8,0x4d,0x08,0x2f,0x7b,0x3d,0xa0,0x2a,0xb5,0x65,0x27,0xc2,0x36,0x13,0x2d,0x8d,0x83,0xeb,0xf4,0x08,0x26,0x41,0x8b,0x32,0xf3,0x09,0x70,0x70
+.byte 0x5d,0x8a,0xcc,0xb8,0xe9,0xf7,0x08,0xdf,0x5f,0x4a,0xb8,0x8a,0xb7,0x1b,0xad,0xe2,0xc3,0x39,0x59,0xe0,0x7f,0xd0,0x66,0x7b,0x99,0x5a,0xde,0x52,0xe2,0x1f,0x47,0xc2,0x63,0x74,0x7a,0xa5,0x88,0xc3,0x24,0x70,0x4a,0x7d,0xdd,0xa4,0xe6,0xf8,0xfd,0x5c,0xfa,0x8c,0x4c,0x0f,0x52,0x95,0xf3,0x2c,0x76,0x47,0x7a,0xe8,0xdb,0xe0,0x9b,0x49
+.byte 0x88,0x5b,0x87,0x5a,0xd1,0x07,0x24,0x06,0x83,0x3b,0x25,0x23,0xe7,0xaa,0x79,0xef,0x74,0x02,0x12,0xfe,0x47,0x5c,0x77,0x73,0xf7,0x2e,0x4b,0x58,0x3b,0x60,0x7b,0x91,0x2f,0x0d,0xb4,0x6d,0x00,0x80,0x19,0xaa,0x88,0xbc,0xb2,0x7b,0xd9,0xb7,0xdd,0x32,0x47,0x62,0xf5,0x0f,0x46,0x95,0x4c,0x6c,0x01,0x67,0xfb,0xe4,0x2b,0xac,0x95,0x84
+.byte 0x25,0x0a,0xe5,0x4c,0x2d,0x4a,0x6e,0x77,0xfd,0xeb,0xe1,0x53,0xc9,0x2e,0x70,0x01,0x32,0x05,0x6d,0xc5,0xc9,0x5d,0x90,0xca,0x56,0xd1,0xd8,0x40,0x2a,0x51,0x4d,0x95,0xc3,0x57,0x8b,0xdd,0x62,0x9c,0x69,0xd1,0x03,0x89,0x95,0x38,0x2c,0xc1,0x6d,0x41,0xf2,0xc3,0xa2,0x9c,0x43,0xea,0xf1,0x02,0x00,0x56,0x46,0xbb,0x87,0x35,0x40,0x0e
+.byte 0x18,0x51,0x29,0x39,0xbb,0x6d,0x15,0xf2,0xcd,0x54,0x23,0x95,0x69,0xdc,0x0a,0xb2,0x26,0xd9,0x25,0xe1,0xf1,0x07,0x7b,0x5e,0xc3,0x30,0x68,0x5f,0x2a,0xce,0x91,0x92,0x03,0x0c,0x62,0x11,0x43,0x80,0xe5,0x12,0xec,0xe3,0x4f,0x90,0xfe,0x38,0x6e,0xe9,0x7e,0x94,0x83,0x26,0x59,0x3f,0x3f,0x81,0xc6,0x94,0x98,0x09,0x80,0xff,0x01,0x44
+.byte 0xff,0x77,0x6a,0x4c,0x76,0x91,0xd9,0x12,0x59,0x9a,0x00,0x7c,0x87,0x06,0x17,0xf7,0x12,0xc7,0xee,0x04,0xd5,0x8d,0x68,0xc5,0x8d,0x80,0x10,0xcc,0x14,0x45,0xe8,0xd7,0x43,0x10,0x01,0x9e,0x61,0xc2,0xc0,0x66,0xfe,0xcf,0x5f,0x9f,0xcb,0xa3,0xf8,0xc7,0x07,0x41,0xe3,0xf2,0xda,0x6e,0x01,0x76,0xc6,0x49,0x49,0x01,0xc7,0xcf,0x6a,0x20
+.byte 0x71,0xc5,0xf0,0xb1,0xa0,0xc9,0xed,0xec,0x66,0x71,0x93,0xf5,0xc0,0x27,0x42,0xed,0xd5,0x6f,0x20,0xe1,0x86,0x3e,0xd0,0x5d,0x94,0x17,0x43,0xb4,0x98,0x0d,0x8a,0x31,0x6c,0x59,0xa9,0x0b,0xb3,0xa4,0x0b,0x46,0x0b,0xa8,0x79,0x62,0x3a,0x3d,0xbf,0xef,0x94,0xd3,0x31,0xf2,0xa1,0x55,0xe8,0x92,0x44,0x37,0x62,0x82,0x1b,0x60,0x87,0x67
+.byte 0x85,0x78,0xd5,0x84,0x73,0xa4,0xea,0x56,0x08,0x78,0x68,0x7f,0xfb,0x15,0x20,0x64,0xeb,0x6c,0xf7,0x5e,0xc0,0x79,0x83,0x59,0x7b,0xed,0x2d,0xa9,0x37,0x46,0xf3,0x62,0xb1,0xa1,0x2b,0x48,0x58,0xd9,0x0c,0x03,0xf7,0xf3,0x47,0xeb,0xd7,0x03,0x9b,0x85,0xd3,0xd7,0xd7,0x7e,0xfb,0x1a,0x25,0x83,0xda,0x06,0xa0,0x04,0x0d,0x6b,0x90,0x29
+.byte 0x2a,0xfc,0xcd,0x96,0xe9,0x17,0x4f,0xdd,0x2c,0x90,0xdf,0xf1,0xe3,0x08,0x0a,0xb8,0x0c,0x59,0x2a,0x83,0x62,0x94,0x00,0xd3,0x80,0x1a,0x31,0xd7,0x17,0x70,0xc7,0xa2,0x20,0x17,0x65,0x88,0xae,0x11,0x25,0xc9,0xba,0x76,0xa7,0x61,0x60,0xd1,0x59,0x50,0x22,0xdd,0xaa,0xcf,0x9d,0xc1,0x36,0x7d,0xf9,0x7b,0x69,0xc0,0x98,0xba,0x40,0xd5
+.byte 0xd6,0x46,0x93,0x92,0x7d,0x37,0x3f,0x3a,0x04,0x9a,0x84,0xaf,0x8e,0x61,0x04,0x26,0x54,0x33,0x84,0xc0,0xac,0x21,0x51,0xd7,0x9a,0x93,0x6e,0xf2,0x09,0x87,0xc5,0x35,0xa8,0x96,0xb0,0x64,0x90,0x35,0x52,0xed,0x0e,0xbc,0xdb,0xa6,0x06,0x3e,0xe7,0xea,0x57,0x4b,0xd7,0xc5,0x1c,0x76,0x3d,0x0d,0xc3,0x1f,0x8e,0x4f,0x12,0xdb,0x3a,0x21
+.byte 0x2a,0x69,0xc2,0x94,0xda,0x4c,0x91,0xcc,0xa8,0x36,0x89,0xd7,0x78,0xa8,0x74,0x79,0x63,0x92,0xeb,0x39,0x3b,0x84,0x8c,0xe5,0xc6,0x26,0xf0,0xef,0xcc,0xc1,0x72,0x4b,0x8e,0xcd,0xe4,0xd9,0x00,0x80,0xbc,0xdf,0xe2,0x61,0x53,0x04,0x81,0xb0,0x13,0xc5,0x6c,0x77,0x74,0xa3,0x0c,0x5b,0xef,0xef,0xea,0xc7,0x5b,0xeb,0xbf,0xee,0x54,0xd7
+.byte 0x7a,0x69,0x6e,0x39,0xc2,0xed,0x08,0x44,0x82,0x08,0x16,0x8b,0xf1,0x74,0x5f,0xeb,0x60,0xd5,0x46,0x63,0x80,0x39,0xe9,0x91,0x0a,0x17,0x8b,0xd4,0x09,0xdc,0xa6,0xab,0x6a,0xbc,0xf8,0xe9,0x09,0x19,0xc1,0x83,0x9f,0xdf,0xad,0x6c,0x31,0x94,0xb9,0xc5,0x77,0x83,0xd1,0xd8,0x76,0xeb,0x12,0x3c,0x00,0x31,0xea,0xac,0x97,0x39,0x16,0xd5
+.byte 0x81,0xfa,0x6d,0x10,0x5b,0x3e,0x20,0xe1,0x88,0x5c,0x4b,0xf3,0x04,0xd4,0xc3,0xb9,0xec,0xe5,0xb0,0x13,0xf5,0x09,0x5c,0xe8,0x27,0xe2,0xde,0x9b,0xac,0x2e,0xf2,0xe5,0x2c,0x33,0x4b,0x4f,0xec,0xc7,0x08,0xf9,0xc2,0xd3,0x1b,0x4d,0x81,0x69,0x14,0xa1,0xc5,0x0f,0xb2,0x57,0x8b,0xcc,0xca,0x3b,0xc9,0x9c,0x1f,0xee,0x06,0x4d,0xc7,0x62
+.byte 0xcb,0x8f,0x49,0x81,0xfb,0xa5,0x68,0x81,0x36,0x38,0x33,0x6b,0x9e,0x58,0xd4,0x24,0x67,0xf1,0x30,0xd6,0x08,0x61,0x5a,0x7f,0x2e,0x4e,0xf1,0xd6,0x64,0x75,0x72,0xb0,0xdf,0xcd,0xae,0x04,0x41,0xbd,0x04,0x2c,0x96,0x36,0x34,0x32,0xec,0xbd,0xd0,0xbf,0x8e,0xe8,0x47,0xe3,0x22,0xdd,0x79,0x53,0xcc,0x6a,0x25,0xf1,0x5e,0x63,0x09,0x98
+.byte 0xc5,0x6d,0x0a,0xe3,0x30,0xd6,0x52,0x70,0x21,0xb2,0xef,0x15,0x66,0x4a,0x2d,0x2b,0x5c,0xcb,0x39,0x1b,0x91,0x10,0xa6,0x02,0x22,0xd0,0xcc,0x32,0x50,0x5c,0x70,0x72,0xd1,0x03,0xb3,0x2d,0x2e,0x33,0xed,0xae,0x7a,0x07,0x3f,0x70,0x38,0x35,0xfc,0xcf,0xdb,0xfe,0x7b,0x26,0xd9,0x38,0x1e,0x52,0x07,0x2f,0x72,0x81,0xcc,0xd3,0x21,0x00
+.byte 0x63,0x48,0x38,0x44,0xb8,0x35,0xf2,0x4f,0xe5,0x33,0x8c,0xb3,0x07,0x0c,0xac,0x3d,0x73,0xe8,0xe3,0xb3,0x43,0xc5,0xb4,0x32,0xf4,0x41,0xdf,0x7b,0x06,0x3a,0xb8,0x67,0x17,0xc5,0xec,0x46,0x30,0xc0,0xa4,0x29,0x40,0xe4,0x8a,0xa3,0x14,0x84,0xa6,0x84,0xc7,0x5d,0x4b,0x57,0x37,0x9c,0x42,0xe6,0xa4,0x20,0xf7,0x5d,0xef,0x21,0xe2,0x80
+.byte 0x54,0x6d,0xf5,0xb5,0xbe,0xa3,0x95,0xcf,0x98,0xf8,0x38,0x46,0xa2,0x90,0x57,0x09,0x8f,0xb0,0x6d,0x01,0x5f,0x95,0x5a,0x78,0xf6,0xfd,0x01,0x0f,0xfd,0xa5,0xe2,0xcf,0x54,0xa3,0x2b,0xc1,0x30,0xbe,0x6d,0x1a,0xd3,0xdb,0x5a,0x17,0x43,0x46,0x93,0x81,0x0c,0x85,0x04,0x13,0xda,0xb4,0xde,0x81,0x48,0x5c,0xbc,0x42,0x9e,0x6d,0x6c,0x82
+.byte 0xff,0xa5,0x51,0xb1,0xd3,0xd2,0x3d,0x82,0x82,0xb4,0x96,0xb1,0x38,0x5d,0xc9,0x55,0xcb,0x9f,0xe5,0x47,0xd4,0x52,0x0f,0x76,0x54,0xec,0x39,0xb6,0x40,0xc3,0xc5,0xaa,0xc2,0x30,0x02,0xa0,0x68,0xc3,0x22,0x63,0x5a,0x8c,0x62,0x6d,0x40,0xc5,0xde,0x06,0x29,0x44,0x5d,0x2b,0x18,0x0a,0xa5,0x43,0x47,0xfe,0x5f,0x0f,0x63,0xa4,0x3c,0xa1
+.byte 0x62,0xcb,0x70,0x1d,0xf8,0x0e,0xc9,0xbe,0x27,0x0e,0x87,0x81,0x69,0x4c,0xea,0xbe,0xf9,0x9b,0xda,0xb6,0x9b,0xd0,0xdd,0xa0,0x1e,0x60,0x38,0x88,0x85,0x25,0x53,0xee,0x2c,0x77,0x53,0x82,0xb0,0x88,0x19,0x87,0x2a,0x77,0x7b,0x37,0x4b,0x4c,0xf4,0x96,0x5f,0x73,0xa1,0xbb,0x5c,0xfc,0x7e,0xbb,0xed,0x6f,0xb7,0x6f,0x9d,0x55,0xde,0xd3
+.byte 0xac,0xb9,0x8e,0x36,0x0f,0x3d,0xea,0x87,0xcd,0x19,0x33,0x1d,0xa8,0xee,0xfc,0xcd,0xe5,0x53,0x7b,0xdf,0x37,0x49,0x2d,0x73,0xf5,0x36,0xdd,0x42,0xc6,0x88,0x0d,0xf5,0xf2,0xba,0x2e,0x81,0xed,0x88,0x27,0x8d,0xe5,0x3f,0x83,0x5e,0xde,0x63,0x8f,0x67,0x2b,0x85,0xf3,0x2a,0x9b,0x26,0x3e,0x2b,0xe2,0x29,0xc5,0x5e,0x21,0x04,0xfe,0x5b
+.byte 0xb9,0xd8,0xa7,0x7b,0xdf,0xcf,0x61,0xd6,0xaf,0x9b,0x17,0xcb,0xaf,0x8f,0x71,0xb3,0xc2,0x9d,0x9a,0x55,0x1d,0x3e,0x1d,0x17,0x25,0xc8,0x44,0x71,0x29,0x2f,0xc8,0x01,0x3b,0xe4,0xc4,0x2e,0xcc,0x3b,0xdb,0x34,0xbb,0xc0,0xcc,0xb6,0x07,0xe3,0x86,0x4c,0x62,0x02,0xe8,0xc3,0x11,0x85,0x6c,0x18,0x80,0xa3,0xbd,0x02,0x30,0x68,0x36,0xa3
+.byte 0xb6,0xc6,0xbd,0x82,0x43,0x40,0xed,0xa1,0xcf,0xc5,0xce,0xe4,0x27,0x8a,0xeb,0x8c,0x59,0xea,0x4a,0x81,0xd9,0x35,0x87,0x7d,0x6d,0xb2,0x8f,0x67,0x37,0x1f,0x11,0x60,0x0d,0xed,0x34,0xd5,0xa0,0x7b,0x46,0x71,0x68,0x19,0x69,0xd3,0x65,0x1d,0x47,0xf1,0x7e,0x16,0xd8,0xec,0xbb,0x52,0xc3,0x7b,0x62,0x5a,0xb3,0x60,0x67,0x2e,0xfd,0x57
+.byte 0xf2,0xfb,0x3d,0x63,0xe6,0x82,0x20,0xff,0x31,0x90,0x1d,0x5e,0x4f,0x04,0x9a,0xf8,0xb2,0x0c,0x84,0xff,0x7d,0xe2,0xec,0x4b,0x09,0xbb,0xdf,0xae,0xc5,0xaf,0xcb,0x8b,0xb5,0x5d,0xa8,0x53,0x78,0xf9,0xb9,0x43,0x71,0xa6,0xc2,0x10,0xfa,0xad,0xda,0xba,0x46,0x13,0x72,0x97,0xef,0x6f,0xe3,0x4f,0x5f,0xf9,0xec,0x25,0xdb,0xcd,0xca,0x33
+.byte 0x7e,0x50,0x73,0x5b,0xd0,0x9f,0xea,0xd5,0xd9,0x29,0xe8,0x1b,0xc1,0xf8,0x40,0xbf,0x50,0xdb,0x8e,0x39,0x0b,0xb7,0x6c,0xf1,0x34,0x0b,0x1f,0x88,0x27,0x4b,0xea,0x1d,0xb2,0x36,0x07,0x4b,0x22,0xa9,0xd0,0xf8,0xf2,0x13,0x8e,0x97,0x9d,0xd9,0x53,0xd3,0xdc,0x63,0x40,0x11,0xc7,0x74,0x9e,0xd9,0x83,0x01,0xae,0x36,0xcb,0x35,0x9a,0x0c
+.byte 0xb5,0x15,0x0a,0xf5,0x41,0xa5,0x6c,0x72,0x40,0x80,0xf0,0x15,0xc0,0x80,0x23,0x0b,0xab,0x98,0xfc,0xab,0x81,0xe0,0x8b,0x61,0x91,0x18,0xd2,0x23,0x71,0xed,0x32,0x80,0x26,0x86,0x96,0xe9,0x90,0x5e,0x43,0xd2,0x89,0x8f,0x89,0x57,0x73,0xca,0xe1,0x42,0xa9,0xa9,0xed,0xdd,0xc5,0x9f,0xf7,0x00,0x0d,0xa3,0xe5,0xc8,0x6f,0x0c,0x14,0xa4
+.byte 0x9d,0x5a,0x14,0xaf,0x96,0x3a,0xb2,0x64,0xa7,0xac,0x20,0xa9,0x01,0x4c,0xec,0x64,0xc6,0x9b,0xfd,0x04,0xc5,0x2e,0xe7,0xdd,0xa5,0x8e,0xe7,0xe7,0x76,0x53,0x59,0x95,0x14,0x07,0xed,0xe9,0x96,0xd0,0x2d,0xc8,0x9d,0xa2,0x11,0xe3,0x02,0x20,0x68,0x09,0x25,0x69,0x07,0x88,0xdb,0x26,0x36,0xf5,0x8e,0xc3,0xf0,0x70,0x8c,0xeb,0xe6,0xcd
+.byte 0xad,0xf3,0x49,0x6e,0x8a,0x54,0xa6,0xdd,0x97,0x8e,0x37,0x28,0x3a,0x6d,0xc4,0xdd,0x99,0x85,0xf7,0x96,0x63,0xb4,0xa2,0xdf,0xff,0x81,0x17,0xa1,0x22,0xb1,0x43,0x5b,0x29,0xdb,0x92,0x91,0xc9,0xc6,0x8d,0x29,0x1d,0x6e,0xe3,0x44,0x3e,0xe4,0x20,0xd5,0xf4,0x4a,0xfa,0xae,0xf6,0x2c,0xff,0x80,0xc9,0xce,0x7f,0x13,0x1e,0xd7,0x24,0xa2
+.byte 0xb3,0x90,0xb8,0x20,0x18,0xe5,0x6c,0x0e,0xf5,0xc6,0x26,0xd6,0xe9,0xe8,0x55,0xe4,0x3f,0x49,0x13,0xe2,0xca,0xef,0x9b,0xc0,0x8f,0x24,0x50,0x37,0xef,0x21,0xff,0x79,0xb7,0x5d,0x86,0x03,0xfb,0x85,0x75,0x74,0xbf,0xc5,0x3a,0x30,0xcc,0x00,0xc3,0x0d,0x4f,0x91,0xd6,0x31,0x19,0xd6,0xcd,0x0e,0x1c,0x53,0x88,0x75,0xb8,0xf9,0x68,0x7a
+.byte 0xa4,0x3e,0x8d,0xed,0xba,0x05,0xb4,0x6c,0xe0,0x45,0x9c,0x41,0x34,0x24,0x82,0xaf,0x9a,0xcf,0x9e,0xd2,0x27,0x5c,0x7f,0xb3,0xcb,0xe5,0xad,0xb4,0x8e,0x74,0x9d,0xe4,0xba,0x55,0xb3,0xd3,0x32,0xbc,0x62,0x11,0xb3,0xa4,0x82,0xf0,0xd8,0xfc,0x79,0x03,0x70,0xae,0x7f,0x7f,0xc8,0x50,0xb5,0xbe,0x47,0x14,0x31,0xd7,0x16,0x65,0x52,0x3b
+.byte 0xbb,0x42,0x38,0x23,0x77,0x4d,0x38,0x0b,0x0a,0x61,0x94,0xac,0xa3,0xc9,0xd7,0x99,0x4f,0x34,0x3a,0x88,0xe8,0x1d,0x0b,0x97,0x48,0x6d,0x5c,0x61,0x4c,0x3f,0xc2,0x7c,0x6c,0x63,0x00,0xdd,0x59,0xae,0xcd,0x17,0x0a,0x21,0x27,0x98,0x15,0x23,0x6d,0x84,0x7e,0x24,0xd4,0x7f,0x1b,0x3a,0x98,0x52,0xc3,0x60,0x33,0xd6,0xc1,0xfe,0x68,0xa8
+.byte 0x49,0x3d,0x7e,0x53,0xee,0x0d,0xed,0x89,0x9a,0x9a,0xe6,0xa1,0x47,0xc7,0xba,0xf3,0x73,0x5b,0xef,0x33,0x51,0x8c,0x1f,0x84,0xa6,0xef,0x77,0x94,0x2d,0xd6,0xda,0x8f,0x85,0x8c,0xd3,0xb6,0x02,0x68,0x9e,0x57,0xb6,0xd9,0x1a,0x8c,0xb5,0xf4,0x61,0x39,0x29,0xb5,0xb7,0x0d,0x0d,0xa6,0x81,0x87,0x54,0xc0,0xca,0x67,0x09,0xca,0x20,0xf3
+.byte 0x37,0x7e,0x03,0x3e,0x31,0x8c,0x51,0x89,0x06,0x81,0xf6,0x7b,0x8b,0xe3,0x4f,0xd0,0xb8,0x0c,0x34,0x7c,0xd6,0xfc,0x25,0xf8,0x00,0xa6,0x10,0x15,0x0d,0xeb,0x22,0x72,0x03,0x79,0x1c,0x84,0x1d,0x3d,0x10,0xaf,0x43,0x6d,0xd7,0xed,0x10,0x2c,0x14,0x26,0xd4,0xa1,0xee,0x6c,0x7f,0x52,0xe4,0x83,0xcc,0x5f,0x1a,0x4b,0xd0,0xc8,0xfb,0x27
+.byte 0x17,0x2c,0xf6,0x90,0x02,0xb4,0xb0,0x63,0x7c,0x14,0xec,0x9e,0x08,0x60,0xec,0x45,0x85,0xc6,0x76,0x42,0x4f,0x1c,0x5f,0x48,0x7f,0x87,0xef,0x8c,0x04,0x23,0x3c,0xda,0x39,0xbc,0xec,0x09,0xda,0xeb,0x9b,0x72,0x7a,0xb4,0x20,0x1c,0xb2,0xdd,0x2e,0x63,0x72,0xd7,0xb1,0xfe,0x5b,0x21,0x28,0xfb,0xeb,0x45,0x31,0x89,0xe5,0x3e,0xa0,0x85
+.byte 0xa6,0x96,0xdb,0x42,0xd5,0xb4,0x27,0x78,0x10,0xa0,0xcb,0x69,0x68,0x1e,0x76,0xed,0xbc,0x3c,0xa1,0x04,0x10,0x81,0x2a,0x4f,0x52,0x78,0x1e,0xae,0x5a,0x47,0x69,0x81,0xee,0xd3,0x14,0x1a,0x68,0x19,0x75,0x92,0x72,0x47,0x61,0x70,0xcf,0x96,0x35,0xa6,0xbb,0x00,0xaf,0x3e,0x90,0x86,0x22,0x9b,0x72,0x8a,0xa1,0x05,0xe2,0xfb,0xdc,0x30
+.byte 0xd5,0xdd,0x46,0x1f,0xf6,0x33,0x43,0xd1,0x59,0xc4,0x93,0x89,0x36,0x6a,0x7b,0x76,0xa7,0x40,0x6c,0xb1,0x9c,0xce,0x3a,0x8c,0xb6,0xd5,0xd1,0x0a,0x78,0xf6,0x08,0xfb,0xf5,0x9c,0xee,0x74,0x0d,0x39,0x51,0x6d,0x0e,0xa6,0xe9,0x22,0xd8,0x30,0xdf,0x16,0xf7,0xe3,0xbd,0xbb,0xe6,0x45,0xb8,0x9c,0xb5,0x49,0xf0,0xe8,0x7c,0xce,0x25,0xf8
+.byte 0x46,0xc0,0x59,0xc2,0xbc,0xdd,0xea,0x3e,0xeb,0x2e,0xf5,0xfd,0xd9,0x05,0x8a,0x2f,0xa3,0xa4,0x63,0xa6,0x50,0x08,0xce,0x2a,0x69,0xe7,0x58,0x57,0xa1,0xb2,0x44,0x41,0x04,0xfc,0x61,0xb1,0xb8,0x19,0x27,0x14,0x71,0x2f,0x55,0x64,0x28,0xa0,0xcc,0x47,0x0c,0xd4,0xed,0xfd,0x07,0x99,0xc6,0x9e,0xdc,0x5f,0x19,0x03,0x1a,0x00,0xda,0xf6
+.byte 0x2c,0x95,0xb0,0xd2,0xaa,0xfb,0xbc,0x1a,0xf3,0x62,0xaf,0x9c,0x38,0xde,0x61,0x30,0xd5,0x56,0x82,0x4b,0xf6,0xeb,0x34,0xc0,0xdc,0x51,0x97,0x89,0x80,0x47,0x9d,0x2a,0xae,0x0e,0x92,0x48,0xd2,0x9d,0x5a,0x67,0xef,0x33,0xa3,0xbe,0xdd,0x80,0x64,0x9c,0xc1,0xaf,0xf9,0x1a,0x4b,0x55,0x67,0x88,0x37,0x37,0xff,0x98,0xe3,0x9e,0xa9,0x4e
+.byte 0x1f,0xa1,0x32,0x70,0xa3,0xbb,0xdc,0x6e,0xb3,0x6d,0xfe,0x8f,0x74,0x89,0xed,0xe1,0x13,0x3c,0x8f,0x08,0x75,0x84,0x84,0xee,0xac,0xcc,0xa5,0x47,0x9f,0x3e,0xb9,0xed,0x26,0x20,0xf7,0x7b,0xfb,0x8a,0x48,0x58,0x51,0x24,0xf9,0xeb,0x66,0x6d,0xd6,0x83,0x24,0xff,0x9f,0x0d,0x38,0x9c,0xf9,0x24,0x99,0x12,0x49,0xb6,0xdd,0xce,0x44,0xe7
+.byte 0x31,0x3d,0x4b,0x23,0x8a,0xd5,0x62,0xa2,0xdb,0x78,0x56,0x3a,0x62,0xc8,0x59,0x5f,0xcc,0x58,0x76,0x19,0x5d,0x48,0x4a,0xc2,0x87,0x21,0xc3,0x3d,0x3a,0x38,0xbd,0x20,0xfd,0xc3,0xa6,0xab,0x32,0xb8,0xc8,0xd1,0x5c,0xa5,0xb4,0x64,0x60,0xd2,0x87,0xb7,0xe9,0xc2,0x2b,0xb2,0x75,0x04,0xf4,0x6e,0x96,0x99,0x5d,0x08,0xff,0xa3,0x45,0x8a
+.byte 0xad,0x7c,0xee,0x94,0x4e,0x45,0x86,0xad,0x0a,0x7a,0x5c,0x8f,0xff,0x28,0xb3,0x3c,0xf8,0x5e,0xb3,0x1e,0x5c,0xe0,0x22,0xf7,0x4e,0xe4,0xdf,0x1f,0xd2,0xa2,0x37,0x4a,0x87,0xa6,0x16,0x80,0x0c,0xc3,0x75,0x18,0xe4,0x76,0x8f,0xc3,0x1b,0xee,0xb1,0xe4,0x4b,0xeb,0x6f,0x15,0x48,0x60,0xaf,0x8e,0x0e,0xeb,0xbe,0x26,0xa3,0xbd,0x2a,0xb5
+.byte 0x6d,0x8b,0xd1,0xa1,0x0f,0x8e,0xaa,0xaa,0xb8,0x8d,0x84,0xe7,0x65,0x40,0x60,0x3d,0x59,0xb7,0x1c,0xef,0x08,0x0e,0x6f,0x21,0xb4,0xe6,0x10,0xda,0x59,0x9a,0x0f,0xe6,0xba,0xfd,0xed,0x7f,0xc1,0xe3,0x7a,0xb7,0x21,0x5d,0xcf,0x1c,0xbd,0xd2,0x59,0xc0,0x31,0xa5,0x8a,0x39,0x86,0x9e,0x7e,0x6a,0xcb,0x87,0x6f,0x01,0xba,0xa4,0x06,0x6b
+.byte 0x3b,0x5d,0x68,0x85,0x11,0xd2,0x2a,0x3c,0x8e,0x3a,0x8c,0x8b,0x59,0xa0,0x4a,0xfb,0x76,0x85,0xe6,0x47,0xc3,0xf4,0xc4,0xe6,0xcc,0x7b,0xff,0x71,0x03,0xd1,0xc2,0x01,0xe4,0x5e,0x49,0x31,0xa6,0x0e,0x17,0x9b,0x42,0xdc,0x75,0xd6,0xfe,0x09,0x0b,0x6d,0x21,0x46,0xfe,0x40,0xcd,0x7c,0xdb,0xca,0xc9,0xba,0x64,0x83,0xd3,0xf7,0x0b,0xad
+.byte 0xff,0xfd,0xe3,0xd9,0x49,0x7f,0x5d,0x48,0xaa,0xac,0xe5,0x74,0x2a,0x14,0x6f,0x64,0x21,0x81,0x09,0xcd,0x2d,0x19,0xf5,0x56,0x85,0xa8,0xec,0x98,0x65,0x46,0x99,0xec,0xbe,0xe3,0x86,0xd3,0x41,0x8b,0xe4,0x76,0x9b,0x5b,0x98,0x33,0x9e,0xdb,0xc9,0xde,0x89,0xfa,0x60,0x58,0xa8,0x2f,0x7a,0xca,0x30,0x91,0xc8,0x26,0x14,0x9c,0xd6,0x6d
+.byte 0xc2,0x3c,0xca,0xe0,0x9a,0x13,0x72,0x63,0x5e,0x20,0xfd,0xa0,0xca,0xb2,0xed,0x37,0xc5,0xd4,0x4e,0xec,0x1f,0x74,0x25,0x37,0xe2,0xbe,0xb1,0x7f,0x52,0x26,0x28,0x4f,0x02,0xe5,0x6a,0x27,0xf3,0xc4,0x9c,0x69,0x09,0xac,0xff,0x77,0x9c,0xa4,0x1d,0xe7,0xa1,0x7c,0x37,0x70,0x3b,0x3c,0xc4,0x16,0x8f,0x5d,0xe5,0x05,0xa9,0x2c,0x91,0x2e
+.byte 0x87,0xb0,0xa9,0x2e,0x32,0x73,0x5c,0x15,0x1e,0xbe,0x01,0xc9,0xd8,0x2e,0x26,0xf4,0x05,0x2d,0xe0,0xc0,0x38,0x81,0x61,0xf4,0x37,0x08,0xa0,0xc0,0x28,0x0a,0xb6,0xd4,0xcc,0x2c,0xc6,0xd4,0xda,0x48,0x49,0xcf,0x76,0x91,0x23,0x51,0x91,0xe7,0x50,0x94,0xae,0xb7,0x15,0x26,0xaa,0x82,0xd0,0x97,0xe8,0x5e,0xaa,0xfc,0xaa,0x60,0x62,0x81
+.byte 0x80,0xfd,0xfd,0xaf,0x65,0xcc,0x29,0x27,0x95,0xad,0x56,0xb9,0x85,0x66,0x49,0x62,0xb3,0x1a,0xf4,0x54,0xc7,0x5d,0x7f,0x73,0xe0,0xd2,0xc8,0x18,0x95,0x62,0x2f,0x5c,0x96,0xfb,0x63,0x15,0x46,0x07,0x5f,0x3e,0x52,0x18,0xf8,0x5d,0x45,0x0b,0xb6,0xf7,0xc5,0x3d,0x16,0xaa,0x0b,0x8f,0x9d,0x16,0xc8,0x93,0x13,0xd2,0xba,0x7a,0x52,0x1a
+.byte 0x7a,0x73,0xc4,0xca,0xfb,0x04,0xaf,0x6f,0x3e,0xfa,0xff,0x29,0x09,0xe2,0x74,0x35,0xc1,0xfc,0x21,0xcf,0x5f,0xf7,0x82,0x55,0x75,0x27,0xc9,0x91,0xc5,0xbf,0xe6,0x68,0xb6,0x0f,0x10,0x0e,0x91,0x30,0xb7,0x05,0xca,0x59,0x4a,0x7f,0xb0,0xf6,0xaf,0xf1,0x5d,0xc9,0xc5,0x06,0xc5,0xf4,0xe1,0x75,0x16,0x9a,0x2c,0xc0,0x3f,0xc1,0x98,0x91
+.byte 0xb7,0xe6,0xb1,0xf2,0xf9,0xfa,0x6d,0x27,0x98,0x33,0x8b,0x73,0x7a,0x57,0x12,0x6f,0x80,0x11,0x28,0x17,0x7d,0xf1,0x26,0xaa,0x05,0xf1,0x6e,0x86,0x98,0xe7,0xf6,0x9f,0x9c,0x06,0x8f,0xec,0xd7,0x2d,0xb0,0x83,0xdf,0x23,0x80,0x34,0xd3,0xd7,0xf7,0xd5,0x0d,0x52,0x18,0xcd,0xc7,0xe7,0x15,0xc9,0x1b,0xae,0x58,0xcf,0xc5,0xdd,0x25,0x2a
+.byte 0xff,0xa5,0xf3,0x6d,0x20,0xfd,0xda,0xfd,0x78,0x30,0x14,0x1f,0xb3,0x47,0xe3,0x2d,0x54,0x87,0xdc,0x30,0xbe,0x41,0xc0,0x48,0x52,0x82,0x49,0x78,0xad,0xfd,0x24,0xad,0xd6,0xc1,0x14,0x1e,0xa0,0xc1,0x3d,0x82,0x59,0x01,0x9b,0xc3,0xf4,0xf7,0x26,0xce,0x92,0x50,0x13,0x47,0xe0,0xf3,0xfa,0xd9,0x61,0x19,0x80,0x12,0xee,0x73,0x45,0x5b
+.byte 0x34,0xfc,0xb2,0x84,0xb2,0x3f,0xdc,0x77,0x8e,0x2d,0xb3,0x62,0xb9,0x03,0x2d,0xb6,0x2a,0x17,0xcd,0xfb,0x54,0xc2,0x5e,0xb9,0xcf,0xd6,0x05,0xe2,0xac,0x3f,0xce,0x50,0x0f,0xa1,0x3e,0x67,0x68,0x46,0x0c,0xab,0xa1,0xdc,0x2a,0x26,0x1f,0x22,0x1b,0xa7,0xc9,0x3b,0x6c,0x97,0x5d,0x5c,0x7d,0x1a,0x46,0x4a,0x99,0x92,0x85,0x87,0x35,0x6c
+.byte 0x78,0x9d,0xb0,0x39,0xd6,0x3b,0x52,0x60,0xb4,0xba,0xcc,0x2e,0xe9,0xe1,0x91,0x51,0xc1,0x52,0xc7,0x5d,0x84,0x95,0x54,0x25,0xdd,0xcd,0x40,0x35,0xa1,0xc8,0x7e,0xff,0x82,0x55,0x9f,0x64,0xef,0xa7,0xc1,0x79,0x57,0xc7,0x44,0xa8,0x1c,0x06,0xaa,0x2a,0x05,0x65,0x6c,0xdc,0x90,0x7d,0x2e,0x53,0x3c,0x56,0xe1,0x30,0xdf,0xcb,0x75,0x3d
+.byte 0x36,0x88,0xfd,0x72,0x2d,0xc7,0x8e,0x2f,0x11,0x5a,0x2e,0xa9,0xd6,0x37,0x4b,0x31,0x4e,0x6e,0xa0,0x4a,0xd9,0xa9,0x48,0x18,0x50,0xb1,0x28,0xf6,0x74,0x03,0x44,0xa7,0x06,0x55,0x86,0x1a,0x1b,0x07,0x79,0xc4,0x25,0xba,0x5d,0xce,0xa2,0x96,0x7d,0x62,0xa7,0x21,0xf0,0xa7,0xc2,0x91,0x03,0x38,0x37,0x0b,0x20,0x40,0x88,0x7b,0x28,0xf4
+.byte 0xf3,0xc2,0xb0,0x4b,0xf6,0xef,0x2f,0xd9,0xb5,0x81,0x17,0x95,0x42,0x98,0x7f,0x18,0xd4,0x7e,0xa1,0x85,0xbf,0x62,0xdc,0x40,0xe4,0xd3,0xcc,0x78,0x01,0xec,0x12,0xcc,0x04,0x5b,0xfe,0xdb,0x39,0x7c,0x1e,0x56,0x7c,0x72,0x57,0xb9,0xdf,0x9d,0x43,0xd4,0xe3,0x1f,0xbf,0x69,0xfb,0x43,0x23,0xd8,0x75,0x81,0xe8,0x39,0x0f,0xe4,0xe9,0x51
+.byte 0xea,0xb7,0xa7,0xc6,0x17,0xc6,0x75,0x4c,0xa8,0x17,0x41,0x1c,0x55,0x8e,0x8d,0xf3,0x64,0xbc,0xc3,0x33,0xa7,0xc1,0xbe,0xa2,0x89,0x75,0xd6,0xda,0xad,0x44,0xd5,0xdd,0x18,0xe2,0xfc,0x1d,0xa1,0xbc,0x1a,0xb8,0x40,0x1a,0x4f,0x44,0x4b,0x56,0xe9,0xf4,0xa8,0x16,0xe6,0xc9,0x40,0x90,0x9b,0x49,0xae,0x62,0x12,0x3d,0x50,0x2e,0x7b,0x60
+.byte 0x6f,0x04,0x01,0x2c,0x83,0x2a,0xd2,0x92,0x63,0xa2,0xe2,0x39,0x9a,0xc4,0x1e,0x5a,0x53,0x3f,0x4d,0x69,0xfa,0x0a,0x22,0x13,0x80,0xa4,0x6e,0xfb,0x09,0xcb,0x35,0xd7,0x12,0xa4,0xcd,0xfc,0x0b,0x06,0xa6,0x5e,0xc6,0x4a,0x22,0x56,0x5d,0x7f,0x70,0xd0,0xf8,0xe6,0x96,0x77,0xce,0xd9,0x69,0x6c,0x06,0xac,0xaa,0x94,0x6d,0x57,0x1b,0x28
+.byte 0xb4,0x07,0x50,0x19,0xd1,0x86,0xba,0xe6,0xe6,0x31,0x74,0x1d,0x3d,0xe8,0xe2,0x7b,0xfe,0xc9,0x41,0x89,0x20,0x5b,0x6a,0xc0,0x18,0x16,0xee,0x35,0xfa,0x56,0x35,0x3e,0x53,0x99,0xfb,0x8d,0xae,0x75,0x4f,0xc5,0x8d,0xff,0x23,0xd5,0x42,0xf4,0x81,0x5c,0x8b,0x71,0x7a,0x22,0xb0,0x6b,0x45,0x86,0xa6,0xc6,0xdb,0xa6,0x83,0x01,0x28,0xde
+.byte 0x38,0xaa,0x6e,0xf8,0x5a,0xf2,0xcc,0x3c,0xc5,0x65,0x78,0x37,0xe8,0x8a,0x59,0xf3,0xfe,0x8b,0xcd,0xf6,0x31,0x46,0xdc,0x72,0x19,0xf7,0x73,0xac,0x5c,0xf1,0xe3,0xfd,0x85,0x51,0xec,0x92,0x3a,0xf3,0xd7,0xb2,0x95,0x53,0x79,0x48,0xd3,0x29,0x84,0xec,0xc5,0x0a,0x71,0x15,0x52,0x69,0x6a,0xe1,0xab,0x69,0x94,0xc2,0x51,0xdf,0x27,0xd8
+.byte 0xb1,0x05,0xc4,0x12,0xea,0x1e,0xda,0x6e,0xf2,0xf5,0x8a,0xa8,0x72,0x74,0x5a,0xe5,0x45,0x5b,0x5f,0xf9,0xb0,0x56,0x5c,0x85,0xf7,0x63,0x8d,0x1d,0xbf,0xe9,0x7c,0x97,0xe9,0x37,0xb3,0x5b,0x4b,0x57,0xfc,0xf4,0x58,0x84,0x26,0x55,0x07,0xc7,0x0a,0xfe,0x5a,0x58,0xd0,0xd8,0x19,0xf4,0x02,0xad,0x2c,0x4e,0xbd,0xe1,0x07,0x48,0x3b,0xc4
+.byte 0xd6,0x23,0x3a,0x63,0xc3,0xf5,0x17,0x46,0x03,0xa4,0x9a,0x10,0xf9,0xac,0x70,0x9c,0x13,0x10,0x94,0xda,0x17,0xc5,0xbb,0x87,0x0f,0x9b,0x4f,0x54,0x55,0x6b,0x57,0x2d,0x12,0x0b,0xa7,0x9c,0x77,0x6d,0x67,0xb0,0x03,0xdf,0xc6,0xa2,0x76,0x96,0x0c,0xac,0x30,0xbc,0xa2,0x55,0x23,0x01,0xae,0x51,0x50,0xd4,0xab,0xd0,0xee,0x75,0xf1,0x96
+.byte 0x75,0xf5,0x2e,0xae,0x52,0x31,0x0b,0x0a,0x8a,0xdb,0x4c,0x4d,0x4c,0x80,0xfc,0xd7,0x68,0x05,0x54,0x47,0xa5,0xc4,0xb1,0x63,0x87,0x43,0x1b,0xe1,0x0b,0x4f,0xff,0x0c,0x02,0xf7,0x00,0xd4,0x8d,0x6e,0xa1,0x21,0x91,0x62,0xec,0x55,0xd5,0x72,0x70,0x59,0x7a,0xa4,0x0e,0x78,0x7a,0x87,0x1f,0x71,0x35,0x3b,0xf7,0x1f,0x66,0x8c,0x90,0xf9
+.byte 0x6d,0x1f,0x74,0x47,0x41,0xf5,0x21,0x98,0x0d,0x42,0x61,0x21,0x0b,0x62,0x59,0xc7,0x5e,0x58,0x37,0xfb,0xee,0xbb,0xa0,0x45,0xa8,0x84,0xae,0x41,0x29,0xc9,0x88,0x64,0x69,0x75,0xc1,0x5f,0x63,0x7c,0x00,0x1c,0x35,0x61,0x9e,0xad,0x19,0xd7,0xd8,0xf1,0x64,0x57,0x10,0x87,0x73,0xa8,0x8b,0x39,0x9b,0x1c,0x1a,0xc2,0x1b,0x01,0x1a,0x41
+.byte 0x26,0x58,0x93,0x8f,0xed,0xf9,0xe7,0xfe,0xcc,0x27,0x1b,0x6b,0xb8,0x28,0x5a,0x0b,0x04,0xa0,0x94,0x23,0x4b,0x21,0x5f,0xb3,0xc9,0xb6,0x7b,0x36,0x5a,0x67,0x6b,0xd2,0xc2,0x53,0x97,0x5d,0xa5,0x43,0xd3,0x79,0x83,0xe2,0x3b,0xe0,0xaf,0x5f,0xbd,0xf3,0xb0,0xfc,0x04,0x95,0x06,0x17,0x0c,0xe2,0x68,0xe8,0xf3,0x90,0xc7,0x2b,0x7b,0xcc
+.byte 0xaa,0xce,0xf5,0x0b,0x3c,0x3f,0x10,0xa7,0x31,0x9d,0xf0,0x1e,0x3e,0x74,0x57,0xbd,0x87,0xe7,0x37,0xd0,0x37,0x09,0xae,0x03,0x96,0xb1,0xad,0x8f,0x2d,0x72,0xdc,0x0f,0xdf,0xd9,0xfb,0xcc,0xb8,0x48,0x62,0xf7,0xad,0x05,0x4d,0xc6,0xe5,0x92,0xe3,0x95,0xa0,0x74,0x7a,0xa6,0x84,0x13,0x68,0x17,0xaa,0x8f,0x40,0x2a,0x8d,0x2b,0x66,0xdc
+.byte 0xf8,0xf6,0x6d,0x7c,0x7e,0x40,0x22,0x05,0x16,0x20,0xbc,0xe5,0xc2,0x87,0xe2,0xd5,0xbd,0x47,0xd5,0x69,0x95,0x12,0x25,0x1c,0xaa,0x9d,0xb5,0x73,0x08,0xaf,0xfb,0x46,0xa5,0x11,0x2c,0x93,0xc6,0xfc,0xc0,0x5e,0x0e,0x99,0x1c,0x80,0x5f,0xe5,0xc8,0x52,0x73,0x35,0x4d,0xbc,0x70,0xeb,0x40,0xc9,0x47,0x8a,0x8f,0x19,0xd9,0xa9,0xec,0x4b
+.byte 0x88,0x53,0x56,0x08,0x4a,0xa2,0x32,0x1f,0xe2,0xbb,0x68,0x35,0xfd,0xf2,0x0e,0x0f,0x7f,0xc8,0xf1,0x59,0xac,0x97,0x8f,0x84,0x69,0xb6,0xb9,0x5f,0x84,0xe9,0xf2,0xf9,0x09,0xf6,0xf1,0x31,0xd7,0x1a,0xa8,0x25,0x32,0x5f,0xb1,0xa7,0x84,0x15,0xfa,0x07,0xa8,0x53,0xce,0x2a,0x26,0xe0,0x4d,0x07,0x4f,0x45,0x63,0x76,0xfd,0xe3,0xb4,0x4e
+.byte 0x81,0x5e,0xe6,0x01,0x9c,0xf5,0x82,0x2d,0x71,0x0f,0x98,0xb4,0x72,0x06,0xbc,0x89,0x89,0x60,0x5f,0xd9,0x92,0xcf,0xb9,0x41,0xe3,0x13,0xaa,0xe4,0x80,0xb5,0x75,0xf4,0x9a,0x1b,0xc2,0xa3,0xa4,0xa9,0x0f,0x15,0xdc,0x26,0xdd,0x20,0x10,0x27,0xbd,0x06,0x77,0x12,0xa5,0xb3,0xde,0x9f,0xbf,0xc4,0xb6,0x1d,0x76,0xdc,0x16,0x00,0x2e,0xe2
+.byte 0x00,0x4d,0xb3,0x62,0x57,0x73,0x1e,0x90,0xe2,0xaa,0x4c,0x47,0xdf,0x6b,0x2d,0x66,0x2f,0x82,0x55,0x91,0x26,0x33,0xb9,0x3a,0xc7,0xf1,0x0a,0xda,0x9b,0x6b,0x05,0x82,0x0f,0x0e,0x30,0x74,0x0b,0xea,0x0f,0x49,0x55,0x3b,0xe7,0x42,0x48,0xca,0x82,0x3e,0x8c,0xbc,0xe2,0x88,0x43,0x44,0x0d,0x37,0x9b,0xd1,0xfc,0xf1,0x45,0x46,0x0e,0xe1
+.byte 0xec,0x91,0x39,0x96,0x7d,0xbc,0xd5,0xb1,0x11,0x55,0x54,0x49,0x4f,0x18,0xed,0xec,0x58,0xdb,0xb3,0x7d,0x64,0x8d,0xfc,0x65,0x1f,0xf0,0xe0,0xc0,0x41,0xc0,0x19,0xeb,0x16,0x16,0x71,0x36,0x88,0xcf,0x75,0x3d,0x9c,0xe6,0xa0,0x84,0x54,0x26,0x64,0x95,0x9a,0xe1,0x0b,0x51,0xcf,0x9a,0x55,0x60,0x4d,0x9d,0x1d,0x37,0x71,0xa8,0x94,0x0a
+.byte 0x20,0xeb,0xf2,0x91,0x14,0xfc,0x12,0xb0,0x1e,0xe3,0x5e,0x3a,0xbb,0x22,0xde,0x20,0xb1,0x58,0xef,0x0b,0xb1,0xc2,0x2f,0xea,0xd8,0xdb,0x1d,0x3a,0x67,0x7b,0xbd,0x26,0xfa,0x4a,0x3c,0x3d,0xbd,0x87,0x4c,0xba,0x57,0xdf,0xfb,0x1d,0xf7,0x26,0x5f,0x52,0x4e,0xdd,0x9b,0x38,0x62,0xed,0x48,0xc1,0xae,0x7f,0xa8,0x13,0x05,0x09,0xff,0xc0
+.byte 0xd3,0x49,0x75,0x1f,0x6a,0xe0,0x79,0x94,0xc1,0xe9,0xe3,0xf5,0x33,0x40,0xd4,0x6b,0xfe,0x4d,0x6e,0x84,0xb9,0x20,0x68,0x2b,0x6c,0xb3,0xf1,0xb1,0x1c,0xfd,0x93,0x14,0x7f,0x35,0x9b,0xd5,0x07,0x15,0x87,0x56,0xb9,0x45,0x22,0x64,0x73,0xdb,0x34,0x35,0xca,0x15,0x4e,0xa2,0xa2,0xe2,0x7a,0x6e,0x14,0x46,0xf5,0xf1,0x70,0xd3,0x3a,0x2e
+.byte 0x38,0x9d,0xf6,0xc6,0x29,0xd5,0x7f,0xc7,0x77,0x2c,0x33,0x55,0x1c,0xc2,0xf1,0xaf,0x8e,0x4d,0x1b,0x22,0x36,0x35,0x93,0x47,0xa5,0x59,0xb4,0x94,0x0f,0x2d,0x66,0x24,0x6f,0x57,0xa4,0x95,0xf3,0xd7,0xf3,0x59,0x9d,0xc0,0xda,0xa7,0xf7,0xf2,0x8d,0x93,0xc9,0x90,0x91,0x9e,0x12,0x3f,0x34,0x01,0x90,0x8b,0x13,0x09,0x3d,0x2f,0xa8,0x31
+.byte 0xfa,0x39,0x4a,0x7d,0x0d,0x34,0xa3,0xf1,0x75,0xdb,0xa2,0xd2,0x5c,0xf1,0x72,0xfd,0x7f,0x7b,0x15,0x92,0xf0,0x71,0xd6,0xa0,0x74,0x53,0x61,0x67,0xa4,0x8b,0x72,0x3a,0x66,0x0a,0xce,0xc9,0x1c,0x5b,0x4d,0xaa,0x0a,0x3a,0x91,0x0a,0xbb,0xef,0x6e,0x8d,0x00,0xc0,0xa1,0x89,0xa9,0xbd,0x5a,0x2d,0xf8,0x7c,0x1f,0xb2,0x5a,0x73,0x33,0xe7
+.byte 0xb3,0xfd,0xd4,0xe3,0x81,0x69,0x30,0xc1,0xf8,0x97,0x7b,0xf3,0x63,0xaa,0xd5,0x5a,0x98,0x95,0xb3,0x65,0x2d,0xf9,0x68,0x2e,0x2c,0x26,0xe6,0x77,0x8f,0x76,0x7a,0x02,0xc7,0x50,0x28,0x40,0xcf,0x44,0x66,0x18,0x54,0x52,0xef,0x79,0x26,0xc2,0x76,0x5b,0x71,0x92,0x49,0xba,0xe1,0xd7,0xf2,0xdd,0x57,0xe0,0x78,0x6e,0xb6,0xdd,0x0d,0x20
+.byte 0x85,0xf9,0x34,0x9e,0x65,0x6b,0x9f,0x41,0x24,0xe2,0xb1,0x2a,0xef,0x8b,0xd2,0x19,0x81,0x73,0x56,0x5a,0x84,0xd3,0x46,0xf8,0x74,0xe3,0x1f,0x3d,0xd9,0x16,0x86,0x38,0xf6,0x7c,0x04,0xab,0x9a,0x64,0x0e,0x48,0x06,0x4c,0x61,0xcd,0x2d,0x4d,0xef,0x6f,0xd6,0x7d,0x31,0x1c,0x56,0x65,0xc4,0xf1,0xa7,0x15,0xac,0xa4,0xe2,0x8b,0x83,0x5e
+.byte 0x64,0x36,0x2e,0x77,0x94,0x2e,0x2e,0xa3,0x62,0xcf,0x6e,0x7a,0x6d,0x39,0xaf,0xf7,0x96,0x88,0x31,0x14,0x58,0x46,0x30,0x0c,0x36,0x3a,0x4c,0x53,0xe0,0xa7,0x24,0x76,0x84,0x0f,0xfb,0x7e,0x55,0xa0,0x0f,0x63,0xfc,0xd6,0x1f,0x58,0x68,0xb5,0xcc,0x77,0x4f,0x16,0x91,0xa7,0xfd,0x62,0xb3,0x88,0x13,0x7c,0xcb,0x63,0x6d,0xe4,0x38,0x4c
+.byte 0x6e,0x3b,0xf7,0xe3,0x8d,0x52,0x84,0x61,0x19,0x12,0x51,0xbe,0xed,0x32,0x3d,0x77,0xdd,0xa1,0xc3,0x59,0x65,0x79,0xa1,0x6b,0xbc,0x65,0x6c,0xe3,0x7e,0x60,0x49,0xbd,0xcf,0x6f,0x61,0x97,0x98,0xbe,0x74,0x38,0xd1,0x09,0xc1,0x59,0xe5,0x7f,0xfe,0xbf,0xfd,0x60,0x1b,0x96,0x00,0x46,0x56,0x4d,0x81,0x4c,0x70,0x59,0x39,0x66,0x13,0x58
+.byte 0xe7,0x62,0x3a,0xfc,0x1b,0xe5,0xf9,0x03,0xd4,0x4b,0xab,0x1d,0x56,0x22,0x4a,0x09,0xa5,0xdd,0xac,0x39,0xbe,0x27,0x39,0xb3,0xe8,0xad,0xe0,0x07,0x86,0x10,0xce,0xa9,0x4e,0x8b,0x47,0x8d,0xb8,0x63,0x2f,0x61,0x1a,0x8b,0xd4,0xd3,0xfe,0x73,0x82,0x5a,0xd6,0xa9,0x46,0x56,0xa7,0x81,0xe9,0xda,0xb9,0x17,0xa7,0xc8,0x0f,0x24,0x16,0x6a
+.byte 0x12,0xfe,0xc3,0x65,0x85,0x77,0xab,0x89,0x44,0x1b,0xa3,0x8b,0xfd,0x07,0xf4,0x77,0xaa,0xe1,0x71,0x33,0x74,0x93,0xdc,0x90,0x53,0x39,0x47,0x8c,0xea,0x18,0xe1,0x6a,0xed,0x8c,0x56,0x08,0x2f,0xa1,0x1f,0x22,0xf2,0xc0,0x12,0xcd,0xb7,0xdf,0xb6,0x3c,0xd6,0x22,0x6c,0x5b,0x00,0x0f,0xdb,0x66,0x5b,0x54,0x35,0x48,0x37,0x8c,0x79,0x74
+.byte 0xd1,0xb0,0x15,0x01,0x22,0x3a,0x7c,0x17,0x8c,0x20,0x06,0x9b,0x13,0x6e,0xee,0xbf,0xb4,0xac,0x01,0x61,0xb9,0x28,0x65,0x8e,0x53,0x12,0x4f,0xe0,0x5f,0xfc,0xdb,0x40,0x6c,0xa2,0x19,0x64,0x49,0x7a,0xc7,0xc5,0xc8,0x53,0x6e,0xd5,0x68,0xe1,0x61,0xe5,0x87,0xc2,0x99,0x59,0x4c,0x27,0xc8,0xd0,0xd0,0x10,0xce,0x9f,0x09,0xff,0xf5,0xa8
+.byte 0xf8,0x79,0xf6,0x0f,0x73,0xda,0x8a,0x36,0x8e,0x48,0x7e,0xbd,0x98,0x76,0x57,0xfa,0x5c,0xec,0xa5,0x3d,0x30,0xfe,0xa3,0xe5,0x27,0x87,0xcf,0x26,0xfe,0x61,0xe4,0xed,0xd1,0xfb,0xfc,0x91,0x5d,0xb6,0x70,0x2c,0x2c,0x59,0x14,0xd5,0x1d,0x9a,0xb9,0x2c,0xef,0x24,0x7b,0x10,0x8d,0x99,0x63,0xaa,0x82,0xf0,0x1c,0xe8,0xa0,0x00,0xa5,0xa7
+.byte 0xf8,0xc0,0x35,0x9e,0x12,0x18,0xaf,0x42,0x9d,0xe5,0x2b,0x72,0x6c,0x31,0xd8,0x8f,0x6c,0xde,0x2e,0x37,0xa6,0x73,0x06,0xe7,0x90,0x43,0x79,0x99,0x64,0xd1,0x17,0xa1,0x43,0x6d,0xd4,0x90,0x50,0xf2,0xcc,0x0b,0x73,0x49,0x9e,0x14,0x7c,0x49,0x92,0x05,0x0e,0x8c,0xda,0xb7,0x18,0xf0,0xcc,0xea,0xe4,0x32,0x58,0xc7,0xbd,0x8e,0xca,0x35
+.byte 0x52,0x9f,0xec,0x5d,0xa0,0x6c,0x83,0x61,0x07,0x74,0x37,0x4a,0x10,0xa0,0x98,0x83,0x3a,0x65,0x17,0x63,0xd0,0x22,0x96,0xb5,0xed,0xbb,0xbb,0x1c,0x18,0x8a,0x49,0x3d,0x0f,0xcc,0x24,0xb3,0x9b,0xb6,0x23,0x2e,0x9d,0x97,0xe7,0x31,0xf8,0x36,0x6d,0x7b,0xa1,0xf1,0x02,0xde,0x7c,0xad,0x77,0x5d,0x85,0x7c,0x39,0x61,0xc7,0xd7,0x3f,0x70
+.byte 0x1c,0xe1,0x0e,0x49,0xf4,0xcd,0xab,0xfd,0x4d,0x2f,0xc7,0xb7,0x53,0xfc,0xed,0xeb,0x41,0x2a,0x80,0x40,0xf3,0x47,0xf8,0x15,0xa0,0x4c,0x8b,0x34,0xf6,0x6a,0xb8,0x30,0x09,0x4d,0xe6,0x60,0xb7,0x24,0x6b,0x4c,0x26,0xdf,0x83,0x37,0xc7,0x96,0xba,0x35,0xda,0x29,0x4e,0xca,0x52,0xf7,0x41,0xd3,0x98,0x27,0xb2,0x9e,0xec,0xcc,0x12,0xdc
+.byte 0x77,0xfd,0x11,0xbd,0xbd,0xbb,0x5e,0x0c,0x37,0x29,0xd2,0x4f,0x7d,0x5c,0x97,0xad,0x72,0x93,0x4a,0xfa,0x17,0x07,0x07,0x26,0xee,0xa7,0x29,0x2e,0xdb,0xf6,0x60,0x65,0x2d,0x85,0xbe,0x27,0x4d,0xf7,0x2b,0xb4,0x81,0xf5,0x3a,0x1d,0xae,0x25,0x8b,0x60,0xc2,0x75,0x3a,0xfd,0xf9,0x4d,0x90,0x7a,0x8a,0x3a,0xf6,0xa9,0xf0,0x11,0xd2,0xb9
+.byte 0xdb,0x23,0x40,0x9d,0x33,0xc3,0xbf,0x60,0x95,0x9c,0x6f,0xa9,0x82,0x42,0xe5,0x67,0x52,0x36,0xea,0x68,0x64,0x24,0x85,0x46,0x7e,0x2a,0x1a,0x6a,0x4b,0xa8,0xb0,0xa0,0x9c,0xb8,0x4a,0xb6,0x2e,0xb2,0x6b,0xf4,0x63,0x9f,0x54,0xb5,0x6f,0x1b,0xf5,0x71,0x7e,0xf8,0xef,0xb2,0x92,0xe2,0xcf,0x65,0xb4,0x02,0x9b,0x75,0x4b,0xf9,0x6b,0xa1
+.byte 0x24,0x3b,0xea,0x7f,0x31,0x08,0xd4,0xdc,0xab,0x12,0xc0,0xca,0x64,0xee,0xfa,0x61,0x1c,0x0f,0x24,0xc3,0x8c,0xbd,0xc8,0xd2,0x42,0xf7,0x1f,0x2e,0xd3,0xd1,0x51,0x86,0xfb,0xa2,0x95,0xc5,0x8c,0x5b,0x61,0x14,0xc9,0xe4,0x07,0xa1,0xf7,0x39,0x11,0x40,0x68,0xd6,0xe2,0x38,0x96,0x6f,0x99,0xf1,0xd2,0xfb,0x8e,0xb8,0x3d,0xf2,0x8a,0x4e
+.byte 0x3e,0x54,0xd9,0x0e,0xd1,0xc9,0x31,0x04,0xa4,0xee,0xbe,0x51,0xcf,0x5f,0xd1,0xc8,0x13,0x96,0x9d,0x9b,0xdf,0x32,0xa9,0x38,0x8f,0xbc,0x7e,0x22,0x1a,0x52,0x5f,0x14,0x61,0xeb,0x78,0xf4,0x01,0xe9,0x5c,0x18,0x1c,0xb5,0xe1,0x80,0x06,0x3e,0x8e,0x72,0x33,0xf9,0xaa,0x49,0xec,0x5b,0x7a,0x04,0xf2,0x9b,0x48,0x8a,0x58,0x14,0x4b,0x7e
+.byte 0x4d,0x26,0x0b,0xe0,0xf0,0x69,0xa3,0x36,0x75,0x3e,0x73,0xec,0x53,0x20,0x35,0x8e,0xfa,0x40,0xf0,0xcd,0x70,0xe1,0xe4,0x64,0x89,0x14,0x55,0xd7,0x20,0xe8,0xbd,0xc2,0x85,0xa8,0x4d,0x51,0x96,0x27,0x54,0x50,0xc7,0xa1,0x9c,0x35,0x52,0x1f,0x8b,0x6f,0xa2,0x62,0x36,0x94,0x02,0xb1,0x01,0xc6,0x4e,0x53,0x83,0x65,0x98,0x25,0x6d,0x26
+.byte 0x6d,0xef,0x4e,0x7a,0xe0,0x56,0x6a,0x6c,0x23,0xe8,0xa6,0x97,0xc1,0xf2,0xb1,0x2d,0x03,0x29,0xef,0xa0,0x6d,0x86,0x8d,0x5a,0x00,0x83,0x14,0xed,0xd4,0x1e,0x79,0xc4,0xb4,0x42,0xfd,0x53,0xaa,0xab,0xd7,0xa3,0xf9,0x7d,0x15,0x26,0xab,0x81,0xc4,0x7a,0x96,0x14,0x94,0x71,0xe1,0x7f,0xc1,0x67,0x5f,0x5f,0x11,0xb4,0x72,0x03,0xf8,0x9b
+.byte 0x2f,0x82,0xa3,0x4e,0xda,0xfd,0x2a,0x31,0xf1,0x74,0x6d,0x96,0x7a,0x9c,0xf9,0x01,0xd9,0x55,0x8e,0x52,0xe4,0xae,0x22,0x14,0x7b,0xc0,0x5a,0xc4,0x31,0x23,0x9a,0x2e,0x9d,0x86,0x86,0xd5,0x66,0xc8,0x8b,0xdb,0x49,0x5f,0xca,0x57,0x51,0x50,0x75,0x3f,0xeb,0xb1,0xe5,0x84,0x42,0x8f,0x0f,0xca,0x86,0xcf,0xb0,0x17,0x06,0x06,0x46,0x8c
+.byte 0x4a,0x84,0xde,0x28,0x84,0x24,0x7f,0x33,0x48,0xe8,0x89,0x87,0x1f,0x02,0x07,0x4f,0x36,0xa9,0xdc,0x8a,0x42,0xb6,0xc7,0x9c,0x47,0xd4,0xd4,0x2d,0xc0,0x17,0xb0,0xe6,0x23,0xb7,0xae,0x0d,0x9f,0x38,0x0a,0xdf,0x7f,0x73,0xbf,0x93,0x19,0x05,0x23,0xbf,0xc0,0x53,0x2d,0xcd,0x3e,0x73,0x01,0x78,0xa7,0xdc,0x6c,0x85,0x1d,0x25,0xc5,0x54
+.byte 0x68,0x95,0xc1,0x20,0x65,0xd9,0x01,0x85,0x7d,0xc9,0xba,0x63,0x43,0x7a,0x23,0xbb,0x95,0x3a,0x76,0x2d,0x75,0x1e,0xac,0x66,0x3e,0x20,0x30,0x8d,0x37,0x64,0x3c,0xc7,0x6f,0x36,0xb8,0x34,0x60,0xd2,0xb4,0x54,0x07,0x52,0x6c,0xfa,0x04,0xfe,0x2b,0x71,0x03,0x03,0x97,0xfc,0x4a,0xf9,0x4d,0x44,0x1a,0xf9,0xd7,0x4b,0xe5,0xe1,0xf9,0xb9
+.byte 0x41,0xa0,0x5b,0xa2,0x69,0x48,0xba,0xeb,0xcc,0x4e,0x55,0x4b,0xbd,0x41,0x09,0xa8,0x90,0x5c,0xc6,0xe3,0x20,0x0c,0x8f,0xfc,0x7e,0x0e,0x4f,0x3d,0x47,0x65,0x40,0x1e,0x79,0x9a,0xe0,0x8f,0x8f,0xe9,0xcb,0xaa,0x04,0xb8,0xd9,0x91,0x30,0x2a,0x4c,0x17,0x44,0xc0,0x03,0x4c,0x37,0xd3,0xdb,0x20,0xe5,0x8e,0x70,0x87,0x57,0x4f,0x8a,0xcf
+.byte 0xee,0x64,0xbc,0xef,0x0f,0x9e,0xcf,0x95,0x5e,0x11,0x4f,0x7a,0x35,0x53,0x8c,0x85,0x6a,0xff,0x72,0x1b,0x35,0x51,0x89,0xf8,0x94,0x65,0x97,0xec,0xfe,0xbd,0x00,0x29,0x3d,0xe8,0x96,0x23,0xa4,0xe3,0xcf,0x81,0xb2,0x8f,0x73,0x4c,0x05,0xc3,0xcc,0x37,0x22,0x97,0xa0,0xda,0x49,0xb2,0xbd,0x07,0x2b,0x26,0xa0,0x6f,0x6b,0x1f,0xa6,0x15
+.byte 0xe3,0x6e,0x12,0xa4,0x51,0x1b,0x72,0x22,0x08,0xfe,0xf7,0x93,0x1a,0x9f,0x62,0x12,0xd4,0x11,0x1f,0xd1,0x80,0xeb,0xa4,0xb1,0xf4,0x37,0x3b,0x60,0xd8,0x2b,0x53,0xae,0x69,0xf8,0x48,0x38,0xf4,0x20,0x28,0xe1,0xfb,0x6a,0xec,0x6e,0x11,0x2e,0x2c,0x59,0x62,0x23,0x8a,0x82,0xc4,0x33,0x7b,0xdc,0x33,0x99,0x41,0x29,0x4f,0xa1,0x6e,0x3a
+.byte 0x48,0x13,0x1c,0x1f,0xa3,0x1f,0xd2,0x02,0x79,0xe1,0xe4,0xb9,0x99,0xa4,0x50,0xea,0x53,0x96,0x4e,0x82,0x7c,0xee,0x65,0x07,0x26,0x87,0xf9,0x9d,0x45,0x17,0x37,0x61,0x7e,0x5f,0xb9,0xd2,0x55,0x3c,0x45,0xf7,0xec,0x33,0x08,0xa3,0x41,0x24,0x8f,0xb2,0x75,0x41,0xb6,0xa2,0x21,0xfe,0x94,0x7e,0x1e,0xe6,0x03,0x6e,0xf4,0xeb,0x23,0x59
+.byte 0x51,0x25,0x99,0x19,0x6d,0xf7,0xe3,0x22,0xd8,0x41,0x0f,0xd5,0xaf,0x0d,0xc6,0x3f,0x8e,0x36,0xee,0x90,0x23,0x67,0x03,0xcb,0xe3,0xaf,0xc4,0xf8,0x22,0x1f,0xd8,0x3e,0x94,0xdf,0x13,0xc9,0x4f,0x17,0x22,0x8c,0x93,0x6b,0x3f,0x60,0x1a,0xbd,0xfa,0x9f,0xe6,0x43,0x45,0xe1,0x0a,0x95,0x21,0x06,0x52,0xbd,0x58,0x56,0x84,0x56,0x36,0xf3
+.byte 0x55,0x58,0x46,0x62,0x6c,0xb3,0xa0,0x29,0x5a,0xfc,0xb4,0x87,0x5f,0x89,0xa5,0xab,0x6d,0x5a,0x44,0xc5,0xc8,0x50,0x83,0xe1,0x41,0xd4,0x97,0x6c,0x08,0xb1,0x43,0x33,0x0d,0x3a,0x8b,0x31,0xa1,0xae,0x77,0x71,0xb7,0x67,0x65,0xd7,0xa7,0xc9,0x6c,0x4a,0x9b,0x80,0xd5,0xbf,0xae,0x0f,0x9b,0xce,0x1a,0xa3,0x26,0xc6,0x19,0xa1,0x8d,0x12
+.byte 0xd9,0x09,0xae,0xac,0x9f,0x4b,0xab,0xaf,0xf6,0xc5,0x9e,0x26,0xe6,0x23,0xcb,0x3e,0x60,0x1e,0x3d,0xa1,0xec,0x59,0xca,0xf1,0x87,0x0e,0xaf,0x47,0x5f,0xab,0x17,0x99,0xbd,0x87,0x1c,0x1d,0x00,0xd6,0xb2,0x59,0x56,0xdd,0x49,0x20,0xb5,0x91,0xf8,0x0c,0xf1,0x80,0xc6,0x37,0x92,0xd7,0x2c,0x02,0x0d,0x47,0x1b,0x1b,0x6b,0x3f,0x60,0xd0
+.byte 0x21,0x9b,0x49,0x47,0x3c,0xaa,0x83,0x44,0x1b,0x92,0x8e,0xec,0x63,0x40,0xd6,0x9a,0x48,0x7c,0x5e,0x97,0xe4,0xf0,0x84,0x36,0x30,0x11,0x0b,0x7c,0x79,0x3b,0xff,0xdf,0x77,0xf6,0xc9,0xdb,0x49,0xdd,0x2a,0xe7,0xca,0x9a,0x5b,0xef,0xd4,0x84,0xe2,0x44,0x8b,0xef,0x4e,0x0d,0x13,0xd6,0xbb,0xba,0x29,0x02,0xae,0xfc,0x55,0x24,0xfa,0x4b
+.byte 0x7d,0x71,0xc9,0xde,0x71,0x36,0xbc,0xac,0x31,0x5c,0xf8,0x20,0xdd,0xb8,0xae,0x03,0xd3,0xb0,0xdc,0x27,0x7f,0xc5,0xff,0xda,0x8a,0x36,0x2d,0x8f,0xae,0xbd,0xf8,0x92,0x28,0x8e,0x0c,0xc3,0xaf,0x4e,0x33,0xf0,0x71,0xdb,0xad,0x4d,0xc1,0xef,0x52,0x1c,0x84,0xdc,0x0d,0xf3,0xab,0xb9,0x0b,0xe0,0x18,0xa5,0x06,0xdc,0x78,0x41,0x73,0x35
+.byte 0x95,0x37,0x84,0xba,0xc1,0x4e,0x0a,0xe4,0x4d,0x05,0xfe,0x9d,0x74,0x68,0x4a,0x35,0xf0,0x15,0xaa,0x7b,0xfe,0x08,0x47,0xb2,0x84,0x65,0x1d,0x0d,0x9f,0xe7,0xe0,0x04,0xf9,0x1c,0xac,0x66,0xb3,0x75,0x96,0x8f,0x25,0xb6,0x29,0x53,0x52,0x50,0x7a,0x50,0xd1,0x89,0xc7,0x05,0xfb,0x3a,0xb0,0xfa,0x6b,0x96,0x9d,0xfc,0xb0,0xcd,0x68,0x21
+.byte 0x61,0xf6,0x65,0x64,0xa7,0xc6,0x56,0xbd,0xf0,0x9b,0x4a,0x9a,0xe2,0x8c,0xd8,0x88,0x70,0x82,0x0c,0x87,0x51,0x77,0x23,0xd8,0xd8,0xf8,0x4a,0xfe,0xf4,0x6d,0x3f,0x2a,0x36,0x0c,0x67,0x85,0x43,0x13,0x83,0xd5,0xe9,0x32,0xff,0x8c,0xec,0xd4,0x7f,0xd2,0x32,0x4d,0x4e,0xec,0x76,0x55,0xf9,0x0d,0xb7,0x57,0x6c,0xc4,0xd6,0x22,0xd3,0x6e
+.byte 0x71,0x23,0x68,0x45,0x03,0x37,0x27,0x3d,0x56,0x89,0xbb,0x7c,0xf1,0xa8,0x09,0xd6,0xb2,0xc5,0xe6,0xf6,0x72,0x77,0x3e,0xb0,0x8a,0x3d,0x17,0xbd,0xd5,0x0d,0xdb,0x62,0xa7,0x07,0x66,0x35,0x19,0x12,0xff,0xcf,0xdd,0xb3,0x09,0xa3,0x58,0x5b,0x0d,0x87,0x76,0x33,0x28,0x98,0x91,0x48,0xac,0xa1,0x22,0x9f,0xda,0x36,0x03,0x8a,0xc1,0x5e
+.byte 0x6c,0x2e,0x42,0x8e,0x1a,0x7d,0x75,0x69,0xb2,0xcf,0xb0,0x14,0x80,0xa8,0x91,0xc2,0xbc,0x24,0x8f,0x25,0x9a,0x9e,0xa3,0x4d,0x46,0x55,0x53,0x05,0x0c,0xf8,0xdb,0xe0,0xee,0xe4,0x32,0xff,0x39,0x74,0x9a,0xa8,0xf7,0xa4,0x6e,0x5b,0x9a,0x89,0x33,0x40,0xf4,0xce,0x54,0x4a,0x18,0xdb,0x11,0xe4,0x83,0x69,0x52,0xef,0x12,0xc6,0x13,0x6e
+.byte 0x2a,0x14,0xb9,0x8e,0x38,0x8d,0x6b,0xef,0x02,0xc8,0x66,0xf0,0x78,0xaa,0xa6,0x04,0xa3,0xa5,0x1d,0xdb,0xac,0x02,0x23,0x4c,0x2a,0xa5,0xbf,0x66,0xa4,0x47,0xa9,0x8e,0x50,0xd2,0xf8,0xf5,0x0d,0x0f,0xc9,0x07,0xd8,0x1a,0x94,0x84,0xcf,0xb3,0x56,0x53,0x5f,0x83,0x1d,0x30,0xb6,0x94,0x36,0xf4,0x16,0x72,0x8c,0x6d,0x49,0xe4,0x6d,0x93
+.byte 0xb1,0xa1,0x97,0x70,0x75,0x47,0x3a,0x7e,0xa6,0x39,0x1d,0xf5,0xcc,0x37,0xaa,0x90,0x53,0xe1,0x9b,0xcb,0x9a,0x97,0x7d,0x18,0x4a,0x3c,0x1f,0x05,0xf4,0xe3,0x6f,0x7a,0x19,0x84,0xbc,0x68,0xa4,0x6e,0x5a,0xb5,0x7a,0x51,0xda,0xf5,0x75,0x1e,0xfe,0xb0,0x73,0x43,0x39,0x98,0xb7,0x1e,0x17,0x36,0x35,0x15,0x64,0x90,0xb6,0x83,0x43,0x8f
+.byte 0xcd,0xb6,0x8c,0xc4,0xe4,0xee,0x0e,0x1c,0xbd,0x3a,0xe6,0x6e,0x44,0x73,0x88,0x30,0xa0,0xf0,0x97,0xf5,0x5e,0x12,0xea,0xd9,0xd7,0xb5,0xc5,0x1d,0xc7,0xc8,0x55,0xbb,0x2c,0x64,0x43,0x50,0x15,0x71,0x02,0xd3,0xf9,0xb4,0xe7,0x2f,0x0f,0x98,0x9e,0x87,0x40,0x2a,0x61,0x06,0x44,0xc2,0x47,0xaf,0x44,0x4f,0xdd,0xa3,0xb0,0xb2,0x8d,0x8c
+.byte 0x83,0x96,0xd3,0x2a,0x38,0xdf,0x87,0x5d,0x1c,0x64,0xc8,0x4f,0x3c,0x41,0xc7,0xf8,0x64,0x58,0xa6,0x9b,0xcb,0xcd,0x77,0xdb,0x38,0xe7,0x30,0xb6,0x91,0x88,0xd8,0x9d,0x29,0x71,0x12,0x9e,0xdf,0x20,0xd9,0x14,0xa3,0xa0,0xbd,0x0a,0x99,0x67,0x0a,0xe1,0xe9,0xba,0xd0,0x1b,0xba,0xc8,0x8d,0x76,0x10,0xe8,0x30,0xa1,0x93,0xf4,0x95,0x6a
+.byte 0x12,0xd5,0x95,0x31,0x7f,0xdb,0x33,0xfc,0xbf,0x7a,0xbe,0xe4,0xfa,0x50,0x1b,0x24,0x75,0x9b,0xf8,0x81,0x34,0xc8,0xfb,0xda,0x3c,0x6f,0x3b,0x9a,0xb2,0x6f,0x94,0x0c,0xd9,0xc3,0x05,0xd6,0x96,0x10,0x27,0xdb,0xd6,0x88,0x72,0xe4,0x8f,0xfc,0xd3,0x52,0xf8,0x63,0xb2,0xce,0xf1,0x2a,0xbc,0x1c,0x23,0x9d,0xfb,0x27,0xdd,0x8d,0xe4,0xcc
+.byte 0x63,0xcf,0xad,0xe6,0xe9,0x4f,0xb8,0x8a,0x20,0x47,0x75,0x73,0x3f,0x27,0x07,0x5d,0x8c,0x8c,0x6e,0x7a,0x91,0xe2,0xf6,0xd5,0x70,0xd8,0x00,0xe5,0x0f,0xde,0x78,0xd8,0xb4,0xd3,0x18,0x5a,0x24,0x43,0x91,0x0c,0xbe,0x8b,0x1b,0x88,0x48,0x7e,0x94,0x05,0xd0,0xec,0xd2,0x71,0x26,0xc7,0x70,0xeb,0x8a,0x83,0x01,0x52,0xdb,0xe5,0x76,0x31
+.byte 0x19,0x14,0x13,0x90,0x5b,0x5a,0x94,0x89,0xe2,0x4e,0x2d,0x17,0xf6,0xbc,0x67,0xee,0x51,0xd4,0x00,0x83,0xe5,0x18,0xa5,0x54,0x6c,0xd2,0x7a,0x1f,0xdb,0x6f,0xed,0x7f,0x07,0xbb,0x9f,0x3a,0xc2,0x8c,0x04,0xf9,0x9a,0x55,0xe3,0x70,0xf3,0x36,0xfd,0x44,0x05,0xd9,0xf3,0xe1,0x87,0x2c,0x29,0xec,0x30,0x8b,0xb7,0xde,0x27,0xa4,0xcd,0xdf
+.byte 0x64,0x0b,0x62,0xdf,0x34,0xa0,0xf5,0xa1,0x69,0xc9,0x0b,0x00,0x81,0xf4,0x03,0x5e,0xef,0xb8,0x26,0x49,0x71,0x5e,0xcd,0x76,0xa2,0x38,0x25,0x1f,0x92,0xc3,0xbf,0xdb,0xb3,0x29,0x37,0x06,0xc5,0xc2,0x3b,0xd8,0xbd,0x55,0xf2,0x7f,0xd5,0xd5,0x34,0x32,0xf1,0xa0,0x92,0x9b,0x1c,0xee,0x6f,0x48,0x40,0x6b,0xd1,0x45,0x09,0x3f,0xaf,0xdc
+.byte 0xe1,0xac,0x75,0x9a,0x33,0xf7,0x50,0x4f,0x2c,0x3c,0x30,0x69,0x69,0x84,0xcb,0xe9,0xca,0xdf,0x8d,0x02,0x5d,0x30,0x71,0x99,0x7b,0xd5,0xb2,0x55,0xdd,0x9c,0x2f,0xae,0x11,0x41,0x01,0x6b,0xf7,0x95,0xe3,0xda,0xe3,0xcc,0xa4,0x17,0xd0,0x50,0xf9,0x4c,0x31,0x2b,0x4e,0xf7,0x49,0xbb,0x75,0x8f,0x28,0x19,0x9f,0x89,0x7b,0x78,0x80,0x41
+.byte 0x50,0x5a,0x5c,0x1e,0x82,0x93,0x9f,0x4f,0x61,0x96,0x29,0x0c,0x25,0xb3,0xe6,0xff,0x86,0x90,0x78,0x09,0x04,0xf9,0x2a,0x3d,0xa1,0xd5,0x68,0xa8,0x0d,0xd9,0x41,0x01,0xdc,0x41,0x01,0xff,0x20,0xc0,0x63,0x0b,0x4d,0xd5,0x80,0x78,0x82,0x05,0x51,0x62,0x09,0xf9,0x11,0xbd,0xde,0xc0,0x7d,0x3f,0xf2,0x30,0xfb,0x41,0x68,0x39,0xb0,0xc2
+.byte 0x2e,0x33,0x4e,0xa7,0x85,0x01,0x6b,0xd1,0xf9,0x78,0xef,0xe9,0x7c,0x0e,0xaf,0x13,0x1a,0xf5,0x97,0xde,0xf0,0xbb,0x67,0xf9,0x9b,0xab,0xee,0x86,0x73,0x9b,0x23,0x6c,0x56,0x0d,0xa0,0xda,0x4c,0xff,0x2b,0xc5,0x92,0xdb,0xee,0xbd,0xba,0x3a,0x54,0x21,0xc0,0x5c,0xfe,0x21,0xf1,0xbd,0xac,0xaf,0xa3,0x7a,0x52,0x62,0x15,0x8b,0x8f,0xb5
+.byte 0x82,0xc6,0x1a,0xfb,0x22,0xbc,0xa2,0x05,0x42,0xfe,0xb4,0x12,0x6b,0xad,0xa9,0x76,0xb7,0x6b,0x1c,0xd8,0x34,0x5c,0x7d,0xd5,0xa9,0x0d,0x91,0xf6,0xc1,0x47,0x69,0xbc,0x43,0x8f,0xb7,0xfc,0x84,0x2e,0xa0,0x8e,0x3f,0x52,0x3b,0xbd,0x1f,0x28,0x6b,0xc8,0x13,0x37,0xd6,0x44,0xe9,0x8d,0x08,0x92,0x96,0xe5,0x2c,0x57,0x34,0x59,0x21,0x04
+.byte 0xa8,0xaa,0x56,0x25,0xa4,0xc8,0xae,0x68,0x17,0x9e,0xa4,0xf4,0x42,0x64,0x57,0x4b,0x54,0x85,0x8a,0xd1,0x09,0x09,0x25,0x18,0x05,0xb0,0x09,0x9d,0xd9,0x75,0x21,0xd3,0x75,0x31,0xf8,0x35,0x46,0xc8,0xd4,0x47,0x9d,0x87,0xeb,0x40,0x95,0x19,0x24,0x7c,0x6e,0xe9,0xd5,0x14,0xaa,0xc3,0xbe,0x22,0x18,0xc1,0xa0,0x5f,0x34,0x98,0xc2,0x4d
+.byte 0x3f,0xa6,0x09,0x57,0x1b,0x75,0xc6,0x89,0xee,0xf0,0xbd,0xbc,0x1a,0xd3,0xea,0x6e,0x82,0x06,0x90,0x4f,0xbb,0x61,0xac,0xbb,0x3e,0x8c,0x94,0xea,0x69,0x58,0x26,0x2e,0x17,0x78,0xad,0x14,0xa4,0x79,0x14,0xbd,0xc1,0x78,0xf9,0xbb,0x11,0x7e,0x8d,0xbf,0x3e,0xc8,0xc5,0x69,0xd7,0x5a,0x4c,0x4b,0x86,0x25,0x4c,0xe9,0x3a,0xc2,0xd9,0xf8
+.byte 0xbf,0x5e,0x46,0x4f,0xca,0xba,0x25,0x58,0x73,0x82,0x02,0x8a,0x41,0x9e,0x2d,0xa9,0x08,0xb4,0x60,0x2a,0x11,0x2c,0x2f,0x3d,0x5e,0x68,0xd8,0xa9,0x2e,0x1c,0xfa,0xdc,0xda,0xfb,0xfb,0xf3,0xb2,0x66,0xd3,0x57,0xe6,0x09,0xeb,0xe5,0xf4,0xed,0x2d,0xb7,0x3a,0xce,0x69,0x2d,0xb4,0x79,0x1a,0x99,0x9d,0xc8,0x99,0x9f,0x9b,0x78,0xd4,0x8a
+.byte 0x73,0xd5,0x89,0x9f,0xda,0xdf,0xd0,0xca,0x6b,0x63,0x5a,0x1e,0xe0,0x2f,0x01,0xa4,0xd0,0x62,0xc0,0x5f,0x4e,0xd9,0xd3,0x47,0xe4,0x68,0x73,0x8c,0x87,0x50,0x91,0xec,0x8e,0x0b,0xa7,0xf0,0x4c,0x32,0x19,0xaa,0x00,0xbd,0xe4,0x20,0xab,0x5c,0x00,0xdb,0x18,0xc0,0xff,0xc1,0xc0,0x8f,0xa2,0x8c,0x47,0x91,0x86,0xde,0xa9,0x09,0xb5,0x86
+.byte 0xcc,0x1d,0x7f,0x4b,0x7d,0x16,0xf6,0x21,0xd0,0xf8,0xaa,0x16,0x20,0xa9,0xac,0x3e,0xef,0x56,0xee,0x0e,0x1d,0xd6,0x44,0x7d,0xa9,0x84,0x41,0x8d,0x69,0x69,0x92,0x74,0x87,0x3b,0x8a,0xbf,0x40,0x29,0x45,0xf9,0xa8,0x52,0x8c,0x99,0x95,0xe7,0x6a,0xcd,0x3f,0x74,0x2d,0xde,0x82,0x47,0x41,0xa6,0xd9,0x5a,0x30,0x6c,0x20,0x98,0x3f,0xfb
+.byte 0x66,0x08,0x73,0x68,0xe1,0xcd,0xfd,0x3c,0x4f,0x33,0x6b,0x42,0xa4,0xab,0x78,0x22,0xb5,0xd9,0x6f,0x99,0xcb,0x85,0x6a,0x14,0xb9,0xd3,0x0f,0xfb,0xd7,0x07,0x7b,0xbe,0x6a,0xd9,0xba,0xde,0x98,0xac,0xd8,0xe5,0x40,0xcd,0x59,0x7f,0x88,0x3c,0x4e,0xfa,0xfe,0xbe,0x48,0x21,0xb5,0x40,0xd5,0xc8,0x1e,0x8a,0x56,0xd9,0xec,0x25,0xad,0x5e
+.byte 0x31,0xf3,0xf2,0x3d,0x0b,0x56,0xb5,0x20,0x08,0xd3,0x02,0x81,0x93,0x29,0x3d,0xbd,0x0a,0x9c,0x26,0x74,0xdb,0x6b,0x7e,0xd1,0x4a,0x1a,0x1c,0x47,0x49,0x34,0xba,0x08,0x7a,0x6a,0xb3,0xd6,0x3b,0xd0,0x28,0x50,0xa1,0xd8,0x17,0x85,0x61,0xab,0x24,0x22,0xda,0xc8,0xb4,0x1b,0x07,0x2e,0x67,0x77,0x84,0xdc,0x6f,0xfd,0x51,0xa5,0xe8,0x34
+.byte 0x63,0xbd,0xae,0xae,0xc7,0x84,0x1d,0x60,0xc8,0x8f,0xde,0x22,0xfd,0x85,0xb4,0x12,0xb4,0x04,0x5b,0xe7,0xb5,0x58,0xf8,0x56,0x66,0xa3,0xb7,0x1e,0x54,0xd0,0xdb,0x12,0xaa,0x9c,0x89,0x5b,0xfa,0xf4,0xe7,0xe2,0xf4,0x9c,0x08,0xa8,0xbe,0x6b,0xe3,0xce,0x6a,0x88,0xb5,0x74,0xb9,0x49,0xaa,0x7b,0xcd,0xbc,0x17,0x81,0x61,0xe2,0x28,0x6f
+.byte 0x4b,0xe8,0xa4,0x55,0xc5,0x1e,0x69,0x21,0x8f,0xfd,0xa8,0xd0,0xb9,0x6f,0x1b,0xfe,0x8c,0x5e,0xf9,0x7d,0xd9,0xc2,0xbe,0x0f,0x6f,0xbd,0xa7,0x94,0x10,0x4e,0xe0,0x5a,0xbb,0xa3,0x40,0x9a,0x5a,0xad,0x10,0x97,0x92,0x3b,0xbd,0xa7,0x75,0x77,0xc6,0xa6,0xde,0x42,0x00,0x3b,0xf7,0xe4,0xf4,0xd7,0xdd,0xaa,0x31,0x1e,0x64,0xae,0x17,0x0a
+.byte 0x25,0xa0,0x94,0x5f,0x3c,0xbc,0x3d,0x00,0x00,0xd3,0xba,0x7b,0x98,0x81,0xe1,0xdf,0xba,0x60,0x08,0x2a,0xe5,0x66,0x08,0x3e,0xfa,0x81,0x0a,0x89,0x4e,0xe5,0x3b,0xc3,0xdf,0x21,0x9b,0x54,0xa3,0xb3,0xc3,0xc1,0xce,0xb4,0xaa,0x06,0xee,0x2e,0x34,0x55,0xcc,0x8b,0x0f,0xcd,0x1d,0x1b,0xd9,0x9e,0x59,0xf0,0x93,0xc9,0xba,0x35,0x5c,0x99
+.byte 0xf6,0x86,0x9e,0xe9,0xf8,0x84,0x80,0x05,0x76,0x6f,0x8b,0x38,0xb6,0xe0,0xdf,0x0c,0xb3,0xc7,0x6e,0x62,0x53,0xe4,0x69,0x0a,0xc1,0xcf,0x5b,0x84,0x75,0x78,0x56,0x35,0xa5,0x26,0xc6,0xae,0x76,0x2e,0xc8,0x29,0x8d,0x16,0xd1,0x4f,0x27,0x36,0x22,0x41,0x31,0xfb,0xbe,0xd0,0xf9,0x0a,0x06,0xbf,0x59,0x6e,0x06,0x20,0x0d,0x52,0x66,0x63
+.byte 0x38,0x2a,0xb6,0x15,0x0f,0x51,0x14,0x0b,0xd1,0x63,0x40,0x2a,0xfe,0x88,0x51,0x53,0x5d,0x82,0x4e,0x1b,0x91,0x30,0x7a,0x09,0xec,0xb6,0x53,0x10,0x87,0xba,0x34,0x1f,0x8a,0xf7,0x85,0x31,0x77,0x76,0xba,0x55,0x07,0x6b,0x80,0x5d,0x14,0x23,0x50,0xef,0x07,0x91,0xc5,0x71,0x3a,0x55,0x44,0x9d,0xbf,0xe6,0xab,0xde,0x7c,0xdd,0xe0,0xcb
+.byte 0xcc,0xc1,0x78,0xb4,0x8c,0xd1,0x35,0x73,0x80,0x9c,0x44,0xff,0xf8,0x8a,0xaa,0x9a,0x94,0xcf,0xc9,0x51,0xfc,0xa5,0x3d,0x86,0xd6,0x67,0x71,0x1b,0xdb,0x83,0xb2,0x67,0xb0,0x17,0xce,0x13,0x1b,0x7a,0x84,0xc8,0xaf,0x69,0x7e,0xf0,0xab,0xc5,0x8c,0x37,0x12,0x43,0x33,0x5f,0xaa,0xde,0xcf,0x4c,0x73,0x7f,0x6b,0x80,0x18,0x27,0x72,0x62
+.byte 0xe8,0x3d,0x1c,0x94,0x91,0xfa,0x33,0xef,0x13,0x94,0x7f,0xb6,0x53,0xe3,0xd7,0x73,0x05,0x3e,0xe8,0x45,0xde,0x1e,0x1d,0xa4,0x41,0x11,0x0a,0x7f,0x62,0x6e,0x9f,0x9f,0xec,0xe9,0x87,0xe0,0x5d,0xbb,0xbc,0x0b,0x37,0xa2,0xf3,0x68,0x8a,0x24,0xec,0x98,0xe5,0x5d,0xbf,0xa1,0x60,0x2b,0xc2,0x74,0x4b,0x8b,0x85,0x44,0x28,0x02,0xd5,0xb9
+.byte 0xae,0x00,0x37,0x1e,0x0b,0x46,0xe6,0x40,0xf1,0xdc,0xa0,0xfc,0xae,0x04,0x7f,0xb6,0x46,0xa3,0x22,0x79,0x92,0xda,0x89,0xa0,0x38,0xf0,0xa2,0x4a,0x76,0x79,0x0c,0x46,0x4d,0xa9,0xe6,0x75,0xff,0x01,0xb3,0xe4,0x13,0xc2,0x53,0xe9,0x6d,0x1f,0xdd,0x88,0xcf,0x10,0xf5,0x16,0xef,0x05,0x59,0x51,0x15,0x49,0x17,0xda,0xff,0x0e,0xb3,0xb9
+.byte 0xae,0x79,0xc6,0xb1,0x94,0x08,0x09,0x30,0x9f,0x2a,0xfd,0x55,0xc0,0x41,0x8c,0xe5,0x0e,0xee,0xc2,0xa0,0x05,0x36,0x66,0x8d,0x9a,0xcc,0xc9,0xeb,0x1d,0x34,0xc0,0x1a,0x29,0xc2,0xcd,0xb7,0x25,0xd3,0x83,0xf8,0x1e,0xa0,0xf4,0x50,0xd4,0x08,0x0d,0xcb,0x6a,0x2f,0xa5,0x8b,0x30,0x94,0x89,0xea,0x94,0x6c,0x00,0x7e,0x7f,0xb5,0x4d,0x61
+.byte 0xa7,0x9d,0x94,0xcc,0x14,0x8f,0x75,0x1f,0xef,0x2b,0xbe,0x37,0xdd,0x19,0x41,0x2e,0x90,0x36,0x27,0xa5,0xa9,0x6c,0x75,0x8c,0x2d,0xe3,0x97,0x74,0x91,0xf3,0xb8,0xcb,0xcb,0x74,0xba,0xf0,0x57,0x70,0x89,0xee,0x4d,0xc5,0xfe,0x3e,0x60,0xe3,0x5b,0x28,0x36,0x91,0x6f,0xcd,0x6c,0x33,0xb6,0x44,0x0c,0xce,0x81,0xe4,0xdb,0x84,0xbe,0x4e
+.byte 0xef,0xb8,0x75,0xf7,0x8b,0xb0,0xb7,0x0d,0x00,0x13,0x54,0x39,0xfd,0x9e,0x86,0x5c,0x59,0xd0,0x84,0x0f,0x97,0xc0,0xf8,0xfa,0x4a,0xcf,0x57,0xb8,0x24,0xf0,0xa8,0x40,0x70,0x9d,0xc4,0xe5,0xc7,0xc9,0xcb,0xb6,0xf4,0x0b,0xb5,0xcc,0xe0,0x90,0x2b,0x42,0x81,0xd6,0x59,0x2e,0x11,0xbd,0xe8,0xf5,0xef,0xa8,0x2b,0xdb,0x93,0x62,0x1e,0xef
+.byte 0x3a,0x5f,0xf5,0x47,0x15,0x1f,0x03,0x6f,0x40,0x85,0xff,0x50,0x89,0x2e,0x72,0x8f,0x5c,0x0d,0x61,0x84,0x8d,0x8a,0x8f,0x2a,0x47,0x7c,0x97,0xfe,0x8a,0x97,0x6c,0xd5,0x1c,0x97,0xfa,0x59,0xbe,0x2c,0x0f,0x4d,0x85,0x7f,0x18,0xe3,0xea,0xe8,0xde,0x5a,0xf3,0x67,0xe1,0x71,0x7e,0x81,0xa3,0x74,0x0d,0xf4,0x3d,0x5a,0xec,0xc1,0xcf,0x6f
+.byte 0x08,0x0f,0x5a,0x63,0x72,0x0b,0x46,0x5d,0x38,0x80,0xea,0xb7,0x12,0x5d,0xce,0x37,0x26,0xaa,0xd3,0x0d,0x93,0x4a,0x34,0x20,0xd5,0x51,0x54,0x1c,0x5e,0x53,0xa9,0xed,0x26,0x3c,0x29,0xaf,0xbe,0x73,0x34,0xa5,0xc3,0xbf,0x8c,0x8a,0xc3,0x30,0x89,0xaf,0xa9,0x2d,0x28,0x35,0x7d,0x6b,0x84,0x23,0x22,0xee,0x8c,0x82,0x04,0xbd,0x26,0x52
+.byte 0x26,0x73,0x76,0x05,0x35,0x0c,0xec,0xf7,0x54,0xb2,0x17,0x68,0xe9,0x68,0x67,0xbb,0x0d,0x98,0x19,0x32,0xa7,0xdb,0xf9,0xef,0x42,0xe7,0xc2,0xe2,0x39,0x9c,0xae,0xbb,0xdb,0x91,0x28,0x82,0x88,0x23,0x61,0x50,0x6d,0x61,0x39,0x73,0xf8,0x6a,0xee,0xf3,0xa9,0x2c,0x78,0x0d,0x5a,0xed,0xb1,0x08,0x8f,0x24,0xe5,0xb7,0xa4,0xdf,0x65,0x9a
+.byte 0x72,0x3a,0x39,0x9c,0xf4,0x43,0xdc,0x8a,0xa3,0x3d,0xb5,0x1e,0x7b,0xe5,0x83,0x11,0x07,0xab,0x62,0x7e,0xac,0xab,0x52,0x94,0x0b,0xaf,0xdf,0x54,0x18,0xf1,0xc0,0x9f,0x1c,0x33,0x02,0xd9,0x62,0xc3,0xcc,0xaf,0x32,0x09,0x35,0x77,0xad,0x72,0xd6,0xb5,0x2d,0xaf,0xf9,0x39,0xfb,0x95,0xbb,0xf9,0x84,0x80,0x84,0xc8,0xc6,0x6d,0xb5,0x79
+.byte 0x25,0xf4,0x6c,0x71,0x26,0xda,0x74,0x86,0xad,0x52,0x47,0x8b,0x46,0x32,0xf6,0x2c,0x89,0xdb,0x93,0x1f,0x46,0x83,0x91,0x19,0xd2,0x0c,0x29,0x97,0x5f,0xa9,0x2b,0x87,0x0c,0x87,0x89,0xe6,0x63,0xa1,0x36,0xfb,0xfa,0xb4,0xb8,0x8e,0x5f,0xe9,0x8f,0x62,0xd2,0x81,0x1d,0x7b,0xc6,0x14,0x37,0x56,0x73,0x64,0x3d,0x0a,0xfd,0xe5,0x94,0x01
+.byte 0x09,0xc8,0x0d,0xa8,0x92,0xda,0x43,0xc4,0x41,0xca,0x3c,0x27,0x2c,0xbb,0xc4,0xb2,0x77,0x13,0xa6,0xb0,0x0e,0x97,0x6a,0xb2,0x83,0xe5,0x5e,0xa3,0xc0,0xe8,0x5e,0x0b,0xe6,0x00,0x04,0x6c,0x1b,0xac,0x84,0xab,0xd3,0xac,0x5f,0x39,0xc2,0xf8,0xfd,0x66,0xf7,0x97,0xd7,0xb9,0x6b,0xd8,0x2a,0x49,0xf7,0x67,0xd8,0xd5,0xa4,0x89,0x57,0xa6
+.byte 0x8f,0x7c,0xcf,0xaf,0xfe,0x3c,0x92,0xc8,0x23,0x2c,0x26,0x83,0x86,0x16,0x97,0x34,0x71,0x3e,0x82,0x2b,0xc7,0x75,0x5a,0x59,0xb3,0x44,0xdd,0x4e,0xd4,0x6d,0x1b,0x9f,0x3c,0x35,0xc4,0xe4,0xf2,0x95,0xb6,0x90,0x95,0xa7,0xc4,0x03,0x10,0x7d,0x3d,0xeb,0x74,0x29,0xaa,0x0c,0xd3,0x27,0xcd,0x3a,0x85,0x3c,0x88,0xd5,0x9a,0x46,0x84,0x8e
+.byte 0x36,0xde,0xe3,0x6a,0x27,0xbf,0xc3,0xd0,0x3e,0xa3,0x0e,0x62,0x1f,0xdf,0x4c,0x02,0xa7,0x11,0x91,0xb0,0x6b,0x50,0xc1,0xe0,0x18,0x5a,0xc0,0x10,0xc7,0x1c,0xb6,0x36,0xac,0xe7,0x7d,0xad,0x34,0x63,0x4f,0x17,0xcc,0x41,0x30,0xec,0xd7,0x14,0xb9,0xfe,0x07,0x5c,0x3d,0xbe,0x08,0x77,0x5b,0xdf,0xa3,0x20,0x56,0x55,0xa2,0x8a,0xe7,0x0d
+.byte 0xf6,0xfc,0x91,0x37,0xb8,0x92,0x6c,0xd9,0x5c,0xb0,0xc2,0xf7,0xc0,0x38,0xfa,0x54,0xc6,0xa1,0xd3,0x4d,0xae,0x49,0x0d,0xd1,0xc0,0xef,0xbe,0x27,0xce,0x23,0x8e,0xf2,0x9b,0x68,0x02,0x67,0x8f,0x53,0x9d,0xf6,0x23,0x57,0x85,0xdd,0x8d,0xd7,0xcb,0x47,0xf1,0xd8,0x17,0xd8,0x46,0x72,0x28,0x4b,0xac,0x94,0xd3,0x5d,0x53,0x4f,0x06,0x19
+.byte 0xc6,0x0e,0x0b,0x9f,0x58,0xc6,0x3f,0xea,0x4e,0x83,0x5e,0xd3,0xcc,0x44,0x55,0xa3,0xc7,0x24,0x19,0xea,0x1b,0x18,0xc1,0x18,0x5f,0x21,0x67,0x73,0x32,0x4e,0x31,0x69,0x05,0x40,0x79,0x7c,0x05,0x13,0xdd,0x50,0xea,0xfa,0xc2,0x26,0xe2,0x33,0xff,0x34,0x0d,0xda,0x77,0x27,0xe0,0xe7,0xa6,0x7b,0x8e,0xcd,0xdb,0x92,0x48,0x3a,0x2d,0x52
+.byte 0xf5,0x59,0xca,0xc7,0x47,0xda,0xb7,0xc7,0x8c,0x37,0x5e,0x29,0x30,0xf5,0x57,0x74,0x8b,0x10,0xcb,0x20,0x31,0x4b,0x12,0xe3,0x84,0xd2,0xb2,0xc3,0xd0,0xe3,0x94,0x18,0xa2,0xdc,0x8f,0x4d,0xc3,0x0a,0x43,0x07,0x2c,0x6b,0x41,0x64,0xc0,0x35,0x8f,0x37,0x9b,0xd7,0x78,0xab,0xd0,0xdc,0x1f,0x77,0x55,0xab,0x71,0xc8,0x99,0x98,0x00,0x29
+.byte 0x1c,0xab,0x3c,0x5f,0x82,0x96,0xc2,0xc8,0x9b,0xd4,0x68,0x3f,0x3d,0xe6,0x5a,0x4c,0x1c,0x7b,0x51,0xa3,0x79,0xe8,0x0e,0x8a,0x78,0xdc,0x98,0x63,0x80,0x74,0x32,0x9d,0x7c,0x3a,0x79,0x54,0xa7,0x4c,0xa4,0x4e,0xfc,0xa5,0x8a,0xa4,0x19,0xce,0x84,0xbb,0x8a,0xb9,0x93,0x4a,0x2d,0x82,0x5d,0x1d,0xf8,0x2f,0x85,0xb3,0x90,0x32,0x61,0x6d
+.byte 0x13,0x33,0xac,0xbc,0x5d,0x3a,0x54,0x45,0x04,0x50,0x30,0x30,0xc7,0x58,0xbe,0xed,0xdd,0xa1,0xae,0x6d,0xe5,0xde,0xed,0x63,0x9f,0xd4,0x2b,0x8d,0x1f,0x69,0xde,0xda,0x55,0x3f,0x3b,0xe7,0xc8,0x73,0xc0,0x68,0x18,0x6a,0xb3,0xfb,0xce,0xaf,0x46,0x0a,0xcc,0x81,0xa8,0x96,0x6d,0xb6,0xa4,0x74,0xf3,0x8c,0x95,0x2d,0xa1,0xfe,0x09,0xb8
+.byte 0xdb,0x3c,0xcd,0xdc,0x5b,0x0e,0x2d,0xff,0x89,0x8a,0xfd,0x7a,0xe9,0x69,0x0b,0xdd,0x4e,0x9b,0x94,0x64,0xe4,0xb6,0x5d,0x69,0xef,0x9c,0xf6,0xe6,0x44,0x73,0xd5,0x86,0x47,0x63,0x77,0x3e,0x74,0xaa,0xf3,0x6b,0x1f,0x37,0xbf,0xef,0xa2,0xff,0x86,0x61,0x78,0xc4,0xb5,0xbd,0x5a,0x43,0x49,0x80,0x16,0xf2,0x4c,0xec,0x1e,0x07,0x0f,0x41
+.byte 0x60,0x6f,0x3a,0xd2,0xab,0x85,0xc0,0x5c,0xfc,0x9f,0x48,0xad,0x5e,0xe0,0x7d,0x66,0x8e,0x46,0xf1,0xc3,0xb0,0xbc,0x5e,0x3b,0x10,0x7c,0xfc,0xa3,0x27,0xbd,0x8f,0xae,0xd9,0x61,0x39,0xbf,0xca,0x27,0xbb,0xe7,0xda,0x59,0xa8,0x63,0x38,0x16,0xd9,0xb5,0xa6,0xd9,0x1c,0x2b,0xa1,0x42,0xec,0x50,0xd7,0x63,0x09,0x22,0xe0,0x0c,0xb8,0xec
+.byte 0x12,0x9b,0xdb,0x8a,0xd3,0x02,0xcf,0x32,0xa9,0x88,0xa4,0x31,0xc8,0xa9,0xf4,0x03,0xf2,0x9d,0xe1,0x41,0xf0,0x0f,0x23,0x65,0xa8,0x99,0x55,0x87,0xf2,0x17,0x66,0xf0,0x94,0xe8,0xe9,0xb6,0xfd,0x10,0xb9,0x55,0xf4,0xda,0x06,0x7a,0xbe,0xe2,0xd3,0xfa,0xb8,0xf7,0x85,0xdf,0xee,0x39,0xdc,0x0f,0xda,0x87,0xf5,0x66,0xd8,0x1b,0x5c,0x0c
+.byte 0x13,0xe8,0xa2,0xcd,0xdf,0x47,0x33,0xd7,0xf4,0x5c,0x79,0xc7,0xf4,0x68,0xe4,0x2d,0xa1,0xde,0x5c,0x06,0x1c,0x85,0xf1,0x2a,0xf9,0x73,0x44,0xbc,0xd3,0x57,0x4f,0x0f,0xcd,0xcc,0x40,0xeb,0x9d,0x35,0x8e,0xdf,0x1d,0x4a,0x61,0xd0,0x66,0xb5,0x16,0xce,0x45,0xc0,0xbf,0x01,0xe3,0xb2,0x51,0xba,0x53,0x18,0x2a,0xff,0x19,0xea,0x41,0xa2
+.byte 0xac,0x0b,0x50,0xd3,0xc1,0x6a,0x9c,0xb0,0x34,0x6f,0xa0,0xcb,0xc7,0xc6,0x79,0x5d,0x17,0x3a,0x4c,0xa3,0x16,0xdc,0xac,0x10,0xf0,0x24,0xad,0x9a,0x5b,0xa9,0x7e,0x45,0xcd,0xe9,0xad,0x87,0x04,0xbc,0x2a,0x05,0x59,0xd1,0xdb,0x86,0x22,0x40,0xdf,0xb1,0xff,0x8d,0x3c,0xf8,0x6a,0xf3,0xcb,0x60,0xf9,0x35,0xa6,0x42,0x81,0xcb,0x0f,0x7c
+.byte 0xf7,0x24,0x3b,0x0c,0x94,0x32,0xd9,0xec,0xcf,0xd1,0x31,0x3e,0x3e,0xeb,0xa9,0xf2,0x1f,0x2d,0xa7,0x89,0xf7,0x67,0x7d,0x90,0x9d,0x40,0xf2,0xdb,0x07,0x8f,0xb8,0x6f,0xfd,0x78,0x6e,0xd0,0x9e,0xd5,0x7d,0xb0,0x7d,0x65,0xdc,0x6e,0x50,0xec,0x7a,0x5c,0x2c,0x3e,0x6f,0x64,0xa3,0x10,0x34,0xf7,0x71,0xc8,0x82,0xb6,0x96,0xb8,0xb1,0x2a
+.byte 0xb4,0x03,0x95,0x75,0x90,0xac,0x6c,0x81,0x17,0x97,0x06,0xd0,0xb8,0xc5,0x98,0xc5,0x9e,0x46,0x07,0x13,0x02,0x9e,0x47,0x69,0xba,0x85,0x2d,0x09,0x86,0x50,0xe4,0x76,0xb1,0xa2,0xbe,0x8b,0x91,0x6b,0x3b,0x76,0xa3,0xb7,0xf5,0x7f,0xfe,0xf1,0xa4,0xf3,0xc3,0x53,0x64,0xef,0x97,0x86,0x96,0x8b,0xc4,0xae,0x06,0x8b,0xe8,0x3c,0xdc,0xff
+.byte 0xfa,0xad,0xcb,0xcb,0x53,0x15,0xf2,0xcc,0x9f,0x48,0xf9,0x57,0x6a,0xcd,0xb2,0xee,0x46,0xc0,0xbf,0x82,0x58,0x60,0xda,0x2f,0xbd,0xde,0xc7,0x41,0xcb,0xf1,0x38,0x56,0x9d,0x38,0x38,0x3d,0xea,0x5e,0x38,0xf1,0xd0,0x02,0x35,0xee,0x4c,0x2f,0x1d,0x19,0xbd,0x08,0x01,0xc3,0x8f,0x75,0xe2,0xf3,0x93,0xbb,0x76,0x6b,0xd7,0x87,0x76,0x7f
+.byte 0x3b,0x29,0x08,0x9f,0x3a,0xa5,0x44,0x96,0x5a,0xb3,0x78,0xa9,0xbe,0xf7,0x5d,0xda,0x06,0x37,0x98,0x5d,0xbe,0x6e,0xec,0x58,0x53,0xd1,0xa5,0xd7,0x7a,0x16,0xb1,0x59,0x98,0x42,0x37,0x76,0x1b,0xd6,0x2e,0xa7,0xdc,0x45,0xa6,0x9c,0x9c,0x99,0x24,0x0e,0x22,0xae,0x94,0x65,0xeb,0x4e,0x64,0xc3,0xb0,0xac,0x19,0x41,0xf1,0x62,0x65,0xb2
+.byte 0x35,0xf5,0x2f,0xdb,0xd2,0xf0,0x78,0x19,0x35,0x04,0x6f,0x9c,0xf4,0xaf,0x81,0x68,0x4f,0x8b,0x85,0xfa,0x31,0x23,0x06,0xeb,0x37,0x86,0x43,0x51,0xb3,0xd2,0x2a,0xd7,0xd5,0xa9,0x33,0xba,0xfd,0xb5,0x0e,0x6d,0x9a,0x91,0xf9,0xe7,0x27,0xb7,0xff,0xe6,0xe7,0x34,0xc5,0x1a,0xa3,0x45,0x3b,0x71,0x34,0x87,0x7e,0xe7,0xab,0x74,0xc5,0xff
+.byte 0xeb,0x23,0x8f,0x3f,0x5d,0x1c,0x91,0x47,0xeb,0x3e,0x5f,0x5a,0xa6,0x5a,0xde,0xa9,0x5f,0xf4,0x8f,0x95,0xc6,0x25,0x3c,0xd5,0xaf,0xfd,0x4d,0x33,0x68,0xe1,0xa3,0x51,0x1b,0x07,0xad,0xb9,0xec,0xf1,0x50,0x51,0xbf,0xeb,0xe8,0x58,0x2a,0x50,0x0e,0x9d,0xc2,0x8a,0x83,0x8c,0xb0,0xb8,0xde,0x1d,0x7b,0x0f,0xff,0xfc,0xfc,0x31,0xe5,0x62
+.byte 0x40,0xc8,0x28,0x30,0x31,0xc9,0x82,0xab,0xbe,0x50,0xe5,0xfe,0x1f,0x49,0x17,0xf9,0xea,0x23,0xc7,0x6d,0x8d,0x63,0xc3,0x70,0x40,0x32,0x0b,0x48,0x7a,0xd9,0x03,0x52,0x1b,0xf4,0x90,0xd6,0x6d,0xd2,0xfc,0xec,0x24,0x7f,0x21,0x2e,0xd4,0xb5,0x60,0x44,0xd9,0x83,0xb0,0x3e,0x75,0x8a,0x6a,0x09,0xab,0xa8,0x4f,0x48,0x3c,0x2b,0x89,0x30
+.byte 0x29,0xdb,0x1a,0x8e,0x68,0xe4,0x89,0xed,0x10,0xe8,0x46,0xa7,0xf9,0x5f,0x7d,0x42,0xe0,0x8d,0xbc,0x3d,0x4d,0xd8,0x06,0x4a,0xf9,0xbb,0x97,0xa7,0xdb,0x24,0x0b,0xfc,0x49,0x92,0x5d,0x80,0xf8,0xed,0x57,0xc7,0x1e,0x82,0xed,0x41,0xb8,0xfd,0x71,0xb9,0xa5,0x11,0x52,0xdd,0x1e,0xa4,0xf1,0x02,0xc7,0x54,0x7c,0xdc,0x37,0x9f,0xfe,0x37
+.byte 0xe8,0xa5,0xcf,0xb0,0x3d,0x25,0x3f,0x24,0xfe,0xf2,0x63,0x97,0x3c,0x13,0xdc,0x31,0x78,0x07,0xf1,0x8e,0xee,0xc6,0x00,0xf8,0xfd,0x84,0x53,0x4d,0x92,0xa1,0xef,0xd0,0xb1,0x12,0x0a,0x12,0x91,0xeb,0x52,0xdd,0x6e,0x15,0x98,0xd2,0xe1,0x53,0x7a,0x0e,0x02,0x83,0xd3,0xd1,0xde,0x72,0x6e,0x5b,0x4b,0x8d,0x40,0xe3,0x2d,0x22,0x59,0x9d
+.byte 0xee,0xbe,0x43,0x18,0x62,0x8c,0x77,0x18,0x91,0xf5,0x9e,0xbc,0x3e,0x8b,0x77,0xb6,0xdb,0x5c,0xcb,0xcd,0xdb,0x36,0xea,0xf5,0x1d,0x9b,0xa7,0x13,0xef,0xda,0xd0,0xe8,0xd8,0xb2,0x4c,0xc6,0x19,0x3d,0x77,0x2d,0x0d,0xad,0xe4,0x32,0x24,0xe9,0xd4,0x7f,0x72,0x1d,0xc6,0x6e,0x83,0x7d,0xb8,0x62,0x64,0x9d,0x9a,0xd7,0x13,0x93,0x92,0xf1
+.byte 0x37,0x98,0xcf,0x44,0x66,0xab,0xd1,0x61,0x6c,0x08,0xa7,0x41,0x4e,0x37,0xc1,0x67,0xfb,0x7c,0x22,0x8f,0xbd,0x93,0xb2,0x09,0x13,0xa0,0x48,0x60,0xaf,0xda,0x73,0x2b,0xa3,0x2a,0xf3,0x4d,0x8e,0x22,0x5b,0x7a,0x32,0xe6,0xca,0xff,0x0e,0xa1,0x0a,0x15,0x33,0x31,0x50,0x71,0x1c,0x85,0x26,0x9b,0x19,0xf2,0xe3,0x69,0x4e,0x2d,0xff,0x79
+.byte 0x80,0xfe,0x2c,0x2f,0x7a,0x49,0x95,0xf3,0x0e,0x78,0xb1,0x0c,0x1c,0x45,0x59,0x68,0x2a,0x37,0xf2,0x48,0x6f,0xd9,0x32,0xf7,0xfc,0xdc,0xbe,0xe3,0xdd,0x61,0x17,0xc0,0x08,0x9d,0xbc,0x2d,0x8d,0x24,0x1c,0xbb,0x53,0xbe,0x37,0x59,0x30,0x87,0xa0,0x14,0xf5,0x08,0xcf,0xd1,0xcc,0x84,0xa7,0x0f,0x69,0xe0,0x77,0x8c,0x0d,0xdc,0x82,0xe5
+.byte 0x88,0x9a,0x58,0x05,0xe3,0x4f,0xdd,0x55,0x1e,0x6e,0x90,0xd5,0x3c,0xa6,0xa6,0x10,0x24,0xe5,0x58,0x97,0xdc,0x31,0x87,0x39,0xdc,0x3a,0xe6,0x24,0x64,0x23,0x45,0xd8,0x01,0x1b,0xf6,0x38,0x68,0x9e,0x62,0x53,0x00,0x97,0x71,0x04,0xb5,0x3b,0x54,0xdb,0xb5,0xcb,0x30,0x91,0x14,0xce,0x94,0xd5,0xe0,0x96,0x70,0x99,0xa5,0xed,0x69,0x32
+.byte 0xc7,0xb7,0x14,0xff,0xc0,0xde,0x19,0x5d,0x31,0xdb,0xa7,0xc0,0x7a,0x94,0xec,0x60,0xfc,0x52,0x71,0x69,0x9b,0xd8,0xbe,0x97,0x0b,0xb5,0x70,0xa7,0x47,0x11,0x37,0x84,0xda,0x3c,0x23,0xfe,0xf2,0x53,0xad,0x55,0x71,0x1e,0x70,0x9b,0x7b,0x61,0x97,0xf8,0x71,0xc4,0xad,0x72,0x98,0x43,0x0c,0x33,0x30,0x2c,0xb2,0xd6,0x21,0x8d,0xbb,0x1b
+.byte 0x85,0x82,0x24,0x14,0x85,0x95,0x88,0xff,0x3f,0x8c,0x88,0x96,0xa0,0xf8,0xd7,0x36,0x78,0x37,0x6d,0x92,0x09,0x04,0x76,0x27,0xb9,0xd5,0xea,0x0f,0x07,0x9f,0xe1,0x49,0x0e,0xd1,0x9c,0x46,0xcd,0x2b,0x7a,0x57,0xb6,0x56,0x39,0xe5,0x59,0x6b,0x1b,0x39,0xbf,0x15,0x3b,0x56,0xf5,0xc2,0x08,0x96,0xf5,0x63,0x4c,0x31,0x33,0x65,0x8b,0x74
+.byte 0x4e,0xde,0xa8,0x20,0xe0,0x7c,0x27,0xee,0x91,0x74,0xe8,0x24,0xb3,0xcf,0xa3,0xd4,0xf1,0xb9,0x18,0x43,0x05,0x5d,0x13,0x36,0x82,0xd1,0xbf,0x16,0x89,0x48,0x83,0xf0,0xcc,0x5c,0xbb,0x75,0x7e,0x71,0xc0,0x73,0xd1,0xf5,0x00,0x38,0x7f,0x10,0x98,0xd6,0xb9,0x14,0xea,0xd3,0x3f,0x0f,0xe3,0x61,0x1a,0x5e,0x21,0xd0,0x11,0x58,0x68,0x47
+.byte 0xf2,0xe5,0xe9,0x65,0x9a,0xc1,0xf4,0xa0,0x98,0x8e,0x9f,0x7f,0xbe,0x7e,0xd0,0xb6,0x88,0x4e,0xce,0xc1,0x8b,0xd4,0xd3,0x93,0xb7,0xd8,0xf3,0x0b,0xf3,0x73,0xc9,0x08,0x2f,0xcf,0xd8,0xbd,0xa6,0x1d,0x7c,0xfa,0x44,0x82,0x9f,0x03,0xca,0x56,0x3b,0xbf,0x4d,0x1e,0xbc,0x06,0xc2,0x37,0xfb,0xde,0xd3,0xa9,0xe3,0xae,0x61,0xef,0x26,0x7d
+.byte 0xbd,0x2f,0xee,0x2d,0xe1,0x65,0x71,0x77,0xab,0x9c,0x96,0x4f,0x00,0xe2,0xde,0xd7,0x05,0x54,0x00,0xb6,0xaf,0x12,0x0c,0x79,0x1a,0xed,0x20,0x72,0xc7,0x3b,0x3a,0x10,0x15,0x74,0xff,0xbd,0xf8,0xaa,0x8f,0x3a,0x83,0x39,0x24,0xfa,0x53,0x2d,0xc3,0x61,0xfc,0x12,0x6b,0x54,0x33,0xbf,0x83,0xc9,0x59,0x00,0xf0,0xdc,0xa8,0x64,0xbc,0xb5
+.byte 0xc3,0x96,0x60,0x3e,0x7b,0xe2,0x08,0x19,0x92,0x17,0x80,0x9b,0x0c,0x09,0x49,0x68,0x8b,0x15,0xe3,0xce,0x0c,0xfa,0x0c,0x8b,0xf0,0xdc,0x58,0xb0,0x7b,0x82,0x85,0xd2,0x56,0x1c,0xfb,0xb5,0xd0,0x0e,0x0a,0x55,0x61,0xda,0xd8,0x20,0xc1,0x79,0x70,0x3c,0x69,0x8e,0x49,0x5f,0x1c,0xdb,0x22,0xb8,0xdd,0x4c,0x4f,0xca,0xe9,0x0f,0x9a,0x4e
+.byte 0xff,0x56,0xbc,0xcf,0x72,0x09,0xa6,0x41,0x38,0xf0,0x7d,0xe7,0x45,0x0a,0x71,0x2c,0x92,0xdd,0x21,0x17,0xb2,0x3b,0x31,0x3c,0x91,0x11,0x69,0x29,0x50,0x31,0xe6,0xa6,0x10,0xc7,0x35,0xe8,0x44,0xec,0x74,0xa3,0x7e,0xb6,0x34,0xe5,0xb7,0xba,0xdf,0x5b,0x2f,0x85,0x02,0x6c,0xb0,0x71,0xb1,0x43,0xff,0x0e,0x47,0x04,0x63,0x4d,0x5b,0x81
+.byte 0x81,0x28,0x8b,0x84,0x79,0xad,0x2a,0x45,0x00,0x1c,0x0c,0x9f,0xef,0x35,0xbb,0x6d,0xc5,0x6a,0x6b,0xef,0x2b,0xae,0x78,0x66,0x05,0x7a,0x61,0x4c,0xe9,0x5e,0xf7,0x95,0x66,0x7e,0x1a,0xa7,0xdf,0x4c,0x4d,0x7c,0x66,0xa5,0x38,0x84,0x86,0x8d,0x66,0xcc,0x7f,0x32,0xb2,0x9c,0xc5,0x0d,0x3d,0xb7,0xb1,0xa6,0xc5,0x80,0x68,0xaf,0x79,0x81
+.byte 0x15,0x8f,0xec,0x50,0x5c,0x1b,0x57,0x31,0xd2,0xb9,0x16,0x66,0xf8,0x16,0xfd,0xcd,0xc7,0xa8,0x84,0x6f,0x35,0xea,0x3f,0xa4,0x72,0x8d,0xad,0xf4,0xd1,0x14,0x46,0xcc,0x06,0xed,0x71,0x39,0x07,0x99,0x28,0xc8,0xf9,0xc4,0xc2,0xec,0xde,0xb8,0x92,0xae,0xc5,0xf8,0xb2,0x49,0xc9,0x32,0x58,0xec,0x9f,0xb0,0x59,0xaf,0x49,0xef,0xe8,0x0d
+.byte 0x4c,0x56,0x8d,0xf7,0x57,0xb0,0x09,0xbe,0xc2,0x6a,0x62,0xc4,0x87,0xf3,0x20,0x07,0xc9,0xe3,0x3b,0x31,0xcc,0x8d,0xcf,0x5d,0x18,0x00,0x2a,0x9f,0xde,0x80,0x1a,0x7e,0x95,0x93,0xd1,0xbd,0xe6,0xd4,0x69,0x37,0x96,0xbb,0x70,0xc5,0x3c,0x87,0x8f,0xff,0x95,0x97,0xfe,0x95,0x56,0x7b,0xba,0x03,0x3d,0x29,0x0f,0xdb,0xd0,0x65,0x4f,0xf8
+.byte 0xa8,0xf3,0x42,0x09,0xb5,0x81,0x34,0xc6,0xa9,0x60,0xb9,0xef,0x3e,0x9d,0xc5,0x42,0x1e,0x79,0x5d,0x2b,0xf2,0x46,0x0d,0xeb,0x88,0x84,0x8f,0xad,0x60,0x69,0x57,0x49,0x33,0xb4,0xdd,0xfe,0x10,0x65,0x65,0x51,0xaf,0x68,0xa0,0xce,0xbd,0xe1,0x6e,0x03,0xe1,0x5f,0xba,0x3f,0x36,0xca,0xed,0x20,0x95,0xfa,0xff,0x3c,0x65,0xa8,0xb1,0x6b
+.byte 0xc5,0x91,0xa0,0xd5,0x36,0x38,0x1c,0x38,0xe9,0x1d,0x1b,0x67,0x4c,0x17,0xd3,0x29,0x92,0xa2,0x27,0x76,0x3d,0xe2,0x26,0x37,0x2a,0x2c,0xf6,0xee,0x64,0x40,0x8a,0x1c,0x2b,0xc1,0xd3,0x28,0xd0,0xcf,0x2d,0xc2,0x45,0xf4,0x37,0x5a,0x63,0xfb,0x18,0x67,0x01,0x0a,0xe8,0xe2,0x41,0xf7,0x15,0x47,0xa7,0xe9,0xc8,0x05,0xbc,0xc7,0x8f,0xf0
+.byte 0xc3,0xc5,0x9a,0x4e,0x0d,0x7b,0xf0,0x20,0x8c,0x21,0x49,0x99,0x0d,0xf7,0x34,0x84,0x35,0xfb,0x11,0x33,0xd6,0x46,0x14,0x3c,0xf1,0xb3,0x37,0xac,0x75,0x63,0xe7,0x1a,0x19,0xa4,0x49,0xf2,0x58,0x1d,0x56,0x55,0x64,0x46,0x25,0xff,0x7d,0x90,0x34,0x21,0x5d,0x00,0xa1,0xa8,0xaa,0xe0,0x93,0xe7,0xda,0x11,0x34,0x1d,0xa3,0x0c,0x67,0xae
+.byte 0xf5,0x60,0x72,0x14,0xdf,0x08,0xf6,0x72,0x3e,0x48,0x41,0x3d,0x00,0x58,0xfb,0x0c,0x15,0x80,0x2d,0xd9,0x72,0x47,0xa6,0x20,0x6a,0x74,0x9e,0x06,0xb9,0xac,0x68,0x3a,0xe7,0xf1,0x19,0xb8,0x0b,0x66,0x07,0x4d,0xa0,0xb5,0xab,0xea,0x70,0xa1,0xdf,0x41,0x76,0x85,0x18,0x5b,0x6f,0x78,0x5a,0x5d,0x08,0xe0,0x1b,0xd8,0x06,0x73,0x1e,0x16
+.byte 0xcb,0xdb,0x02,0xf8,0x96,0x64,0x65,0xc5,0xc1,0x52,0xd4,0xd8,0xb3,0x1e,0xd4,0x09,0xfd,0xa7,0x30,0x41,0x5a,0xce,0x53,0x4d,0x11,0xc8,0xdd,0x13,0x50,0xd5,0x2e,0xa0,0xe6,0x48,0x49,0x31,0x4b,0x1d,0xce,0xfc,0x42,0xed,0x8f,0xc8,0xb3,0x0a,0xae,0x1d,0x4c,0x1e,0x4f,0x39,0xa4,0x37,0xc8,0x54,0xdf,0x40,0xa6,0x42,0x61,0x7d,0x34,0xd4
+.byte 0x75,0x0a,0x9f,0xf0,0x33,0x54,0xf3,0xc4,0xdc,0x4e,0x2f,0x81,0xc2,0x20,0xaa,0x4f,0xa0,0xae,0xa6,0xb8,0x50,0xf8,0x45,0xf1,0xf2,0xd1,0xd2,0xcf,0xc8,0xf0,0xf4,0x54,0x37,0xdc,0xfb,0x13,0xdf,0x38,0xc2,0x3f,0xe0,0x59,0xb5,0x9a,0x0f,0x27,0x87,0xd4,0xd3,0xdc,0xfd,0xda,0x1d,0xfa,0xdd,0x12,0xe0,0x7f,0x34,0x01,0xde,0x28,0xf5,0x0e
+.byte 0xff,0x59,0xc7,0xbd,0x6a,0xe4,0x0c,0x85,0x7b,0x87,0xf9,0xd7,0xe2,0xed,0xb2,0xf7,0xb7,0x13,0xfb,0xfc,0x4d,0x25,0x52,0xfd,0x23,0x6b,0x10,0xd0,0x80,0xd8,0xbd,0xbd,0xf0,0x87,0xfc,0x38,0x85,0x83,0x20,0x5f,0x7c,0x26,0x14,0x93,0xd3,0xe1,0xdc,0xa4,0xda,0xa7,0xf9,0xfd,0x6c,0x9a,0x2b,0x75,0x82,0xf1,0x9f,0x1b,0x0c,0x43,0xd4,0x2d
+.byte 0x5b,0x0c,0x54,0x7e,0x61,0x24,0x8e,0x50,0x25,0xd8,0x54,0xfd,0x30,0xec,0x4c,0xa8,0xb6,0xf0,0x35,0x67,0xf7,0xe4,0x3c,0xfd,0xc8,0x40,0xf4,0x2d,0xc5,0x4d,0xc3,0x29,0xc2,0x88,0x60,0xab,0xd9,0x2a,0xe8,0x31,0xcc,0x0c,0x9f,0x97,0xa8,0x2e,0xaa,0xa5,0xb6,0xee,0x3c,0x71,0xa9,0xff,0x90,0xb4,0x43,0x2e,0x16,0x80,0x8c,0xfe,0xb5,0x7a
+.byte 0x40,0x58,0xd5,0x98,0x7e,0xca,0xaf,0x95,0xee,0x00,0x26,0x8d,0x5b,0xba,0x33,0xee,0x35,0xb5,0x9b,0xf8,0x08,0x1e,0x15,0x2d,0x01,0xb1,0x83,0xa6,0x57,0x58,0xd1,0xf3,0xa4,0xf1,0x3a,0x00,0xf4,0x40,0xee,0x35,0x3a,0x20,0xc2,0x13,0x1e,0xda,0x32,0xc2,0x35,0x74,0x29,0xce,0x51,0x3f,0xec,0xb2,0xd7,0x23,0xa7,0xc6,0xef,0x70,0xb9,0x88
+.byte 0x6f,0xa8,0xf5,0x5b,0xff,0xc5,0xf5,0xb4,0x3b,0x12,0x75,0x20,0xbf,0x61,0x8a,0xb1,0xae,0x01,0x9b,0x17,0xf4,0xf3,0x2d,0xfb,0x44,0xe8,0xac,0x29,0x81,0xc2,0x6d,0x50,0x05,0x11,0xd9,0x43,0xf8,0xc7,0x58,0x5d,0xbc,0x2d,0xc0,0x83,0xd2,0x81,0x41,0x1c,0x46,0x62,0x60,0x6e,0x65,0x52,0x4b,0x1c,0x88,0x72,0x1b,0x0e,0x8e,0x7d,0xa2,0xb5
+.byte 0x4e,0x28,0x32,0xf2,0xb1,0xfa,0xf1,0x4b,0xc5,0x85,0x95,0x2c,0x08,0x78,0x85,0x68,0xe5,0x20,0x23,0x8b,0xc4,0xf5,0xb2,0xdb,0xc1,0xdd,0xe5,0x69,0xa4,0x97,0xa9,0x6c,0x2e,0x3a,0x25,0x1c,0x24,0x54,0x97,0x3e,0x8d,0x61,0x61,0xa3,0x60,0xf5,0xd2,0x4e,0x90,0x25,0x06,0x09,0x31,0x7b,0x96,0xce,0xcc,0xb7,0xbc,0x63,0x9f,0x04,0x7d,0xec
+.byte 0xa1,0x4a,0x65,0xd3,0x26,0xe1,0xbf,0xf9,0x88,0xea,0x5c,0x5d,0xfe,0xe9,0x60,0x77,0xbd,0xf2,0xa0,0x11,0x91,0x24,0xca,0xa1,0x0d,0x05,0x7b,0xe2,0x7d,0x22,0x2e,0xd2,0xc9,0x4b,0x78,0xce,0x0c,0x7b,0x49,0xaf,0xd6,0x59,0x5f,0xb4,0xbd,0x2e,0x4a,0x22,0xcb,0x5d,0x1c,0xd5,0xde,0xea,0x86,0x74,0xd5,0x15,0x52,0x59,0xfc,0x3d,0x7b,0x1c
+.byte 0x3f,0x14,0xec,0xf2,0xc8,0x3c,0x88,0xbf,0x89,0xd5,0x23,0xc3,0x94,0x3c,0x28,0x04,0x91,0x6c,0x36,0x35,0x4b,0x75,0xf8,0xdc,0xf3,0xff,0xba,0x8c,0xa4,0xc7,0x85,0xc5,0x1a,0x30,0x4b,0x7c,0xc5,0x2f,0xb9,0x2a,0x14,0xaa,0x65,0xe3,0x92,0xdc,0xe1,0xed,0x3f,0xb6,0xff,0x0e,0x74,0xe0,0xb3,0xc9,0x4b,0xd1,0x96,0xfc,0x49,0x72,0xbe,0xb0
+.byte 0xc8,0x4a,0xd5,0xf0,0xb3,0x58,0x29,0x35,0x97,0xd4,0x5c,0xc7,0x0b,0x27,0x1d,0x14,0xdb,0xb7,0x5c,0x7e,0x6d,0xc1,0x56,0xa9,0x80,0x72,0x7d,0x75,0xc2,0x2f,0x07,0x28,0xb4,0xff,0xef,0xa7,0x34,0xed,0x31,0x44,0x85,0xe6,0xc3,0xa4,0x5f,0xe2,0xe8,0xab,0xd1,0x59,0xe7,0x32,0x20,0xd1,0xcc,0xef,0x6f,0xe1,0x10,0x89,0x6c,0x0c,0xf3,0x5f
+.byte 0xe8,0xc7,0x1c,0x3b,0xeb,0x3e,0xa5,0x53,0x2d,0x48,0x64,0x92,0xa0,0xec,0xf3,0x75,0x5b,0x5b,0xe2,0x83,0x87,0x04,0xa7,0xd8,0x1b,0x44,0xfb,0x42,0xee,0xd8,0xf2,0x98,0xff,0x30,0xc8,0x09,0xf8,0x1a,0x95,0x46,0x2d,0xe7,0x43,0x10,0x90,0xf4,0x2c,0x8f,0x0b,0x60,0x6d,0xeb,0xbf,0x19,0xc1,0x9d,0x5c,0xc0,0xff,0xb1,0x86,0xbc,0x01,0x73
+.byte 0x35,0x1f,0xd8,0xf4,0xa1,0xd4,0x7f,0x2d,0x1b,0xf9,0xa6,0x78,0x1a,0x2e,0x2c,0xe2,0xcc,0x8b,0x5f,0xbb,0xb9,0x80,0x31,0x32,0xa5,0x5d,0x70,0x59,0xae,0xe3,0xac,0xab,0xde,0x38,0x09,0x07,0x57,0x5f,0xbf,0xe8,0xa0,0xb8,0xd0,0x03,0xac,0x02,0x0d,0x7f,0x7e,0x0c,0xd2,0xcf,0x46,0x01,0x07,0x9f,0x16,0xf6,0x2b,0x94,0xaf,0xae,0x66,0x09
+.byte 0xca,0x4c,0x5f,0x37,0x53,0xa6,0x50,0x82,0x3a,0x0a,0x7b,0xb3,0x52,0x2e,0x0f,0xe4,0x64,0xab,0x40,0x21,0x2d,0xb7,0x20,0x9b,0xe3,0x2f,0xec,0x2b,0xb3,0x31,0x60,0x51,0x2e,0xb6,0x68,0xac,0xae,0xee,0x2d,0x28,0x5b,0xe0,0xa7,0x85,0xab,0x95,0xba,0x53,0x8c,0xc0,0xf8,0x16,0x8f,0x42,0x01,0xef,0x00,0x32,0x44,0x8e,0x41,0xc9,0x05,0x5b
+.byte 0xe0,0x3f,0xe1,0xd8,0xd4,0x97,0x8e,0xa0,0x14,0x84,0xce,0x5c,0xef,0xbe,0xa4,0xae,0x18,0x91,0xd9,0x48,0x9b,0xc3,0x7a,0x8f,0xfb,0xb3,0x3e,0xa9,0x87,0x74,0x84,0xd2,0xc6,0x7c,0xc9,0xce,0x01,0xa5,0xcc,0xff,0x5a,0xe8,0x94,0x98,0x54,0x2a,0x6e,0xd9,0x58,0x75,0xd4,0xdd,0x6c,0x7d,0x83,0x32,0xc9,0x4e,0x35,0x2c,0x51,0x26,0x68,0x1f
+.byte 0x95,0x20,0x82,0x54,0x0a,0xad,0x5e,0xe2,0xba,0xf9,0xa3,0x54,0x24,0x93,0x4a,0x62,0xff,0x28,0x05,0xd2,0x22,0x62,0x82,0xd4,0x2d,0xe2,0xec,0x66,0xc5,0xee,0x63,0xd0,0xf6,0x93,0xa8,0x37,0xbf,0xdd,0xe0,0x95,0x0b,0x19,0xa1,0x9d,0x9a,0xf8,0x94,0x1a,0x3a,0x50,0x9e,0x66,0x75,0x8c,0x25,0xbd,0x18,0xb0,0x58,0x76,0x7f,0x2d,0x3d,0x06
+.byte 0x02,0xb3,0xcf,0xa3,0x14,0x6e,0xe7,0xc8,0xcd,0xe6,0xbe,0xae,0x92,0xd6,0xa2,0xfe,0x12,0xf0,0xdf,0x9f,0x9e,0xad,0x77,0x77,0xfb,0xfc,0x36,0xb7,0x82,0x9c,0xf1,0x51,0xc2,0x58,0xa0,0xf3,0xa0,0xd6,0x6e,0x64,0x28,0xac,0x09,0x8f,0x7b,0xef,0x19,0x87,0x76,0xb9,0x4e,0xca,0x1f,0x05,0xb6,0x00,0x4a,0x14,0x83,0xaf,0xff,0xd9,0xa1,0xc6
+.byte 0x0f,0x98,0x3a,0xcf,0x85,0x18,0xea,0xa6,0x9a,0x1e,0xae,0x7c,0xaa,0xae,0xef,0x89,0x5e,0x14,0x5d,0x2f,0x73,0x8f,0xd1,0xf0,0x77,0xcd,0x45,0x92,0x7f,0xee,0xb9,0x7c,0xc2,0x3c,0xff,0x56,0x56,0xa5,0xa5,0x49,0xe4,0x20,0xd6,0xa2,0xb6,0xe4,0xfc,0x86,0x53,0xce,0x9e,0x2b,0x7b,0xcb,0xcf,0x6a,0xd5,0x62,0xb7,0x34,0x0e,0x39,0xe2,0xaa
+.byte 0x1c,0x24,0x30,0x71,0x94,0xb3,0x57,0xd8,0xe8,0xd4,0xc5,0x4f,0x33,0x2c,0x73,0x7e,0x48,0xba,0xb3,0x55,0x84,0x6d,0x10,0xcf,0x8f,0xf2,0xb6,0xdb,0x4e,0xcf,0x49,0x08,0xf6,0x5a,0x3c,0x7e,0xef,0x3f,0x5c,0x11,0x09,0xfe,0x26,0xfb,0xff,0x30,0xcb,0x81,0x12,0xea,0x1e,0xa9,0x6e,0xf8,0xea,0x4f,0x92,0x2c,0x23,0x99,0x35,0xa5,0x59,0xca
+.byte 0x1d,0x66,0x72,0xad,0x5b,0x7c,0xb3,0x4a,0x7c,0x76,0x4c,0xf6,0xc1,0xec,0x68,0x5f,0x2c,0x17,0xbe,0x92,0xe1,0xa1,0xee,0x40,0x24,0x25,0x6b,0xc5,0x0b,0x6f,0x06,0xc0,0x05,0x8c,0x23,0x24,0x76,0xea,0xe9,0xb9,0xa1,0x3d,0x59,0x15,0xe7,0x65,0x47,0x5a,0x75,0x9b,0xc8,0x7b,0x86,0x97,0xf4,0x4a,0xa3,0xec,0x54,0x0e,0x66,0xef,0xda,0x41
+.byte 0xb8,0x3b,0xa6,0x86,0x63,0xe1,0x4e,0x89,0x92,0x40,0xf4,0x8b,0x32,0x47,0x3b,0x4b,0xb4,0xe6,0xd8,0x4b,0x1c,0xac,0x03,0xab,0xde,0x2e,0x63,0x96,0x3f,0x27,0xa1,0x32,0x11,0x35,0x24,0x6a,0xe9,0x0b,0x73,0x61,0x4e,0xd8,0xdc,0x91,0x98,0x01,0x8a,0x0d,0x61,0xec,0x39,0xbe,0x3b,0xb9,0x78,0x77,0xea,0xaa,0xa2,0x12,0x20,0x92,0x98,0x16
+.byte 0x27,0x3b,0xd1,0xfa,0x59,0xef,0x81,0x38,0x9f,0x42,0xe8,0xb4,0xab,0x4f,0x26,0x9a,0xe7,0x0b,0x05,0x03,0xfa,0xe1,0xe1,0x3d,0x45,0xac,0x7d,0x40,0xcc,0x2f,0xf2,0xb0,0x33,0x42,0x14,0xbd,0x91,0x3e,0xe1,0xb7,0x17,0x25,0xc3,0x92,0xcb,0x9e,0x44,0x1e,0x13,0x93,0x98,0x1f,0x96,0x64,0x3a,0xaa,0x53,0x9a,0x18,0xc0,0x34,0x3c,0x47,0x94
+.byte 0x14,0x70,0x67,0x76,0x2a,0x82,0xd3,0x6a,0x18,0x13,0xe7,0x01,0x8d,0x97,0x52,0x51,0x8e,0x08,0xde,0x44,0xb0,0x74,0x07,0x58,0x35,0xc2,0x29,0xb5,0xd7,0x00,0x46,0x31,0x34,0xd7,0x1f,0xdd,0xaa,0x5c,0x27,0xc7,0x37,0x71,0xe8,0xbe,0xad,0x89,0xf1,0xb2,0xd1,0x46,0x33,0x0c,0x2f,0x26,0x21,0x5e,0xc9,0xda,0x25,0xcd,0xd0,0x17,0x23,0x87
+.byte 0x15,0xc2,0xa0,0x1a,0x9f,0x6e,0xfb,0x63,0xe9,0x69,0xdf,0x79,0x18,0x33,0x2f,0x47,0xca,0x54,0x23,0x7e,0x4f,0x6e,0x38,0x06,0x99,0xfb,0xcd,0x22,0xdb,0x4b,0x3f,0x8a,0x05,0x2e,0x5c,0x56,0x65,0xb7,0xab,0x57,0x8b,0xdd,0x28,0xab,0x7e,0x77,0x32,0x0f,0xc6,0x3c,0xf3,0xde,0x43,0xb0,0x13,0x3b,0xbd,0x28,0x3a,0x8b,0xd5,0x6b,0x1d,0x5d
+.byte 0x20,0x1a,0x5f,0xa6,0x01,0xed,0x88,0x7f,0x87,0x55,0x38,0xc2,0x0d,0x03,0x6c,0x41,0x6a,0x43,0xdf,0x09,0xf3,0x58,0x69,0x13,0xa1,0xd6,0x39,0x0c,0x8e,0x8f,0x40,0x67,0xe8,0x0e,0x9b,0x9b,0x42,0x30,0xd7,0xae,0x04,0x75,0x66,0xfb,0x4a,0xa7,0xe0,0xe9,0xea,0x6d,0x28,0x4f,0xc0,0x5c,0xd4,0xd4,0xb7,0x60,0x5a,0x35,0xc1,0xe8,0x5f,0xc3
+.byte 0x4f,0x7a,0x5d,0x8d,0xc2,0x29,0x6e,0x36,0x50,0x5b,0x82,0x63,0xf2,0xda,0x8d,0x02,0x61,0x09,0x69,0x0a,0x47,0x9d,0x58,0xf3,0xf6,0xe0,0xc0,0x09,0xd9,0x3b,0x8d,0xf5,0xba,0xf6,0xc4,0xf0,0x65,0x89,0x7b,0xdd,0x93,0x6b,0x6e,0x21,0xa1,0x2a,0x66,0xe0,0x8f,0x62,0xb0,0x49,0x60,0xa3,0x48,0x42,0x62,0xcc,0x26,0x1f,0x59,0x3a,0x7b,0xa7
+.byte 0x82,0x10,0x5f,0xc6,0xf8,0xa2,0xc0,0x07,0x7b,0x26,0x26,0x11,0xe2,0x5b,0xb8,0x86,0xb7,0x66,0xcf,0x0a,0xcc,0x6f,0xe8,0x02,0x22,0x4c,0x13,0x75,0xdc,0x68,0xf0,0x7c,0x0c,0x46,0x9a,0xa2,0x4c,0xf5,0x50,0x3f,0xf9,0xbc,0x01,0xb1,0xa1,0x28,0x90,0x07,0x6b,0x17,0x69,0x89,0x7b,0xe5,0x0a,0xf7,0x7b,0xe1,0x94,0x30,0xfc,0xd3,0x8d,0xd3
+.byte 0x99,0x37,0x91,0xd5,0xdf,0x59,0x2a,0x4f,0xfe,0x6c,0x37,0x4b,0x78,0x2c,0xa9,0x28,0x6a,0x5c,0xd6,0xe1,0x0b,0xad,0xae,0x62,0x7c,0x09,0xb8,0x90,0x3f,0x29,0x37,0x7b,0x79,0xee,0x55,0x02,0x05,0xef,0x28,0xa2,0xc7,0x07,0x2b,0xe6,0xab,0x87,0x9d,0x8f,0x4c,0x0f,0xc1,0x75,0x5d,0x88,0x7f,0x26,0xe0,0x1e,0xf8,0x3f,0xb5,0x2a,0x6c,0xe6
+.byte 0x7f,0x85,0xae,0x55,0x7b,0x58,0x34,0x4c,0x81,0x05,0x21,0xa1,0x5e,0xd7,0xb6,0x20,0x6e,0xf9,0x60,0x15,0xa4,0xb2,0x8f,0x68,0xd2,0x23,0x9f,0xbf,0xfa,0x6a,0xcb,0x87,0x7d,0x41,0x4a,0xae,0x28,0x4f,0x9e,0xbb,0x69,0x1c,0x37,0xb2,0xc9,0xd2,0x21,0xa1,0x2b,0x6b,0x5d,0xff,0xd6,0xdb,0x8f,0x21,0xd9,0x17,0xd6,0xe6,0x74,0xf2,0x20,0x0e
+.byte 0x06,0xb5,0x0c,0xdc,0x74,0x4e,0x93,0xcb,0x27,0xc7,0x4b,0xf3,0xef,0x46,0xa8,0xf0,0x58,0x1c,0xa0,0x65,0x09,0x84,0xc7,0x2e,0xba,0x51,0xd9,0xd4,0x53,0x20,0xc7,0x20,0x85,0x93,0x2b,0xf3,0x42,0x93,0x7b,0x22,0x1c,0x8d,0x22,0x76,0xcf,0xde,0x6a,0xa1,0x76,0xea,0x65,0x20,0x2f,0x2e,0xdb,0x85,0xdd,0x73,0x43,0xf8,0xe0,0xe3,0x3a,0xe5
+.byte 0x02,0x57,0x96,0x54,0xbc,0xaf,0xa4,0xd5,0xda,0x9d,0x9d,0x8b,0x85,0x01,0x7c,0x72,0x03,0xfe,0x39,0x46,0xab,0x04,0xcc,0x62,0x71,0xf5,0xa5,0x67,0xd7,0xfc,0xc0,0xb6,0x95,0x74,0xdf,0x1c,0xfe,0x1c,0x5b,0x25,0xae,0x42,0x75,0x00,0x71,0x3c,0xec,0xfc,0x3c,0x7b,0x0f,0xec,0x44,0xc7,0xec,0x9b,0x86,0xf5,0x3d,0x47,0x15,0xf0,0x25,0xba
+.byte 0x43,0xc8,0x68,0x15,0x4f,0xeb,0x35,0x76,0x2d,0x04,0xb7,0x9b,0xb8,0xa7,0x0d,0xb3,0xb4,0xf2,0x93,0x85,0xb1,0xb8,0x81,0x7c,0xd6,0x5f,0xbd,0xc2,0xcc,0xf4,0x0e,0x98,0x2c,0x06,0x54,0x2f,0x5e,0x49,0x94,0x93,0x78,0xa0,0x0a,0x33,0x2e,0x3f,0xb2,0xa7,0x81,0xed,0xe9,0xb6,0xb5,0x86,0x4b,0xa5,0xc0,0x51,0x30,0x9d,0xe2,0x9f,0xc2,0x56
+.byte 0x92,0x6b,0x96,0xca,0xcb,0x65,0x5c,0x0e,0xf4,0x91,0x2b,0x89,0xf4,0x27,0x55,0x26,0xd7,0x7b,0x00,0x19,0x1f,0x67,0x4e,0x43,0x24,0x81,0x05,0xb7,0xc6,0x41,0x1a,0x39,0x3d,0x40,0x3e,0x8a,0x03,0x94,0x63,0x1b,0xb1,0x87,0xb6,0xe1,0x52,0xd0,0xe8,0xbb,0x0e,0x37,0x72,0xe5,0xde,0x86,0xc0,0xdf,0x5b,0xc2,0xc6,0x0a,0x67,0xa7,0x4c,0x03
+.byte 0xb6,0xd8,0x7f,0x1d,0xb3,0xe3,0x84,0xb7,0x5c,0x04,0x15,0xe0,0xd0,0xae,0x44,0xac,0x39,0xa5,0xa2,0x86,0xc8,0xad,0x27,0xa0,0x36,0xa1,0x6e,0xaa,0x87,0x7a,0x43,0xae,0xa0,0x45,0x1a,0xac,0x04,0xe2,0x55,0xf2,0x9a,0x97,0x67,0xfb,0x01,0x8f,0xb8,0x80,0x9c,0x27,0x1d,0xbe,0xa3,0xf1,0x6d,0x66,0xf2,0x1a,0x99,0x99,0xf6,0xa5,0xba,0x58
+.byte 0x28,0x58,0xb5,0x44,0x5b,0x38,0x4a,0x3f,0x37,0x85,0x7e,0x36,0x8e,0x16,0xb9,0x1e,0x0b,0xbf,0x7d,0x0a,0x0c,0x83,0x53,0x0d,0xcc,0x37,0xe1,0x42,0xbb,0x0d,0xfc,0x01,0x25,0x10,0xbe,0xb5,0x83,0x2f,0xa5,0x42,0x98,0xbc,0xd6,0x50,0x75,0xda,0x32,0x2b,0x3f,0xd6,0xc1,0x1a,0xe7,0x0b,0x80,0x07,0x6f,0xfe,0x77,0x9e,0xe9,0x1e,0x45,0x65
+.byte 0x68,0x92,0x34,0x8b,0xce,0xf3,0xcd,0x94,0x17,0xe0,0x41,0x92,0x96,0xb5,0xd1,0x98,0xd1,0x25,0xd1,0x3d,0x76,0x88,0x86,0xb1,0x01,0x80,0xc7,0xde,0x60,0x20,0xb8,0x03,0xe7,0x3f,0x44,0x39,0xb1,0xb8,0x19,0x53,0x5a,0xc6,0xa0,0x18,0x8e,0x0e,0xb6,0xfd,0x7e,0xe7,0x7e,0x8a,0xeb,0x4c,0x35,0x4a,0x0f,0x52,0x81,0x68,0x12,0xe4,0x46,0x2e
+.byte 0x20,0xb4,0x41,0x59,0xb3,0x16,0x02,0x9f,0xdb,0xe8,0xea,0xfd,0xe3,0x5d,0x14,0xd0,0x97,0x52,0x66,0xcb,0xb4,0x48,0xa3,0x05,0xab,0x73,0x8e,0x2c,0x46,0xc2,0x94,0xd5,0xc8,0x57,0xc4,0x13,0xa4,0x0b,0x7c,0x34,0xbf,0xb4,0x07,0x28,0x92,0xe2,0x1d,0x00,0xa6,0xf0,0xb0,0xbf,0xdd,0x5d,0x20,0x05,0x9f,0x53,0xcf,0x07,0xf7,0xe8,0x79,0x04
+.byte 0x57,0xd1,0xac,0x9c,0xdd,0xae,0xcd,0x8b,0x04,0x0a,0x2d,0x0a,0x0f,0x21,0x09,0xc8,0x0d,0xfa,0x23,0x26,0xe3,0xdb,0x84,0xc8,0x8e,0x9c,0x96,0x93,0x4f,0xcc,0x2f,0x96,0xed,0x04,0x91,0x0d,0xc7,0xbb,0x27,0xa3,0x6b,0x9d,0xe2,0x15,0x83,0x31,0x78,0xb5,0xb9,0x6d,0xb1,0x6c,0xa2,0x3e,0xf5,0x45,0x77,0xf4,0x96,0x3a,0xe6,0x10,0x08,0xfd
+.byte 0x23,0xcc,0xda,0x27,0x73,0x67,0xbb,0x8b,0x59,0xe2,0xcf,0xda,0x57,0xf9,0x17,0xeb,0xeb,0x98,0x39,0x48,0xbf,0x3d,0x5b,0x7b,0xc2,0x11,0x4b,0xd6,0xb6,0x8a,0x14,0xb3,0xf5,0xc3,0x18,0xff,0xde,0x62,0x98,0x4a,0x1d,0x6b,0x4e,0x00,0x4f,0x7d,0x2f,0x67,0xf4,0x22,0x1e,0xdb,0x69,0xd5,0x87,0xfd,0xee,0x97,0x56,0xd4,0x00,0x0c,0x9e,0x22
+.byte 0x11,0xda,0x8e,0x3b,0x91,0xad,0xf1,0xb6,0x0a,0xba,0xe7,0xc6,0x14,0x0e,0xc4,0x85,0x5f,0x7d,0x69,0x7d,0x73,0x9c,0x83,0x6a,0x69,0xef,0x10,0xb0,0xe6,0x33,0x32,0x0f,0xd8,0x54,0xa4,0x9d,0x39,0xaf,0xfc,0x6d,0x4f,0xeb,0x34,0x89,0x2e,0xb0,0xa1,0xcd,0xe1,0x5b,0xab,0xe1,0xff,0x82,0x85,0x6b,0x5e,0xa9,0x9e,0x43,0x02,0x0d,0x38,0x33
+.byte 0xe1,0xbc,0xa4,0x77,0x8a,0x5e,0x54,0xa8,0xcf,0xc9,0x76,0xcb,0x73,0x21,0x1f,0xa7,0x1e,0x5c,0x0a,0xd6,0xa2,0x36,0x6f,0x07,0xa1,0x6b,0x0d,0x5a,0x21,0x3a,0xc3,0xc0,0xcd,0x9d,0xed,0x83,0x96,0x89,0xaa,0x55,0x56,0xfd,0x0a,0x97,0x3a,0x50,0xfd,0x95,0x3f,0xb7,0xfa,0x87,0x7d,0xa6,0x5d,0x12,0x65,0x3f,0x61,0x4f,0x86,0xdd,0x58,0x64
+.byte 0xd7,0xde,0xd6,0xb9,0x68,0x87,0xde,0xba,0x96,0xf5,0x1c,0xec,0x8e,0x81,0xfc,0xca,0x77,0xe2,0x85,0x11,0x93,0xc7,0xf2,0x0f,0x77,0xbb,0x7c,0xed,0x20,0x7a,0xe3,0xc5,0x76,0xff,0x04,0xc7,0xe6,0x7a,0xa1,0xfe,0x58,0x52,0x1b,0xec,0x27,0xbb,0xd4,0x27,0x7c,0xc7,0x4a,0xfb,0x07,0x62,0x99,0x36,0xff,0x6e,0x71,0x2f,0xbd,0x25,0xff,0x8d
+.byte 0x97,0x14,0x56,0x23,0x7f,0x13,0x89,0x10,0xd8,0x29,0x1f,0x91,0x56,0x52,0x85,0xa7,0xd3,0x04,0xc9,0xe2,0x09,0xa2,0x0f,0xaa,0x28,0xb1,0x79,0xf9,0x08,0xf4,0x14,0x57,0xc4,0x54,0xd7,0x69,0xb0,0x37,0xf0,0x80,0x90,0xce,0x75,0x81,0xe7,0x75,0x0f,0x7f,0x71,0x58,0x3b,0x78,0x53,0x9b,0x4a,0x5e,0xcc,0x23,0x04,0x9e,0x0c,0xd7,0xd8,0x69
+.byte 0x90,0xdf,0x36,0x99,0x90,0xd3,0xfa,0x35,0xf7,0x13,0x64,0xb0,0xc0,0x70,0x0c,0xd4,0x87,0xc0,0xca,0xd8,0xca,0x8a,0xc3,0x9a,0xfa,0x73,0x34,0x18,0xe9,0x3a,0x85,0x42,0xc5,0xe1,0xaa,0xb5,0x87,0xac,0x43,0x9c,0xfa,0x7e,0x05,0x35,0xed,0x7e,0x0d,0x38,0x82,0x17,0x7f,0x22,0xa2,0x3d,0xd3,0x0d,0xd1,0xff,0x0a,0x68,0x52,0xd2,0x17,0x59
+.byte 0xaa,0x57,0xbd,0xd3,0xea,0x0c,0xe8,0xb0,0x22,0x13,0x59,0x42,0x46,0x34,0x58,0xa9,0x16,0xc5,0x9f,0x88,0x8f,0x75,0x02,0xbf,0x63,0xda,0x28,0xba,0x9a,0xcf,0xbb,0x73,0x58,0xb1,0x13,0xf2,0x68,0xd8,0x6b,0xfd,0x49,0x50,0xcf,0x09,0xea,0x6a,0xff,0x20,0x39,0xc5,0xae,0x70,0x79,0xea,0xec,0x9d,0x09,0xf8,0x51,0x1f,0xfd,0x01,0xd5,0x9f
+.byte 0xec,0x29,0x36,0xfc,0x39,0xb4,0x4c,0x1f,0xe6,0xb4,0xcc,0x97,0x21,0xe5,0x19,0xe9,0x7a,0x60,0x6d,0x39,0x3c,0x31,0xd4,0x43,0x76,0xba,0x10,0xd9,0x3f,0x75,0x7a,0xa6,0x1d,0x02,0x88,0x3d,0xa5,0x9f,0x91,0x61,0x4e,0x32,0xec,0xf5,0xd3,0xe4,0x65,0xf7,0x0e,0x3b,0x8a,0x8f,0x22,0x31,0x71,0x8f,0xf1,0x5f,0x7b,0x04,0x88,0xf9,0x88,0x67
+.byte 0x14,0x85,0x74,0x9e,0x54,0x0b,0xed,0x7a,0x48,0xcd,0xcf,0xd2,0x05,0x38,0xd5,0x58,0xa2,0xaf,0x6a,0x28,0x21,0xfd,0x38,0x4e,0x83,0x06,0x15,0x60,0xfb,0x89,0x2a,0x72,0xfe,0x75,0xc7,0xa4,0xae,0xe4,0x5b,0xbb,0xde,0x54,0xde,0x77,0xbb,0x9d,0xd2,0x07,0x05,0x61,0x53,0x65,0x31,0xd4,0x3a,0x8a,0x7d,0x9d,0x30,0x09,0x25,0x28,0x72,0x19
+.byte 0xe4,0xae,0x1d,0xbf,0xa7,0xef,0x75,0xd0,0xe3,0xdc,0x0b,0xd1,0x17,0x9c,0xc6,0xdf,0x65,0x9a,0x7c,0x9d,0x0b,0x9a,0x3d,0x8f,0xb0,0xf5,0x51,0x46,0x6b,0x12,0x0d,0xe6,0xa9,0x3a,0xb5,0xe9,0x52,0x85,0xa5,0x25,0x1f,0xc9,0x8b,0xff,0xe3,0x37,0x25,0x97,0xd8,0x91,0x17,0xed,0xcf,0x2a,0x6d,0x4f,0xef,0x74,0x5e,0x92,0xa2,0x2d,0x84,0xa6
+.byte 0x09,0xc4,0xfc,0x36,0x95,0x54,0x25,0x9e,0xeb,0xd9,0xea,0x5a,0x01,0x0c,0x54,0xdb,0x82,0x01,0xed,0x0b,0xf7,0x9f,0x0d,0x8f,0x2e,0xee,0x7c,0x6e,0xb3,0xe7,0xe8,0x04,0xef,0x8d,0x5e,0xfe,0x3d,0x96,0x3a,0x65,0xd3,0xb2,0x11,0x75,0x1c,0x6f,0x2a,0xd3,0x26,0x1f,0x5f,0x35,0x02,0x0b,0x9f,0x38,0x5b,0xa5,0x3a,0x90,0x3e,0x03,0x9f,0x50
+.byte 0xf2,0xd7,0xe4,0x3c,0xd3,0x28,0x67,0x0a,0x5a,0xe8,0x59,0x6f,0x38,0x8f,0x8b,0x0d,0xe4,0x1c,0xfc,0x6e,0x07,0x69,0x7b,0xfb,0x04,0x30,0xe7,0xa6,0x13,0xfb,0x33,0xa0,0x52,0x6a,0xec,0x64,0xad,0x90,0xbd,0xba,0x15,0x12,0x48,0xed,0xd1,0x94,0x2d,0xe7,0x19,0x28,0x5e,0x7a,0x94,0xf4,0x79,0xd7,0x79,0xc9,0xf6,0x16,0xb4,0x88,0xee,0x15
+.byte 0xa2,0x68,0xe3,0x1d,0xd0,0xd2,0x63,0x78,0x7c,0xb3,0x30,0xac,0x63,0x7a,0x36,0xc5,0x50,0xbf,0x57,0xf6,0xfe,0x4e,0x43,0x4e,0xf9,0xc4,0xa2,0x2a,0xa7,0xa4,0x2c,0x18,0xb9,0x43,0x7b,0xe8,0xf6,0x14,0x4f,0x07,0x6e,0x65,0x9a,0xdd,0x10,0x2a,0x4c,0xa4,0x58,0x86,0x19,0xad,0x6d,0x5e,0x30,0xfb,0x5f,0xb6,0x9f,0x2a,0xac,0x90,0x0d,0xae
+.byte 0xf9,0xab,0xc1,0x33,0xd3,0x73,0x1d,0x46,0xe5,0xc8,0x1e,0x1d,0x61,0xf1,0xda,0x53,0x3e,0x61,0xf0,0x9a,0xe4,0xb7,0x04,0xe9,0x5e,0xf6,0x11,0xa6,0x56,0x39,0xed,0xfb,0x06,0xd0,0x92,0xb9,0xb8,0xb5,0x3b,0x39,0xec,0xa5,0xc0,0xb1,0x7e,0x7e,0xfb,0x89,0x86,0xa8,0x70,0x47,0xa5,0x60,0x8c,0xf8,0x47,0x31,0x04,0x54,0x29,0xf3,0xa2,0x79
+.byte 0xac,0x24,0xda,0x33,0x6c,0x1c,0x34,0xc2,0xa0,0x96,0x27,0xbb,0x31,0xbf,0xc1,0xd9,0xc8,0x35,0xbc,0xb3,0x13,0x8a,0xb6,0x25,0x92,0xdc,0xcc,0x3b,0x8a,0x65,0xf3,0xf9,0xd1,0x2a,0xcd,0xb0,0xf4,0xd7,0x44,0xa0,0x27,0xfc,0x0e,0x69,0x46,0x0b,0x56,0x5b,0x58,0x40,0xd9,0xc4,0x37,0x9b,0x4d,0xa1,0x45,0xd8,0xab,0x4d,0x02,0x31,0x4f,0x93
+.byte 0x56,0xd0,0x26,0x99,0x1c,0xc7,0x2b,0xc2,0x80,0xb4,0xbd,0x6e,0xfe,0xa1,0xf7,0x8f,0x13,0x74,0x2c,0xa8,0x63,0xb1,0x3d,0x6d,0x32,0x4a,0x80,0x6a,0x7f,0xcf,0x6c,0x51,0xa9,0x21,0x34,0x4e,0x13,0x19,0x8f,0x33,0xfc,0x06,0x46,0x05,0xf0,0xcf,0xf1,0xce,0x20,0xe0,0x40,0xf2,0x0a,0xd0,0xf6,0xcc,0xcc,0xc2,0xc7,0x07,0x2e,0x9e,0x0a,0x1e
+.byte 0x53,0x59,0xbb,0xe3,0x02,0xc8,0x20,0x9f,0x3c,0xe6,0xec,0xf7,0x8a,0x6d,0x3c,0x0f,0xb3,0x14,0x66,0x5c,0x51,0xbe,0x82,0xc2,0x0b,0x10,0x63,0xa9,0xd4,0x7f,0x12,0x88,0x13,0x81,0x8a,0x06,0x8a,0x7f,0xc8,0x89,0xe7,0xbd,0xce,0x51,0xdc,0x93,0x03,0x07,0x6f,0x8c,0xe6,0xcc,0x0d,0x45,0xa8,0xfc,0x02,0xe2,0x3e,0xa7,0xc8,0x83,0x77,0x98
+.byte 0x91,0x4e,0x1f,0x8d,0xed,0xa5,0x38,0x54,0x0e,0x4e,0x53,0x1c,0x0c,0x47,0x11,0x59,0x54,0x15,0xb5,0x47,0xb0,0x21,0xa1,0x3d,0xaa,0xef,0xee,0x9e,0x26,0x3c,0x39,0x75,0xff,0x1a,0x8c,0xbb,0x1a,0x49,0x62,0x21,0x76,0xe8,0x3d,0x10,0x55,0xf5,0x5a,0x44,0xf0,0xb3,0x81,0xd0,0x35,0x96,0x95,0x63,0xf7,0x50,0xb1,0xa0,0xf0,0x29,0x97,0xc9
+.byte 0x27,0x73,0xd8,0x29,0xef,0x74,0xd2,0x6d,0xf4,0xfb,0x72,0xa9,0x4f,0x12,0xd5,0xfd,0xc9,0xba,0xf0,0xbd,0xfd,0x5e,0x5c,0xfa,0x53,0xe3,0x96,0xab,0x57,0xc3,0xb6,0xe8,0x0e,0x43,0xe4,0x77,0x97,0x04,0x69,0xff,0x72,0xd0,0xd8,0xab,0xb9,0x19,0x25,0x89,0xf7,0xbb,0x01,0x03,0xf2,0xc6,0x8d,0xd5,0x86,0xe3,0xfe,0x9c,0xff,0x78,0xd7,0xfc
+.byte 0xda,0xd4,0x69,0x8e,0xd6,0x31,0xfb,0x15,0xd3,0x38,0xfd,0x53,0xe2,0x4e,0xce,0xcc,0xfe,0x17,0xc5,0x88,0x92,0x28,0x98,0xb7,0xcf,0x7b,0x53,0x7b,0x96,0x14,0xaf,0xeb,0x5b,0x2d,0x16,0x41,0xcc,0x7b,0x65,0xe1,0x73,0x81,0x4e,0x8f,0xc3,0xad,0xe1,0x3f,0x0c,0xa7,0xbe,0x38,0xed,0x02,0x67,0xf5,0xfa,0x1d,0xb0,0xd5,0x4c,0xe1,0xd8,0x62
+.byte 0xc9,0xb5,0xf8,0x84,0xc4,0x51,0x57,0x14,0x11,0xf8,0x7d,0x1d,0xe7,0x81,0x85,0x61,0xa9,0x9f,0xc8,0x45,0xb9,0x2d,0x8a,0xc9,0xa3,0xfe,0x5a,0xf9,0xe0,0x1c,0x80,0xd8,0x77,0xaa,0x85,0xca,0x93,0x9a,0x2e,0x10,0x03,0x71,0x3d,0xb1,0x2a,0x64,0x2e,0xad,0x64,0xba,0x5c,0xaa,0x8a,0xc2,0x2a,0x80,0x28,0x2e,0xf9,0x93,0xe1,0x71,0x72,0xae
+.byte 0xda,0xd8,0x4f,0x4c,0xec,0xb5,0xe3,0x05,0x10,0x5f,0x4c,0xe6,0xe1,0xf4,0x07,0x63,0x75,0x6f,0xc5,0xf9,0xcd,0xfc,0xfc,0x35,0x2f,0xe4,0xca,0x4b,0xfc,0xc3,0x20,0x8b,0x5c,0x4a,0x3c,0xf8,0x92,0xca,0x2b,0xb0,0xce,0xd9,0x4b,0xf0,0x44,0xcb,0x4e,0x83,0xf3,0x9d,0xb0,0xd4,0xab,0xba,0x2a,0x76,0xaa,0x87,0xcd,0xa2,0xd1,0x3f,0xa0,0xb9
+.byte 0xdb,0x7e,0x67,0x2d,0x92,0x4c,0xeb,0x3c,0xa6,0x8c,0x62,0x80,0x18,0x78,0x2b,0x9d,0x8f,0x5e,0xc3,0xa5,0x3b,0x10,0xb3,0x8a,0x3b,0x00,0x96,0xb2,0xab,0xce,0x8d,0xff,0x3c,0xee,0xeb,0x4f,0xfb,0xab,0x96,0x38,0x4c,0x15,0x6e,0x7c,0xf3,0x31,0x5f,0x8f,0x99,0x88,0x52,0x48,0x8b,0x71,0x1b,0x31,0x3f,0x7c,0xe4,0xae,0x9c,0x7b,0xeb,0x64
+.byte 0xe3,0x80,0xd4,0x56,0x9a,0x6a,0xd9,0xca,0xc5,0xf0,0x86,0xe7,0xda,0x80,0x8f,0x17,0x61,0xca,0x24,0x0b,0xb6,0xf9,0x24,0xc5,0x7a,0x28,0x42,0x32,0x7f,0x2b,0xde,0x44,0x30,0xed,0x69,0x63,0x07,0x3f,0xca,0x7b,0x02,0xea,0x6e,0xef,0x27,0x1d,0x76,0x32,0xc2,0x81,0x3d,0x03,0x9a,0xe7,0x0d,0x28,0x07,0x03,0x0c,0x65,0x73,0x58,0x26,0xc6
+.byte 0xfe,0xcc,0x33,0x7f,0x33,0xad,0xea,0x81,0x05,0xcc,0x61,0x1e,0x78,0x69,0x70,0xc9,0x1f,0x6e,0x4f,0xb8,0x19,0x42,0x03,0x03,0x9d,0x56,0x87,0x0e,0x9a,0x32,0x3a,0xba,0xb9,0x11,0x66,0x9f,0x4d,0xd1,0xb0,0x11,0xbf,0x46,0xfc,0xcf,0xe5,0xef,0xf1,0x61,0xeb,0xad,0x31,0x7c,0x0d,0x66,0x0d,0xa9,0x1f,0xe4,0xf9,0x80,0x9e,0xae,0x9e,0x34
+.byte 0x1e,0x95,0x6c,0xa2,0x77,0x69,0x84,0x77,0xb7,0xe8,0xca,0x1f,0xea,0xc1,0x34,0xe6,0x0d,0x4f,0xba,0x77,0x2b,0x8c,0xbe,0xff,0xc4,0x06,0xa3,0xb6,0x1a,0xbe,0x55,0x99,0x57,0x6f,0x54,0x24,0x93,0x7a,0x0d,0x52,0xd6,0xbb,0xd2,0x9c,0xd5,0x76,0x6a,0x22,0x66,0xdc,0x43,0x9a,0x7b,0x1b,0x11,0x80,0x02,0x0c,0x8f,0xc6,0xc6,0x02,0x42,0x29
+.byte 0x00,0xc4,0xb2,0xa1,0x6a,0x7f,0xa9,0x60,0x8d,0x41,0x4f,0xd3,0xde,0x33,0x5a,0x44,0x31,0xb0,0xdc,0xc0,0x0c,0x31,0x03,0x96,0x71,0x0a,0xce,0xe3,0x0b,0xc7,0xe3,0x5d,0xe0,0x88,0x4b,0xfd,0x4c,0x1a,0xce,0xaa,0x89,0xc6,0x99,0xa8,0xd3,0x1e,0xe9,0x6c,0x2a,0xbd,0x26,0x81,0x03,0x6a,0xf2,0xf2,0x0f,0x1e,0x9d,0x8a,0x59,0x45,0xbf,0x6d
+.byte 0xb7,0xc8,0xec,0x77,0xb0,0x70,0x1a,0x31,0x21,0xeb,0x25,0x12,0xff,0x13,0x33,0x6b,0x47,0x34,0xd8,0x66,0x11,0x8a,0xc9,0x93,0x5b,0x2c,0x55,0x42,0xb2,0x9b,0x60,0xc6,0xba,0xab,0x12,0x12,0x5d,0x0a,0xd4,0x54,0x79,0x17,0x6d,0x31,0x7d,0x4f,0xf2,0x94,0x16,0x65,0x62,0x38,0x76,0x3a,0x7d,0x55,0x05,0xd9,0x17,0x45,0x62,0xb4,0x1d,0x31
+.byte 0x34,0x40,0xd3,0x8e,0xf9,0x29,0x4d,0x3f,0x93,0x9a,0x2e,0xa4,0x75,0x66,0xf6,0x62,0x8f,0xf9,0x8d,0x79,0x4b,0x51,0x7e,0xfb,0xeb,0x9a,0x86,0x96,0x01,0x79,0xbe,0xe4,0x42,0xb3,0xc8,0x28,0x9e,0xed,0xa8,0xb6,0x6d,0xd3,0x31,0xed,0x30,0x9e,0x6a,0x5b,0x02,0x4b,0xbd,0xb3,0xf2,0xf0,0x9d,0x50,0x09,0x40,0x71,0xfe,0x4b,0x91,0xc9,0xd6
+.byte 0x07,0x87,0x9e,0xdb,0xa9,0xcd,0x0b,0x95,0x18,0x5a,0x55,0x10,0xaa,0xe1,0x70,0xe9,0x2e,0xc2,0x31,0x6b,0x48,0x84,0x2f,0xe5,0x7b,0xdd,0x4c,0x03,0xed,0xb6,0xb6,0x64,0x24,0x38,0x7a,0x5a,0x15,0x35,0x9d,0x66,0x08,0x4d,0xa6,0x3c,0x96,0x1a,0xcd,0x02,0x61,0x40,0xde,0xac,0xc3,0x15,0x8c,0xca,0xe6,0x62,0xe9,0x61,0x68,0xf6,0x60,0xd3
+.byte 0x7e,0x5f,0x44,0xcf,0x09,0x01,0x60,0xc2,0xb1,0xfc,0x2f,0x41,0x4c,0xc1,0x06,0x72,0xcc,0xde,0x25,0xe0,0x8c,0x34,0xb8,0xe0,0xb2,0xeb,0x05,0x5d,0x9e,0x7e,0xf7,0x1e,0x24,0xcd,0x1b,0x14,0x3f,0x1b,0x13,0xc0,0x64,0x38,0x43,0x95,0xba,0x7b,0x61,0xa0,0xdc,0xe0,0xf5,0x80,0x13,0xa1,0xc5,0x48,0x92,0xc5,0xd5,0xd0,0x87,0x0c,0x73,0xae
+.byte 0xe2,0xb3,0xe8,0x70,0x4a,0x7e,0xa0,0x13,0xc3,0xc6,0x9c,0x77,0x51,0xca,0x88,0xcf,0xe0,0x1e,0xff,0x6c,0xe2,0xc3,0x33,0xce,0x7f,0x3e,0x7d,0xd5,0x37,0x23,0x09,0xb7,0xbd,0xb7,0xec,0x9a,0x29,0xd6,0x4f,0xea,0x79,0x24,0x4c,0x09,0x74,0x9c,0x97,0x3b,0x08,0x1f,0x82,0xcc,0xae,0xc4,0x3f,0xcf,0xc6,0xcb,0xaf,0x8c,0x89,0x15,0x79,0xeb
+.byte 0x88,0xb9,0x03,0xab,0xc6,0xf8,0x6e,0x54,0xde,0x50,0x6e,0xcf,0x8a,0x4b,0x3f,0x64,0xd0,0xcb,0x69,0xc2,0xe3,0x40,0x4a,0x94,0xe2,0x04,0xfa,0x9b,0x4a,0xf6,0x2b,0x93,0x0c,0x0e,0xf8,0x68,0xbc,0x6e,0x6c,0xe6,0xd9,0xb6,0x04,0x40,0xf4,0x60,0xbc,0xc1,0x1e,0x67,0x1f,0xce,0x5c,0x4d,0xba,0x78,0xa8,0xf5,0x96,0x00,0xb9,0x61,0x82,0x65
+.byte 0xb2,0x1d,0x42,0xb8,0x88,0x66,0x43,0xd9,0xfe,0xe0,0x86,0xef,0x5d,0x4d,0xcc,0xeb,0x57,0x9a,0x2b,0x27,0xf2,0xcf,0x68,0xc3,0x05,0x92,0x4d,0x4d,0xb7,0x46,0x7e,0xfd,0xb7,0x4a,0x4d,0x6f,0xac,0xc8,0x8d,0xf2,0xcd,0x52,0xcf,0x91,0x77,0x2d,0x68,0x06,0x7a,0xc9,0xf3,0x17,0xc6,0x8f,0x8f,0xb5,0x8f,0x74,0xfa,0x90,0xcc,0xfc,0xaf,0x4e
+.byte 0xd2,0x29,0xd9,0x57,0x71,0xe9,0x52,0xd8,0x50,0xfa,0x4d,0x13,0x7c,0x42,0x15,0x22,0x65,0x26,0x08,0xda,0xaa,0x53,0xcf,0xeb,0xd1,0x87,0xd5,0x7c,0x4e,0x66,0x1c,0x7d,0xc9,0x03,0x59,0xf8,0x09,0x3e,0x1b,0x94,0x4c,0x39,0x56,0xeb,0xfd,0xb6,0xd0,0xf9,0x76,0x8b,0x5d,0x6e,0x44,0x15,0xcf,0x27,0x7f,0x69,0x9a,0x00,0x96,0xbe,0x80,0x5e
+.byte 0xbb,0x5a,0x05,0xea,0x15,0xdd,0x44,0x69,0x9e,0x64,0xcd,0xba,0xf2,0x6f,0x67,0x10,0xc5,0xa1,0x75,0x85,0x5f,0xdc,0x61,0x43,0x34,0xc3,0x52,0x06,0xd4,0xe9,0x9f,0xdf,0xd4,0xa6,0x96,0xac,0xb1,0x21,0xdd,0x20,0x46,0x20,0x89,0x5f,0x0e,0x9d,0xa8,0xc7,0x75,0x3a,0x54,0x9e,0x7c,0x3a,0xd5,0xb2,0x68,0x77,0x06,0x1b,0x1c,0xbd,0xb3,0x02
+.byte 0xb5,0xdd,0x87,0x55,0x6b,0x00,0x9f,0x2c,0x30,0xb7,0x4e,0xc3,0x67,0x38,0x37,0x61,0x81,0x68,0xcb,0x14,0x81,0x27,0xd7,0x38,0x18,0x81,0x68,0x45,0xca,0xf4,0xaa,0xae,0x58,0x9e,0xf8,0xbe,0xe9,0x1e,0x05,0x19,0xf0,0xea,0x89,0xf8,0xa1,0x9c,0x7b,0x63,0xc1,0xcd,0x81,0xc8,0x95,0x56,0x81,0x81,0x29,0xb0,0x4d,0xbf,0xe6,0x8d,0xa3,0xb3
+.byte 0xfa,0xae,0x13,0xc8,0xca,0x4d,0x5c,0x5e,0xd9,0x17,0xf8,0x87,0xdb,0x5b,0xe2,0xd9,0xba,0xe3,0xe8,0xdb,0xcb,0x74,0x36,0x7e,0x0e,0x3a,0x94,0x6a,0xe9,0x9e,0x50,0x8e,0xf4,0xd4,0x15,0xb7,0x50,0x60,0x3f,0x14,0x72,0x41,0x9d,0x51,0x63,0x8c,0x31,0x95,0xf2,0xbc,0x14,0xc7,0x64,0x2c,0xee,0x0b,0xe6,0xde,0xf6,0x33,0x85,0x65,0x00,0x54
+.byte 0x54,0x84,0x85,0x94,0x87,0xa0,0xc3,0x95,0x4e,0x74,0xcb,0x2d,0x82,0x9e,0x46,0x7f,0xf5,0x64,0x60,0xfe,0x1a,0x37,0xee,0xa7,0xb6,0x85,0xb5,0x4e,0x30,0x11,0x39,0x4b,0xe9,0x57,0x18,0x3a,0x2c,0x6b,0xb9,0x8e,0x5a,0x54,0xa9,0x31,0xf7,0xe1,0xe0,0xc7,0x52,0xfe,0x76,0x9b,0xc6,0xfe,0xde,0xe0,0xe9,0xf9,0xf6,0x10,0xda,0xef,0x72,0x24
+.byte 0x9c,0xbe,0x4a,0xba,0x58,0x21,0x1b,0xe3,0x1d,0x80,0x10,0x76,0x70,0xde,0x8f,0xf3,0x07,0x93,0x01,0xe0,0xb4,0xd9,0x7d,0x60,0x0d,0x08,0x07,0xa4,0x6d,0x9b,0x2b,0x8c,0x9a,0x58,0x65,0x5e,0x29,0xf1,0x24,0xb2,0x31,0xfb,0xb7,0xad,0xf0,0x50,0x8e,0x25,0x1b,0x75,0xc5,0x82,0x88,0x8c,0x68,0x14,0x2c,0x28,0xa2,0xb6,0x93,0x14,0xe3,0x28
+.byte 0xd0,0x95,0x6f,0x79,0x91,0x03,0x75,0x82,0x5c,0x20,0x46,0x0d,0x53,0x40,0x2c,0x88,0x62,0xa4,0x8c,0xd5,0xf1,0xc1,0xbf,0xde,0x57,0x91,0xb2,0xa6,0x66,0x29,0xf0,0x6b,0xb8,0x5e,0x78,0x5f,0xd1,0x76,0x98,0xf2,0x56,0xc2,0x5f,0x48,0x1f,0xa6,0x98,0xb0,0x87,0x53,0x13,0x1d,0x1a,0xa7,0xdf,0xa5,0xea,0x37,0x12,0x6d,0x64,0x53,0xdc,0x04
+.byte 0x2d,0xb9,0xeb,0x78,0x89,0x7b,0x70,0xd2,0x6d,0x45,0x8d,0x45,0x50,0x57,0xc7,0xb2,0xaf,0xdd,0x72,0x0f,0x9f,0x1b,0x29,0x61,0x68,0xb5,0x4a,0xd4,0xe9,0xd7,0x10,0xe7,0xcd,0xe8,0x22,0xd3,0x54,0x0c,0x0b,0x32,0x77,0x7d,0x3e,0xed,0x6e,0x79,0x4b,0x7b,0x99,0x1f,0x9e,0xbe,0xe7,0x12,0x7c,0x94,0x36,0x1c,0x20,0x8a,0xd0,0xab,0xda,0x95
+.byte 0xf6,0x4f,0xbe,0x6f,0x44,0x0b,0xa3,0x7b,0x4d,0x00,0xf6,0xdf,0x6f,0xc8,0x50,0x9e,0x3e,0x0c,0x1e,0xfe,0xb8,0x39,0x9f,0x83,0x4f,0xb3,0x1f,0x7e,0x53,0x54,0x64,0x04,0xa3,0xf7,0x79,0x01,0x71,0xce,0x18,0x0d,0x47,0x4e,0xae,0x88,0x6a,0xe7,0x26,0x4e,0x59,0xee,0x3a,0x03,0xc2,0x4d,0x0c,0x29,0xf0,0x96,0x9d,0xc0,0xa3,0xb3,0x82,0xf9
+.byte 0xc4,0xf8,0x8b,0xae,0x68,0x47,0x39,0xdc,0x10,0xd7,0x09,0xb4,0x86,0x87,0xfa,0x7e,0x0c,0xe4,0xee,0x3a,0x35,0x1a,0x0e,0x95,0x88,0xce,0xe7,0x9e,0xcc,0xa5,0x58,0x98,0x48,0xbd,0x9c,0x27,0xe6,0xb9,0xf7,0xca,0x66,0xee,0x54,0x87,0xd0,0x6d,0xab,0x31,0x1a,0x57,0x33,0x8b,0x89,0xa0,0xc0,0x18,0x9a,0x87,0x5e,0x58,0x02,0xe5,0x50,0x47
+.byte 0x0f,0x60,0x53,0x9d,0x99,0xe4,0x0a,0xfa,0x4a,0xc3,0x77,0x4b,0x4d,0x4e,0x0c,0xbb,0x68,0xd9,0xb3,0xd3,0x59,0x78,0xdf,0x65,0x97,0x6e,0x22,0x5b,0x24,0x26,0xf9,0x2a,0x14,0x73,0xa7,0xec,0x65,0xfc,0xdf,0x7d,0x35,0x0d,0x44,0x1b,0x4b,0xad,0x6b,0x8f,0x0e,0xa3,0x3b,0x6b,0x40,0xb3,0xe3,0xd9,0x41,0xba,0xbf,0x95,0xbb,0x6e,0x91,0xf6
+.byte 0x63,0xb3,0xde,0xdb,0xc2,0x6f,0xfe,0x00,0xf1,0x53,0x96,0x37,0xa4,0x27,0x48,0x3e,0xf9,0x32,0x23,0x90,0x90,0xe0,0x01,0xde,0x08,0xad,0xc4,0x6c,0x25,0x7a,0x7f,0x2f,0xb7,0xb7,0xc6,0xaf,0xeb,0x91,0x9c,0xa2,0x9c,0xf7,0x7f,0x9f,0x74,0x9b,0x7d,0x54,0x66,0xf9,0xe0,0x73,0xb4,0x15,0x2b,0xaa,0x71,0x50,0xd0,0x74,0x5d,0xcd,0x1c,0x09
+.byte 0x4c,0x80,0xcc,0xdc,0x10,0xd9,0x96,0xb3,0xdc,0x09,0x73,0x1f,0x36,0x4c,0x1b,0x86,0x25,0x13,0x7c,0xd2,0xc6,0x9d,0x5a,0xce,0xd6,0x22,0x97,0x66,0x7b,0x7b,0x84,0xba,0x69,0xd2,0x87,0x9b,0x08,0xda,0x77,0x66,0x90,0xbc,0x7c,0x3c,0x5d,0x43,0x92,0x5f,0x05,0xfb,0x23,0x46,0x88,0xf7,0xa4,0x10,0xbd,0x7d,0x00,0x29,0x2d,0xa5,0x6a,0xab
+.byte 0xcc,0xdd,0xcf,0x1e,0x2b,0x9b,0x5f,0xa9,0x94,0x14,0x99,0x6e,0x3b,0x41,0x52,0x61,0x16,0x17,0x44,0xcf,0x5b,0x34,0x5c,0x27,0x29,0x4a,0xc3,0xba,0x9a,0x0c,0x20,0x17,0x2b,0x92,0xd9,0xf1,0x76,0x51,0xd8,0xa5,0x4a,0x4b,0x4a,0x0b,0xe4,0x6b,0x93,0x61,0xc7,0xb3,0x23,0x7a,0x24,0xfa,0x5e,0xee,0x80,0x10,0x65,0x44,0xa5,0xed,0x72,0xd9
+.byte 0x8a,0x06,0x2a,0x86,0xa9,0x26,0x50,0xa1,0xb2,0xb2,0x8b,0x7b,0x4a,0x29,0xf1,0x18,0xef,0xff,0x61,0xf1,0xa1,0x48,0x0f,0x84,0x8c,0xef,0xd8,0x02,0x65,0x44,0x11,0xf2,0xe1,0xba,0x98,0x03,0xbe,0x5a,0x5d,0xb8,0x0a,0x88,0xd8,0x4a,0x49,0x4c,0x70,0xa6,0x98,0x81,0x36,0x56,0x92,0xde,0xcb,0xaf,0x33,0xf5,0x1c,0x0a,0xce,0x7a,0xc0,0xff
+.byte 0x24,0x54,0xd3,0x9a,0x0f,0x82,0x76,0xe5,0x0e,0x82,0xb4,0xfe,0xc2,0xac,0xe4,0xba,0xa3,0x4c,0x8a,0x0d,0xa7,0x3e,0x2b,0x71,0x73,0x5f,0xd2,0x35,0xd3,0xae,0xc0,0x3e,0x6f,0x67,0x98,0x51,0xa6,0xdf,0xb2,0xf4,0xd2,0xc1,0x43,0xe2,0x0a,0x7c,0xa0,0xb6,0xff,0xfc,0xc0,0x88,0xe5,0x34,0x20,0x79,0x50,0xc3,0x06,0x5b,0x20,0x9f,0x05,0x33
+.byte 0x22,0x30,0xaf,0xc4,0xc3,0x17,0x09,0xbb,0x30,0x0f,0x42,0xb7,0xc1,0xe0,0x4c,0x71,0xc5,0xf7,0x96,0xb4,0xd4,0x0f,0x44,0x47,0xa3,0x06,0x17,0xbd,0x0f,0x7c,0xc6,0x53,0x07,0x34,0x9a,0x9a,0x2f,0x3f,0x01,0xea,0xdf,0x1c,0x06,0x33,0x15,0x9c,0x5a,0xe3,0x33,0x29,0xce,0x40,0x4b,0xb1,0x99,0xe0,0x80,0x6e,0x0c,0xa1,0x4c,0x34,0x01,0x21
+.byte 0x12,0xbe,0x67,0x26,0xe6,0xdb,0xab,0x8d,0x45,0xdd,0x12,0x60,0x02,0x1a,0xdd,0x85,0xd6,0x33,0x78,0x23,0xe1,0x58,0x2a,0x46,0xf0,0xc2,0x4d,0x71,0x59,0x5b,0x8d,0x65,0xa7,0x97,0xf4,0x71,0x88,0x7d,0x60,0xe0,0x2d,0x2d,0x09,0x2f,0x26,0x15,0xa7,0xbf,0x30,0x0b,0x99,0x08,0xd7,0x85,0xfc,0x0c,0x19,0x31,0xde,0x5e,0x55,0x91,0x13,0x45
+.byte 0x3a,0x6d,0xd0,0x61,0x02,0x81,0xa0,0x42,0x7d,0xd8,0x7d,0x41,0x11,0xd2,0x25,0xb7,0x15,0xa1,0x16,0x3e,0x70,0x77,0x1b,0x80,0xb7,0xf1,0x24,0x8e,0x70,0x8d,0x73,0x6d,0xba,0xf1,0x46,0x32,0x60,0xe4,0xc8,0x4d,0x69,0xc8,0x10,0xf8,0x2d,0x53,0xe1,0x81,0x96,0x20,0x9d,0x59,0x74,0xae,0x93,0x92,0x44,0x5a,0x09,0x79,0x20,0xcb,0xff,0xb2
+.byte 0x08,0x7a,0x81,0xee,0x98,0x83,0x0b,0xa4,0x15,0xb0,0xaa,0x55,0xb0,0xb5,0x60,0x09,0x21,0xeb,0xe2,0x9b,0x57,0x41,0xb9,0xb4,0xd9,0xbe,0x7d,0x60,0x5d,0x25,0xde,0x9f,0x9e,0x5b,0x7c,0xee,0xeb,0x87,0x54,0x6a,0xc3,0xcf,0xec,0x57,0xce,0x97,0x2e,0x47,0x84,0x4c,0x15,0xf4,0xf5,0xe9,0xd4,0x45,0x23,0x20,0xf0,0x0f,0xda,0x97,0xc2,0xb9
+.byte 0xb2,0xe2,0x44,0xea,0xbd,0x95,0x73,0xcc,0x94,0x03,0x0b,0x97,0xeb,0x03,0xc1,0x51,0xc8,0x14,0xa6,0x7d,0x18,0x30,0xa1,0xda,0xa3,0xcd,0x78,0x67,0xb0,0xc1,0x6c,0x88,0xdd,0xd6,0x52,0x4b,0x85,0x1d,0x4a,0xaa,0x44,0xec,0x3b,0xff,0x00,0xd8,0x9e,0x18,0xf8,0xac,0x4f,0x73,0x6d,0xc7,0x4b,0x59,0x15,0x85,0x87,0x02,0xd8,0xf1,0xe6,0xfb
+.byte 0x66,0x57,0xcf,0x06,0x84,0x50,0xc5,0x67,0x94,0xc6,0x96,0xb2,0x1a,0x37,0x06,0x3d,0x21,0xf2,0x1e,0xb4,0xe7,0xcb,0x36,0x8b,0xa3,0xe3,0x84,0xa0,0x9a,0x31,0xdb,0x87,0xf9,0xb0,0xef,0x06,0xfe,0xb0,0x8a,0x32,0x53,0xb4,0x41,0x79,0x6b,0xf7,0x7c,0xf7,0x9c,0xc1,0xea,0x61,0xf3,0x75,0xac,0x1f,0x92,0x75,0x44,0x58,0x9a,0x20,0xa4,0x20
+.byte 0xe3,0x19,0x1c,0x0d,0x27,0xe5,0x2e,0xbd,0x14,0xcb,0x40,0x3f,0x1c,0x19,0x7c,0xf9,0x92,0x13,0x1a,0x71,0x87,0xaf,0x77,0x0f,0x50,0x92,0x06,0x75,0x2d,0x75,0xe0,0x2e,0x37,0x54,0xcd,0xac,0xcb,0xca,0x7c,0x0e,0x66,0x53,0x10,0x50,0x70,0x9a,0xa4,0x79,0x76,0x87,0x71,0x4a,0x55,0xd4,0xa3,0x83,0xb3,0x04,0xed,0xa9,0xd6,0x84,0x7d,0x1a
+.byte 0x64,0x5d,0xf7,0x4f,0x55,0x97,0x5e,0x26,0x9c,0x03,0x42,0x0a,0x16,0xd3,0xdf,0xc8,0x07,0xb8,0xb3,0xe9,0xac,0xa9,0x99,0x83,0x32,0x5b,0x83,0xde,0x7f,0x2b,0x70,0xca,0x15,0x09,0x33,0x0e,0x28,0xc9,0x89,0xc6,0xa6,0x47,0xd1,0x56,0x04,0x40,0x5d,0xd2,0x17,0x1d,0x32,0x21,0x6d,0xb2,0xc7,0x89,0x14,0x98,0xc6,0x58,0xc4,0xca,0xda,0x0f
+.byte 0x32,0xdd,0xe1,0xe1,0x9a,0x25,0x09,0x31,0x16,0xf1,0x48,0x40,0x1c,0xc2,0xf9,0xd0,0xba,0xec,0x07,0x94,0xea,0x17,0xcf,0x6e,0xbc,0xfd,0x70,0xb4,0xbb,0x40,0xae,0xc3,0xae,0xf7,0x56,0xf5,0x13,0x55,0xfb,0x4b,0x81,0x5d,0xab,0xf2,0x3f,0xd7,0xa7,0xe6,0xcf,0x17,0xef,0x1f,0x71,0x1b,0x92,0x67,0xd3,0xd2,0xed,0x89,0x14,0x8f,0x8d,0x83
+.byte 0xef,0x7f,0xca,0x65,0x6d,0x79,0x13,0x5f,0x6e,0xf9,0x5d,0x9a,0x68,0x54,0x71,0x5c,0x9d,0x03,0x7c,0x73,0x7a,0xc2,0x17,0x9b,0x5a,0x7d,0x45,0x24,0x0c,0x41,0x13,0xe4,0xcb,0xdb,0x7b,0xc6,0xfb,0x93,0x48,0xca,0xd3,0x01,0x68,0x3f,0x36,0xc0,0x4b,0x1d,0xfa,0x9f,0x25,0x0e,0xcc,0xd0,0xf7,0xa0,0x7a,0x14,0xac,0xd7,0x6e,0x00,0x9f,0xf1
+.byte 0xc0,0xdc,0xfc,0x3b,0xd9,0xbf,0x68,0xfd,0x65,0x34,0x66,0x18,0xe5,0x02,0x9a,0x2d,0xff,0xaa,0xf7,0x73,0x58,0x21,0xe3,0xff,0x23,0x0f,0x63,0x1f,0xf3,0x8b,0x08,0xc7,0x00,0x46,0xe7,0xef,0x85,0x5f,0x7f,0xd9,0x5f,0xc2,0x36,0xe2,0xb6,0xa3,0x00,0xcb,0xff,0xe0,0x22,0x28,0x8c,0xb1,0xb1,0x17,0x91,0x4a,0x4a,0xc8,0x77,0x5a,0xa9,0xb2
+.byte 0x6e,0xb7,0xf0,0x4f,0x70,0x34,0x7f,0x87,0x2a,0x0c,0xcb,0x16,0x24,0x9b,0x41,0xb2,0x3e,0x0a,0xc1,0x33,0xf3,0xbb,0x48,0x17,0x2f,0xe6,0xfc,0xf4,0x27,0xc0,0xdb,0x58,0x24,0x9b,0x99,0x43,0x25,0xfb,0xd3,0xcf,0x1c,0x5a,0x5f,0xbe,0x28,0x3a,0x84,0x51,0x19,0xc3,0x53,0x6b,0xc8,0x73,0x44,0x6e,0x3d,0x7e,0x01,0x37,0xc2,0x2b,0xf7,0xa8
+.byte 0x1f,0x8e,0xd8,0x02,0x5a,0xae,0x56,0x81,0x2b,0x46,0x1b,0x7d,0xca,0x27,0x1f,0x48,0x99,0x24,0x54,0x59,0x08,0xfd,0xb7,0xdf,0x0a,0x77,0xef,0x4e,0x89,0x21,0x71,0x71,0x3f,0x8c,0xd7,0x52,0x89,0x7a,0x0d,0x68,0x09,0xc8,0x88,0x9c,0x0c,0x60,0xca,0x77,0x96,0xeb,0x05,0xeb,0xeb,0x60,0x5b,0x68,0x51,0x2c,0xcb,0x8f,0xca,0x3b,0x18,0x39
+.byte 0x28,0x8f,0xda,0x17,0x9b,0x53,0x71,0x26,0xa9,0x19,0xfb,0x1e,0x4a,0xd0,0x14,0x93,0x1c,0xee,0xe1,0x21,0xea,0xb3,0x16,0x47,0xaf,0x50,0xe5,0xe5,0xd3,0x21,0x8c,0x67,0x46,0x5d,0x97,0x19,0xda,0x6e,0xd9,0x70,0x7d,0x9f,0xd6,0x25,0xd0,0xfb,0x01,0x62,0x0a,0x9e,0x49,0x3d,0x33,0x0d,0x35,0xe5,0xae,0xfd,0xeb,0xb5,0x9b,0xd8,0xc1,0x2a
+.byte 0xee,0x4d,0xf2,0xfc,0x16,0x51,0xab,0x58,0x7a,0x9e,0x5c,0xca,0x0a,0x92,0xbb,0xbb,0xa8,0x5b,0xfb,0xf9,0x33,0x67,0x0e,0x13,0x4c,0x83,0x3a,0x25,0x84,0x23,0xe1,0x41,0xfb,0xf1,0x42,0xc1,0x8d,0x58,0x0c,0x5e,0x75,0x09,0x34,0x58,0x96,0x32,0x54,0xb6,0xd8,0xaa,0x48,0xc1,0xed,0xc0,0x92,0x5a,0xec,0xeb,0xb1,0x75,0x59,0xf6,0x35,0xf5
+.byte 0xfd,0x7d,0x96,0x9b,0x83,0x38,0x31,0x10,0xa4,0xd7,0xfb,0x28,0xf0,0xc9,0xe4,0x33,0x5d,0x66,0x81,0x9c,0x31,0x9a,0xe9,0x9a,0x5e,0x70,0xf7,0x61,0xf9,0x93,0xaf,0x2b,0xbd,0x78,0x9e,0xdc,0x61,0xe0,0xa9,0xd1,0xa0,0x8e,0x3a,0x5f,0xb1,0x71,0xe7,0x9e,0xfd,0x81,0xee,0xf0,0xd6,0x63,0xec,0x4a,0xca,0x30,0xaf,0xb6,0x2d,0xaa,0x2d,0xa1
+.byte 0x5a,0x38,0xb5,0xc6,0x3f,0x5f,0x63,0x48,0xd3,0x18,0xeb,0xe3,0x36,0xca,0x91,0x86,0x4b,0x6f,0x57,0x66,0x47,0x2f,0xce,0xe4,0x44,0x26,0xe4,0xfd,0x8c,0xde,0x74,0xdc,0x17,0x0e,0x7d,0x6a,0xcf,0x89,0x0e,0x7f,0x09,0x65,0xf8,0xeb,0x58,0x00,0x3d,0xc5,0x1b,0x14,0xc5,0xca,0xca,0x28,0xbc,0xb7,0x63,0x6f,0x3b,0xa4,0x62,0x23,0x0e,0xd5
+.byte 0x04,0x76,0x0c,0xe8,0xea,0x64,0x10,0x3a,0x76,0x03,0xd6,0xea,0x69,0x52,0x14,0xa7,0x5e,0x40,0x7e,0x14,0xdb,0x7f,0xbf,0xe8,0xf6,0xf0,0xdd,0x5e,0xac,0x55,0x44,0xfb,0x28,0xf3,0x16,0xcb,0xed,0x8f,0x10,0x01,0x91,0xac,0x2c,0x27,0x46,0x0c,0x51,0xd6,0xf6,0x30,0xa3,0x34,0xd0,0x5e,0x93,0xe8,0x4e,0xc0,0xb4,0x9b,0xc1,0xe8,0x20,0x7d
+.byte 0xb7,0x68,0xdd,0xf1,0xc4,0x60,0x20,0x97,0xdd,0x5c,0x7c,0x9b,0xea,0xc0,0x22,0x84,0x2c,0x65,0x78,0xbd,0x18,0xa1,0x62,0x7e,0x06,0x49,0x96,0xde,0xd1,0x89,0x06,0x0d,0x35,0xa0,0xcc,0x22,0xd3,0xf5,0xa6,0x4b,0xb6,0xca,0x43,0x34,0x5a,0x3d,0x39,0x95,0x0b,0x95,0xbe,0xdc,0xe6,0x61,0x72,0xbe,0x2f,0x19,0x1c,0xe8,0x22,0x5e,0x18,0xc9
+.byte 0x59,0x4a,0x08,0xa3,0x85,0x5c,0x06,0x36,0x00,0x2e,0x84,0x3e,0x3e,0x07,0x5b,0xfa,0xda,0xbb,0xbb,0x57,0x20,0x6f,0x1b,0x8d,0xe5,0xc5,0xdb,0x8d,0x23,0x1a,0xfc,0x67,0xa9,0xc8,0xea,0xe1,0x54,0xbb,0x8a,0x8a,0x0b,0xa6,0x02,0x35,0xd6,0xd5,0x4d,0xff,0x09,0x79,0x31,0x9a,0xc2,0xad,0xa7,0x66,0xb5,0x3c,0xbd,0xb7,0xcb,0x17,0x30,0x4b
+.byte 0x56,0xf5,0xd2,0x51,0x90,0xbb,0x47,0x00,0xc0,0xf3,0x8b,0xd7,0x10,0x33,0x6d,0xe8,0xe4,0xcf,0xd6,0xbf,0x35,0x75,0x8d,0x40,0x55,0xd7,0x5d,0xb0,0x40,0xf6,0x95,0xfb,0x1a,0x97,0x24,0xb8,0xc1,0x91,0x5f,0x66,0x6c,0xc7,0xdb,0x16,0xba,0xb8,0x07,0xf8,0xf8,0x91,0xb2,0x8c,0x26,0xb9,0xa2,0x59,0xb0,0xde,0x49,0x63,0xcc,0x7c,0x4c,0x48
+.byte 0xb5,0xe4,0xf9,0x81,0x28,0x48,0x9f,0xa0,0xa4,0xf8,0x0d,0xcc,0x7b,0xf3,0xce,0x08,0x85,0x73,0x4a,0x64,0xfc,0xa8,0xc0,0xae,0x7a,0xbf,0xa5,0x3f,0x45,0xaf,0xe7,0x7f,0x41,0x61,0x34,0x08,0x6e,0x09,0x0d,0x9d,0xea,0x90,0xbe,0x62,0x7c,0x38,0x92,0xa7,0x63,0xfa,0x03,0x80,0x10,0xc4,0x53,0x46,0x0b,0x44,0x88,0xea,0x50,0xb6,0x82,0xf8
+.byte 0x0b,0x2d,0x93,0x63,0x82,0x80,0x2b,0x61,0x3e,0x17,0xd1,0xd8,0x6c,0xb1,0xb4,0xbd,0xfd,0xad,0x1c,0x10,0x30,0xc1,0x78,0xd4,0x5f,0x21,0x49,0x54,0x7a,0x08,0x2b,0x25,0x3b,0xc9,0xb7,0x0a,0xf2,0x37,0x83,0xc0,0x43,0x73,0xee,0xd6,0x8b,0x92,0x15,0xde,0xfe,0x14,0xf1,0xfb,0x8b,0x4a,0x85,0x8d,0x78,0xe6,0x36,0x1a,0xbb,0x32,0x6c,0xdd
+.byte 0x43,0x76,0xad,0x68,0x90,0x08,0xd2,0xbd,0x24,0x41,0xd4,0x93,0x17,0xa8,0x9f,0xeb,0x33,0x25,0x1f,0x1a,0xfd,0x45,0x20,0xc1,0x47,0xf1,0x25,0x09,0x89,0x14,0x9e,0x4c,0x88,0xa4,0x1c,0xb8,0xba,0x84,0xd5,0x7d,0x73,0xb2,0x9c,0x48,0x9f,0x84,0x31,0xd3,0x2c,0xe1,0x94,0x61,0x3e,0x5f,0x37,0x25,0xc7,0xb7,0x2d,0xc3,0xa9,0xaf,0xcc,0x0e
+.byte 0xe6,0xc7,0x9a,0xa7,0x06,0xe3,0x41,0xb8,0xa6,0xa8,0x9a,0xe7,0x76,0xef,0x83,0x5a,0x80,0xa4,0xe3,0x0c,0x04,0xa2,0x0b,0x91,0x33,0x34,0x17,0xa4,0x02,0x2d,0x12,0x84,0x67,0x85,0x6b,0xc0,0x3a,0x0d,0x16,0xf2,0x66,0x04,0x71,0xe9,0xec,0xa6,0xbb,0x58,0x42,0x92,0x70,0xf5,0x0d,0x52,0xcd,0x1e,0x2d,0xd4,0x28,0x0f,0x68,0x35,0xd9,0xa4
+.byte 0x40,0x09,0x30,0xe9,0xbb,0xaf,0x77,0x63,0x4f,0xba,0x56,0x97,0xe8,0x92,0xcc,0xba,0xdb,0xe4,0xe0,0xdf,0x19,0x21,0x71,0x23,0x3d,0xd0,0xb1,0x25,0xd3,0xf8,0x53,0x01,0x30,0x9a,0xea,0x84,0x1b,0x18,0x68,0x4a,0xb9,0x9e,0x60,0xc4,0xfc,0xf7,0x56,0xb7,0x49,0xe1,0x50,0x38,0x7d,0x3d,0x87,0xa2,0xad,0x38,0x5c,0x0c,0x53,0x21,0xa0,0x56
+.byte 0x3a,0x94,0xd7,0xa8,0x23,0x96,0xa9,0x66,0x4e,0x88,0xae,0x4b,0x6e,0xcb,0xc6,0xa6,0xdb,0x1f,0x2e,0xae,0xe7,0x24,0xe2,0x1e,0xf7,0x3a,0x14,0x48,0x5e,0xfa,0x90,0x0a,0x84,0xa6,0x1c,0xaa,0x60,0xc0,0x2c,0x69,0xe8,0x36,0xb3,0xee,0x55,0x2a,0xf7,0x90,0xa1,0x92,0x4f,0x29,0x1e,0x49,0x6e,0x73,0x22,0x1f,0x8b,0x0c,0xb6,0xf4,0x3c,0xbf
+.byte 0x82,0x47,0x49,0xc3,0x94,0x0e,0xcf,0x9b,0x86,0x88,0xc2,0xd0,0xd7,0xa7,0x43,0xfb,0x89,0x4b,0xbd,0x5d,0x4c,0x6b,0x7a,0xc7,0x74,0x1b,0xfb,0x48,0x12,0x68,0x61,0x91,0xf9,0xf3,0xb6,0x7f,0x4f,0x72,0x89,0xf0,0x72,0x46,0xf7,0x6f,0x84,0xd1,0x38,0x6d,0xd9,0x1b,0xa5,0xd1,0xe2,0x29,0xe0,0xa6,0xbf,0x1c,0xbd,0xfb,0xdd,0xdc,0xa5,0xae
+.byte 0x7a,0x9c,0xd0,0xc3,0xfa,0x6f,0x72,0xa3,0xa2,0x8b,0x87,0x0d,0x9a,0x6a,0xfc,0x53,0x9a,0x08,0x61,0x86,0x67,0x2a,0x90,0x6a,0x09,0x20,0x8e,0xde,0x32,0x35,0x34,0x75,0xc0,0xa8,0xab,0x1b,0xc4,0x7c,0xc8,0xd9,0x90,0xcf,0x32,0x27,0x6c,0x68,0xf9,0x18,0x14,0x05,0x57,0x39,0xc6,0x9e,0x5e,0x38,0x07,0xdb,0x81,0xb4,0xa4,0x54,0x06,0xd6
+.byte 0x79,0x78,0x0e,0xc8,0xb9,0x56,0xda,0x08,0x2e,0x77,0x26,0xcc,0xf7,0xa5,0x2d,0xd8,0x91,0xa6,0xfc,0x25,0x0e,0x91,0xdd,0x3c,0xa8,0x14,0x7a,0x95,0x05,0x5b,0x15,0x7d,0x1d,0x9b,0x3c,0x8c,0xfd,0xdc,0xa5,0xcd,0xec,0xea,0x7a,0x2b,0x7e,0x79,0x21,0x54,0xea,0x7f,0x52,0xb4,0xbb,0x4f,0x07,0x95,0x39,0x4a,0xaf,0x2e,0xb4,0x1e,0x9e,0xc6
+.byte 0x0a,0x07,0x58,0xd4,0xa5,0x44,0x73,0xa8,0x84,0x26,0x67,0xb8,0x0f,0xc7,0x6b,0xa7,0x28,0xf6,0x05,0x91,0x3e,0x22,0xcd,0xd7,0xf5,0xfc,0xae,0x22,0x42,0x96,0x3b,0x57,0x91,0xce,0x44,0xd0,0xfd,0xc3,0x4c,0x8b,0x8b,0x67,0xfe,0x03,0x86,0x92,0x34,0xf7,0xf9,0x53,0xb3,0xdf,0x36,0xcf,0x16,0x1c,0x68,0x36,0x17,0x1f,0x41,0x56,0x1d,0xda
+.byte 0x90,0xb3,0xab,0x03,0x97,0x88,0x23,0x65,0x89,0x72,0xe3,0x6d,0x8e,0x37,0x5d,0xee,0x89,0x81,0x11,0x27,0x8b,0xf0,0x9b,0xef,0xa2,0x34,0x45,0xcc,0x41,0xcf,0x2a,0x88,0x70,0xe4,0x78,0xfc,0xe1,0xb5,0x51,0x70,0x84,0x64,0xd1,0x10,0x71,0x5d,0xa4,0xb4,0x6d,0xb5,0x98,0x6e,0xcc,0x9a,0x62,0x14,0x30,0xce,0x1a,0xff,0x49,0xd6,0xaa,0xcc
+.byte 0xe1,0x99,0x42,0xb1,0xfe,0x77,0x8a,0x2d,0xdb,0xc0,0x0d,0x50,0x53,0x0d,0x92,0xe5,0x2b,0xd0,0x78,0x83,0x08,0x4a,0x0c,0x1d,0x5b,0x03,0x22,0x65,0x3d,0x9e,0xdb,0xcf,0x01,0x61,0xf7,0x6d,0x2b,0x99,0xef,0xba,0x80,0x50,0xda,0xda,0x2d,0xbf,0x00,0xdf,0x6f,0xec,0x95,0xbc,0x5b,0x4e,0xda,0x83,0xe4,0x5d,0xf0,0xa7,0x1b,0x27,0xf1,0x76
+.byte 0x04,0x5d,0x3d,0x2c,0x12,0x15,0xad,0xef,0x47,0xdc,0x22,0x9b,0xc2,0x80,0x91,0xf3,0xbf,0x16,0xe9,0xd3,0x35,0x94,0x4b,0xfd,0xa3,0xa1,0xee,0x98,0xad,0x99,0xea,0x07,0xe1,0x0f,0xa7,0xbd,0x0b,0xfb,0xc0,0xd5,0xb0,0x49,0x37,0xc6,0x5f,0xe7,0x18,0xc1,0x60,0xe9,0x1d,0x5e,0x0e,0xea,0x73,0xf2,0xa1,0x75,0x7e,0x39,0x51,0x07,0x1e,0xcb
+.byte 0x2a,0x5b,0x26,0x75,0xbe,0x02,0x5e,0xde,0x6c,0x37,0xb1,0x3c,0x1f,0x25,0x65,0x7d,0x9e,0x5d,0xa1,0x0b,0x98,0x27,0x53,0xb9,0xbb,0xc2,0x3e,0x8d,0x2d,0x5e,0x5c,0xbf,0xed,0x66,0xe8,0xd1,0x7d,0xaa,0xef,0xca,0x0e,0xd0,0x78,0x2b,0x89,0x07,0x76,0xb6,0xc3,0x92,0x42,0x3a,0x84,0x1d,0x81,0xc1,0xe8,0x1a,0xb8,0xe6,0xf1,0x43,0xcc,0x7a
+.byte 0x59,0x4d,0x9f,0x00,0xfe,0x6a,0xe5,0x42,0x71,0x3c,0xcb,0xc8,0x45,0x18,0xf0,0xf2,0x81,0x9d,0x5a,0xb7,0x8d,0xbe,0x31,0xcb,0x7d,0xca,0xb7,0x19,0x57,0xb1,0x61,0x36,0x90,0x42,0xe2,0xc3,0xf5,0xa5,0x4b,0xc3,0xd4,0xe7,0x6c,0xb6,0x0c,0x06,0x19,0x4b,0x54,0x8f,0x2d,0xdc,0xc5,0x2b,0xff,0x1c,0x61,0x29,0xda,0x95,0x4f,0xa1,0x21,0x25
+.byte 0x24,0xbe,0xc7,0x34,0x2f,0xbf,0x33,0x6d,0x82,0x8f,0xf1,0xa9,0x97,0x5a,0x49,0x7f,0x60,0x00,0xf2,0x3e,0x7b,0x64,0xdf,0xc8,0xd3,0x5f,0x6e,0x1f,0xfb,0x71,0x80,0xf3,0x55,0x42,0xbe,0x32,0x7b,0xa9,0xeb,0xf6,0x31,0xe2,0xf0,0xd1,0xe9,0xbe,0x96,0x0e,0xb3,0xdf,0x3e,0xb2,0x2c,0xc3,0xce,0xbd,0xe7,0xfe,0x1c,0xed,0x2c,0x0b,0xaa,0x32
+.byte 0x76,0x82,0xb4,0x6b,0x18,0xa7,0x68,0x19,0xb7,0x27,0x21,0x4c,0xb0,0x22,0x98,0x58,0xd5,0x90,0x80,0xab,0xa1,0xfe,0x83,0xc5,0x66,0xf6,0x3e,0xa2,0xa9,0x6f,0x73,0xce,0x7f,0x0c,0xe6,0xde,0xee,0xb0,0xe6,0x2a,0xcc,0xcc,0xb0,0x53,0x8c,0xce,0xc8,0xdc,0xea,0x83,0xb4,0x0e,0x69,0x8d,0x90,0x86,0xaa,0xe3,0x3b,0xfb,0x88,0xe2,0xe8,0x27
+.byte 0x65,0x36,0x07,0xb3,0x91,0x0e,0x5a,0x6b,0x9f,0x0f,0xbd,0x81,0xb3,0x54,0x65,0x71,0xa4,0x2c,0x8e,0xda,0x47,0x04,0xce,0xfe,0x00,0x52,0xf1,0xdf,0x82,0x27,0x70,0x2a,0xb1,0x79,0x2f,0x27,0x7f,0xae,0x9e,0x5c,0x36,0xec,0xa0,0x2a,0xf3,0x74,0x78,0x01,0x17,0x74,0x2a,0x21,0x4f,0xb8,0xd2,0xe4,0xfe,0x5b,0x06,0x14,0xa5,0xb1,0xb1,0xff
+.byte 0xee,0x79,0xf7,0x18,0xb9,0x31,0xa4,0x63,0x47,0x1c,0xdf,0x38,0x04,0x2d,0x18,0xca,0x14,0xf8,0x2f,0xec,0x0d,0x58,0xad,0xbb,0xf4,0x45,0x11,0x0e,0xfa,0x17,0x4c,0x5e,0xd4,0xa6,0xde,0xe4,0x13,0x44,0x2c,0xb9,0xfd,0xcd,0x41,0xe7,0xf9,0xda,0xbc,0x28,0x8f,0x0c,0x41,0x4d,0xa7,0x0d,0xf5,0x96,0xd7,0x8f,0x10,0x96,0xfb,0x75,0x75,0x86
+.byte 0xc9,0x6e,0x23,0x92,0x71,0x69,0x7b,0x94,0x61,0x1c,0x3f,0xcf,0x66,0x34,0x62,0x68,0x5d,0xee,0x7b,0x34,0x5d,0x2a,0x39,0xbb,0x6a,0x34,0xea,0x6e,0xe3,0xe9,0xdb,0xe4,0x34,0x6e,0x29,0x0b,0x21,0x38,0xe7,0x5b,0x79,0x37,0x54,0xf0,0xed,0xaa,0x07,0x2b,0x21,0x29,0x67,0xfe,0x7d,0xa5,0x99,0x0e,0x5d,0x05,0xe7,0x61,0x6e,0xd1,0x4a,0x15
+.byte 0x4a,0x56,0xb1,0x13,0x49,0x8c,0xf4,0x4f,0xd7,0xe9,0x68,0xae,0x09,0x37,0xd3,0x96,0x21,0xe8,0x1f,0x9f,0xa9,0xc6,0x54,0x57,0x63,0x09,0x1e,0x71,0xf2,0x48,0x9e,0x50,0xbb,0xb3,0xf1,0x4e,0x2d,0x1d,0x79,0x69,0x0a,0xa2,0xa9,0xdd,0x1b,0x55,0x62,0x6b,0x0d,0xcc,0x9c,0xb1,0x5e,0xc8,0x4c,0x4f,0x62,0x3c,0xc4,0xa3,0xb4,0xe4,0x34,0xec
+.byte 0x9d,0x0c,0x1b,0x46,0x60,0x68,0xd5,0x04,0xd7,0x1b,0x3c,0x7a,0x98,0x0c,0xd9,0x87,0x2b,0x4f,0x97,0x5b,0x56,0x65,0xb0,0x06,0x6e,0x9e,0x06,0x37,0x0e,0xd2,0xa1,0x52,0xf5,0xaa,0x2b,0xec,0xbd,0x0f,0xb6,0xba,0x48,0x63,0x57,0x51,0xe3,0x00,0x53,0xf5,0x77,0xb2,0xa4,0xb1,0x44,0x01,0x3e,0xcf,0xe9,0x2a,0x7a,0xf5,0x19,0x5e,0x43,0x36
+.byte 0xe0,0x38,0x41,0xbc,0xda,0xb5,0xd0,0x69,0xdf,0xd2,0x04,0xd4,0xf8,0x38,0x37,0x1c,0x90,0x30,0xf2,0x3d,0x03,0xe4,0x3f,0x84,0x2c,0x9a,0xa4,0x8a,0x00,0x4e,0x49,0x24,0x62,0x06,0xb4,0x9d,0x33,0x8a,0x8e,0xd2,0xbd,0x1b,0xa1,0x83,0x0b,0xa5,0xa2,0x5c,0xcf,0xb1,0x65,0x85,0x92,0x1f,0xb0,0x2e,0x3b,0xb2,0xf3,0x80,0xff,0x9d,0x41,0x4d
+.byte 0xcd,0x25,0x09,0x02,0x85,0xb3,0xa8,0x49,0x12,0x10,0xe7,0x5c,0x94,0x13,0x4b,0x52,0x53,0x35,0x9c,0xbc,0x7a,0xad,0x04,0x19,0x54,0x8a,0xbc,0x42,0x73,0xf1,0x0a,0x22,0x75,0xbf,0x3b,0x12,0xa8,0xa4,0x47,0x5c,0x95,0x48,0x60,0x71,0x5c,0x9a,0x39,0x5c,0xdb,0x44,0xe8,0x74,0x92,0x3e,0x2b,0x3b,0x1b,0xb7,0x21,0x98,0xe1,0x87,0x32,0xaf
+.byte 0x4a,0xe3,0xda,0x4a,0x46,0xde,0x15,0x4c,0xdc,0xc6,0x60,0xe6,0xd7,0x92,0x29,0x05,0x21,0x22,0x9b,0xaf,0xc4,0xd7,0x6a,0xea,0x2c,0x82,0x5d,0xc7,0x81,0xe2,0x67,0x85,0xd2,0x16,0x6f,0x83,0xa8,0x82,0x5f,0x8f,0xf5,0x3a,0x50,0xba,0x04,0xcb,0x76,0x4d,0x80,0x16,0x12,0x72,0xa8,0x6c,0xac,0x78,0xf1,0x8c,0x93,0xab,0xe0,0xb5,0xdc,0xd1
+.byte 0xa5,0x40,0x0e,0x50,0x88,0xd2,0x9d,0x56,0xf6,0xa0,0xd4,0x45,0xcf,0xef,0x16,0x1a,0xa4,0xaa,0x91,0x5c,0xa3,0x8f,0x84,0xf8,0x3e,0x30,0x1f,0x5f,0x55,0xf9,0xd3,0x3d,0xb8,0x64,0xbb,0x3c,0x91,0xe4,0x0d,0xa5,0x43,0x14,0x75,0xe7,0xec,0x8c,0x12,0x56,0x34,0xb0,0xa9,0xae,0x93,0x91,0x34,0xfc,0x78,0xa3,0x81,0x51,0x45,0x7d,0x9f,0x7d
+.byte 0x5e,0xc7,0x5e,0x51,0x17,0xfa,0x02,0x5d,0xb2,0xf7,0x79,0x4b,0x49,0xd2,0x1b,0x6f,0xfd,0x9e,0xff,0x75,0x74,0xf0,0x26,0x7e,0xd7,0x65,0xb0,0xf3,0x0a,0x0c,0xd2,0xa2,0x26,0x98,0x03,0x26,0xb5,0x67,0xc4,0xc0,0xed,0x80,0xd4,0x20,0xf6,0x7e,0x17,0x54,0xeb,0xde,0xc3,0x86,0x51,0xda,0xf7,0xe5,0xc7,0xfe,0xfc,0x71,0x83,0x80,0xbe,0xde
+.byte 0x4b,0xda,0x83,0x76,0x63,0x04,0x03,0xdd,0xe0,0xe0,0x4e,0xb6,0x32,0xd5,0xd0,0xce,0xd7,0xaa,0xcd,0x5f,0x64,0xa6,0xd8,0x9e,0xc5,0x97,0x30,0xad,0xf1,0x82,0x8f,0x7c,0x18,0xec,0x30,0x1d,0x2d,0xb6,0xdb,0x33,0x65,0xed,0xe2,0x24,0xd8,0xba,0x0a,0x1f,0x79,0x2a,0x1c,0xe1,0x4e,0x04,0xa6,0x74,0x74,0x37,0x42,0x94,0xc4,0x99,0x0e,0xf8
+.byte 0x3f,0xf3,0xff,0xeb,0x7f,0x95,0x9c,0x47,0x56,0x68,0x6a,0x0d,0x6e,0x66,0x71,0x3b,0x51,0xd5,0x12,0x7e,0x59,0x39,0x43,0xb5,0x53,0xd3,0x1d,0xa2,0xe9,0xa1,0xc8,0x8d,0xf2,0x8e,0xa1,0x9c,0x36,0xdd,0xda,0xd3,0x61,0xd8,0xe9,0x76,0x5e,0xcb,0x0a,0x52,0xc8,0x5a,0x25,0x00,0x21,0xea,0x6a,0x96,0xde,0x02,0x76,0x02,0x63,0x73,0x28,0x63
+.byte 0x46,0x37,0xe1,0x75,0x2f,0x42,0x8f,0xee,0x2c,0x84,0x82,0x43,0x43,0x2d,0xa9,0x13,0x50,0x46,0x54,0xed,0x76,0xbd,0x10,0x1c,0x9b,0xa1,0x42,0x97,0x68,0xca,0x84,0x2e,0x1d,0x6f,0x86,0x67,0xaf,0xb7,0x20,0xc1,0x7c,0xab,0x70,0x20,0xa1,0x79,0x71,0xe4,0xb7,0x45,0x8a,0x04,0xd3,0x70,0x10,0xa8,0x28,0xc3,0x56,0xff,0x43,0x36,0x13,0x88
+.byte 0xb6,0x2d,0xfd,0x7f,0xbc,0xc9,0x1d,0x11,0x9a,0x7c,0xd0,0xfc,0x11,0xac,0x54,0xd5,0xc3,0x03,0xd1,0xe3,0x9e,0xff,0x03,0xdb,0xd9,0xd8,0x77,0x96,0x08,0xf4,0x1b,0xd9,0xfa,0x70,0xed,0xab,0x53,0x78,0xca,0x28,0xa7,0x29,0x49,0x45,0x37,0x10,0x8f,0x61,0x7d,0x11,0x99,0x2e,0xe8,0x5d,0x45,0x3a,0xe7,0xd2,0x6c,0xb6,0x03,0xc4,0x6d,0xaa
+.byte 0x52,0x60,0x8c,0xc6,0x9c,0x17,0xba,0xf6,0x3b,0xd4,0x4b,0x26,0x63,0x92,0x8c,0xb9,0x6a,0xf2,0x26,0x91,0x9d,0x8d,0x99,0x39,0x26,0x7d,0xb5,0x4f,0x4c,0xc6,0x0e,0x2e,0xe1,0xc6,0xcb,0x98,0x93,0x71,0x9b,0xaa,0x01,0x40,0x70,0x93,0x2a,0xe8,0x27,0xc5,0x20,0xa7,0xd2,0x06,0x8b,0xb0,0x29,0xcd,0x4f,0x2c,0x5a,0xde,0x35,0xc7,0x2a,0x8e
+.byte 0xa7,0xae,0x02,0xfa,0x8e,0x4d,0xf3,0x77,0x67,0xe0,0xcb,0x84,0x69,0xc6,0x05,0xe4,0x84,0xe3,0x6e,0x02,0x6c,0x3b,0x93,0x30,0x3e,0x89,0x2c,0xc7,0xa5,0x7e,0xaa,0x58,0x59,0x25,0xf6,0xff,0x56,0x9a,0x4a,0x70,0xbf,0x88,0x20,0x8d,0x51,0x5e,0x08,0x13,0x26,0x2c,0x5d,0x88,0x13,0x3e,0x32,0x7a,0xf6,0x17,0x5c,0xdb,0xc4,0xcd,0x5a,0x16
+.byte 0x65,0xe4,0x34,0xeb,0x21,0x6d,0xb9,0x30,0x5d,0xc0,0xa2,0xea,0x4f,0x63,0x0e,0xbe,0x32,0x91,0x89,0x6f,0x96,0x40,0xf3,0x5f,0xa3,0xf2,0x15,0xc3,0x3c,0x3c,0xb8,0x2f,0x0d,0xc2,0xcd,0x4e,0xa0,0xa5,0xf6,0x78,0x40,0x0b,0x90,0x11,0x52,0xff,0x8f,0x7f,0x6a,0x0c,0xd6,0x3b,0x64,0x80,0x47,0xfa,0x70,0xbe,0x01,0xdc,0xdf,0x5b,0x75,0x7c
+.byte 0xca,0x66,0xf0,0x2a,0x53,0x89,0x55,0x87,0xf8,0xec,0xd1,0x18,0x22,0x0c,0xd5,0x0e,0xc8,0x1c,0xbc,0x1e,0x66,0x14,0x44,0x10,0x3c,0xd4,0x2e,0xca,0x0b,0xd8,0x3f,0x81,0xd8,0x9f,0x81,0xf6,0x62,0x23,0xe4,0xc7,0x0d,0xb0,0x1b,0x00,0xd8,0xf4,0x1a,0xdd,0x9b,0xa1,0x74,0xeb,0xf0,0x65,0x5c,0x82,0x00,0x17,0xa6,0x68,0x29,0xd5,0xa4,0x64
+.byte 0xd3,0x15,0x90,0xd0,0x91,0x17,0xfc,0xd2,0xd7,0xad,0x4b,0xd8,0x41,0x03,0x51,0xfd,0x61,0xac,0x34,0xd4,0xff,0xaa,0xb1,0x64,0x6c,0x79,0x78,0xf7,0x6b,0x18,0x03,0x2b,0x6b,0x9a,0xd7,0xce,0x55,0x6e,0xdd,0xab,0x2e,0xbc,0x27,0x3a,0x8c,0xa5,0x8d,0xf0,0x55,0x81,0x0c,0x6e,0x8d,0xd8,0xd2,0x24,0x5e,0x2e,0x56,0xa8,0x1e,0x9c,0x98,0x88
+.byte 0xd3,0xbe,0x90,0x56,0x70,0xe5,0xcc,0x49,0x2a,0x13,0x98,0x99,0xbd,0xc9,0x9f,0x53,0x85,0x07,0xbe,0x54,0xa7,0x4c,0xd6,0x96,0x7d,0x8f,0x24,0x79,0x67,0xb2,0x62,0x4c,0x6a,0xc1,0x6c,0xb7,0xdc,0xe9,0x21,0xe3,0x27,0xc7,0x53,0xff,0xe7,0xd1,0xea,0x60,0xa8,0x56,0x08,0x5c,0x29,0x0a,0x04,0x0c,0xda,0x7a,0x70,0x8c,0x3d,0x55,0x3f,0xcf
+.byte 0x9e,0xea,0x74,0x8b,0xbc,0xf0,0xf1,0x3a,0x86,0x22,0xe5,0x54,0xa7,0x70,0xc2,0xcd,0xb8,0x9f,0x4e,0x9f,0x48,0xa8,0xc0,0x82,0x0d,0x73,0x8b,0x3c,0xfc,0x20,0xf4,0xbe,0x79,0xde,0x8e,0x3c,0x26,0x85,0xde,0x74,0xd1,0xe3,0xd5,0x8f,0x39,0x71,0x46,0x8c,0xbd,0x68,0x28,0x2d,0x36,0x0d,0x66,0xc1,0x0b,0x96,0x3e,0x11,0x2e,0x44,0x17,0xd5
+.byte 0xfe,0x0d,0x70,0x84,0x96,0x20,0x34,0x2f,0xbe,0xf0,0xf5,0x9b,0xb4,0x5a,0xa9,0x50,0x6a,0xda,0xdb,0x69,0xea,0xef,0xa9,0xaa,0x06,0xc0,0x68,0xa4,0x61,0x1b,0x4b,0xf8,0x0b,0x56,0x91,0xc8,0x6f,0x39,0x15,0xe2,0xcc,0xbf,0x2b,0x36,0x96,0x0c,0x84,0xfb,0x3d,0x4b,0x09,0xe3,0xc2,0x4b,0x05,0x5e,0xfa,0x30,0x75,0xc5,0x54,0xa5,0xbd,0x45
+.byte 0x1e,0x14,0x72,0xd6,0xfd,0xe0,0x8f,0x7b,0x46,0x9b,0x11,0x07,0x27,0x03,0xe1,0x2d,0xcc,0x0a,0x01,0x49,0x61,0xc4,0x61,0x78,0x06,0x5f,0xaa,0x01,0x5b,0x68,0xd7,0x29,0xb4,0x9e,0xd3,0xaf,0xc7,0x45,0xf0,0x23,0xaf,0x28,0xcd,0x96,0x23,0x61,0xb2,0xb4,0x21,0x96,0x5d,0x91,0x3e,0x71,0xb5,0x41,0xf1,0x29,0xf4,0x5b,0x45,0x77,0x16,0x00
+.byte 0x9d,0x39,0x2a,0x1c,0x38,0x6d,0x36,0x97,0x98,0x4c,0x84,0xfc,0xf5,0xf1,0x59,0x7a,0x8c,0x21,0xfb,0xbc,0x9b,0x0c,0x8d,0x60,0xb6,0xc4,0xe3,0x4b,0x33,0x4f,0x04,0x4c,0x27,0xd2,0xa0,0xe1,0x71,0x0b,0x6d,0x40,0x8d,0xba,0xb3,0x11,0x9b,0x07,0x97,0x82,0x01,0x47,0xaa,0x2a,0xd4,0xcc,0x02,0xd3,0x86,0x86,0xb5,0xd7,0x5d,0xbc,0xd0,0x0f
+.byte 0x97,0x5c,0xe5,0xac,0xc6,0x53,0xb3,0x39,0x09,0x68,0x2e,0xcc,0xf3,0x43,0xba,0xed,0x15,0x90,0xbe,0x9d,0xeb,0xa4,0xfb,0x4a,0x20,0xcf,0x10,0xb9,0x47,0x99,0xb0,0x89,0x26,0xb9,0xbd,0x4b,0xf6,0xa5,0xbd,0x2f,0xad,0x1a,0x75,0xe8,0xff,0xc6,0x6b,0x6a,0x31,0xbe,0xec,0xd2,0xc4,0x39,0x9e,0x3b,0x05,0x3f,0x24,0xba,0xf1,0x4d,0x0c,0x0c
+.byte 0x05,0x60,0x60,0x22,0x0c,0x1b,0x0b,0x6c,0x80,0xd5,0xe8,0x8f,0x81,0xee,0x80,0x41,0x4a,0x69,0x47,0xc6,0x4c,0xeb,0xf6,0x2b,0x91,0x7c,0x9f,0x22,0x74,0x7b,0x43,0x95,0x56,0x55,0xba,0x85,0x23,0xb3,0xc3,0xee,0x6a,0xcc,0x49,0x2c,0x6c,0x86,0x6d,0x60,0x5d,0x84,0x0c,0x3c,0x88,0x61,0x58,0x1d,0xfc,0x00,0x2c,0x84,0x49,0x4d,0x95,0x75
+.byte 0xc0,0x03,0x02,0x59,0xc0,0xe9,0x84,0xea,0xce,0x3f,0x8b,0x76,0xbf,0x19,0xaa,0x13,0x1b,0x8d,0x9f,0xb2,0xeb,0xb3,0x02,0x87,0xee,0xfe,0x73,0xdb,0xc4,0x19,0x27,0xaf,0x15,0x8d,0xf4,0x58,0x97,0x43,0xb9,0x45,0x32,0x5f,0x24,0x2d,0x08,0xfe,0xec,0xf2,0xf1,0x34,0x99,0x7a,0x66,0x44,0x3d,0xd4,0xf7,0x82,0xcf,0xca,0x6f,0x53,0x9f,0x0a
+.byte 0x74,0x79,0x9b,0x45,0x5b,0x07,0x92,0x35,0xc6,0xf4,0xd1,0x90,0x2b,0x62,0xec,0x93,0x7b,0x05,0x90,0x75,0xb7,0xb6,0xd9,0x6c,0x30,0xdd,0x9b,0x2a,0x32,0xb1,0xba,0xab,0x1a,0x6c,0x2b,0xd8,0xfb,0x39,0x8e,0x80,0x98,0x6c,0xd0,0xb3,0xf3,0x76,0xe2,0xe6,0x5e,0xee,0xd0,0x29,0xd7,0x57,0x8f,0xc3,0x13,0xcb,0x45,0x90,0x3e,0xa2,0x54,0x88
+.byte 0xd5,0x50,0xd3,0x75,0xed,0x2d,0xa6,0x50,0x11,0x6b,0xb0,0xb6,0xf0,0x1d,0xc9,0x3d,0x1d,0x2a,0xda,0x5e,0x43,0x44,0xf4,0xef,0x3e,0xc7,0xa9,0xe0,0x6d,0x3c,0x38,0xbf,0x84,0x72,0xaf,0xea,0x60,0x15,0x03,0x14,0x77,0xb7,0xb3,0x15,0x4c,0xbc,0xbf,0x55,0x86,0x24,0x73,0x97,0x22,0x9d,0x59,0xa0,0x39,0x76,0x38,0xd1,0x1f,0x25,0xb0,0x64
+.byte 0xf3,0x10,0x67,0xf2,0x7c,0x11,0xf2,0xce,0xbe,0xaf,0x5e,0x2e,0xc5,0xc1,0x01,0xfa,0x80,0xf9,0x87,0xfc,0x5c,0xfd,0x66,0x50,0x01,0xc2,0x00,0x92,0x84,0x0f,0xdc,0xfc,0x10,0xa5,0x6e,0x45,0xf5,0xff,0x58,0x78,0x45,0x5e,0x50,0xbe,0xe3,0xc7,0x25,0x1e,0xdf,0x7f,0x68,0x6f,0xa5,0xb8,0xf8,0x69,0x89,0x5a,0x55,0x65,0xf4,0x96,0xe5,0x7a
+.byte 0xa6,0x89,0x69,0x8d,0xdd,0x4f,0x24,0x5a,0x29,0x92,0x1e,0xca,0x74,0x65,0x7f,0xb8,0x32,0x75,0xb5,0x7b,0x15,0xea,0xeb,0xcc,0xf1,0x23,0x69,0xc7,0x58,0x1c,0x3a,0xaa,0x27,0x0a,0x11,0x79,0xcf,0xc9,0xb6,0xbd,0x9d,0x56,0x47,0x36,0x6b,0x7f,0x82,0xb5,0xa7,0x9f,0x79,0x72,0x16,0xba,0x50,0xef,0x37,0x68,0xdf,0xe0,0xd8,0x0c,0x16,0xcc
+.byte 0x50,0x6c,0x25,0x63,0xc2,0xd6,0x7b,0xef,0xd9,0xa1,0xef,0x62,0x81,0x97,0x51,0x49,0x69,0xe3,0x13,0x6c,0x1a,0xd0,0x64,0x1b,0x3e,0x48,0x25,0x5b,0x34,0xe9,0xee,0x41,0x34,0xfb,0x8e,0x9d,0x3c,0xbc,0xc8,0xcf,0xe7,0xf8,0x72,0x21,0x0f,0x95,0xde,0x57,0xd7,0x2f,0x80,0x97,0xbd,0x8f,0x2c,0xde,0x19,0xa3,0xba,0x5c,0x92,0xa3,0x75,0x83
+.byte 0xe3,0xc9,0x33,0x3f,0x8f,0x09,0xfa,0x0b,0x60,0x0a,0x2f,0xb3,0x45,0x9d,0x8e,0x9d,0xa3,0x66,0x2d,0xda,0x37,0xe0,0x21,0x52,0x74,0x9d,0x59,0xa4,0x9e,0xea,0x15,0x22,0xb0,0xbf,0x3c,0xd4,0x59,0xef,0x27,0x60,0xf7,0xbf,0x5d,0x1d,0x36,0x9a,0xa5,0xfb,0x53,0x90,0x40,0x83,0x3a,0x20,0x3d,0x6b,0x47,0xbc,0xc3,0xe6,0x07,0xfe,0xd0,0x8e
+.byte 0x40,0x42,0x65,0x2b,0x27,0xba,0x69,0x61,0x03,0x36,0x58,0x35,0x7e,0x82,0x53,0xb5,0xe2,0x25,0x31,0xc3,0x77,0xc1,0x91,0x13,0xa4,0x92,0x52,0xea,0x9f,0x43,0x44,0x6b,0x43,0xe9,0x11,0xd4,0x3d,0x53,0xba,0x6b,0x96,0xb5,0x96,0x29,0xa3,0x2a,0x0a,0xf2,0xb5,0x0c,0x5d,0x62,0x37,0xe0,0xd6,0xa2,0xbf,0xcd,0xf9,0x58,0x7f,0xa2,0xfd,0x54
+.byte 0x6a,0xa1,0x90,0xa5,0x61,0x9e,0xa6,0xc2,0xb9,0x80,0x7a,0xb8,0xaf,0x60,0x68,0xa7,0x27,0x77,0x41,0x03,0x4e,0xc1,0x96,0x46,0x23,0x1b,0xff,0xa1,0x37,0x28,0x33,0x27,0xc2,0x99,0xf7,0xcb,0x7f,0x1a,0xfb,0x41,0xc3,0x59,0x11,0xf8,0x39,0x50,0xbd,0x90,0x61,0x4a,0x67,0x4a,0x07,0x5f,0xb1,0x07,0x66,0x0b,0x52,0xad,0x90,0xc2,0xd7,0x4e
+.byte 0x42,0x9e,0xcc,0x5c,0xeb,0xf2,0xdc,0xaa,0x52,0xcf,0x0e,0x7d,0xae,0x3e,0x1a,0x2c,0x9e,0x79,0xfb,0x29,0x10,0x29,0x61,0xa4,0x93,0x9d,0xa9,0xe9,0x71,0xc5,0xf7,0x07,0x13,0xe9,0xbd,0x2e,0x2d,0x0c,0xd6,0xaf,0x54,0x48,0x58,0xc2,0x91,0x37,0xf4,0x61,0x3a,0x96,0x81,0xdc,0x82,0x02,0xff,0xc9,0xf7,0xf7,0x9f,0x9f,0x28,0xd1,0xb1,0xe3
+.byte 0x2b,0x3d,0x85,0xef,0x15,0x82,0x3b,0x9a,0x17,0xee,0x7f,0xd3,0xa5,0x7c,0x41,0x27,0xc9,0x4c,0xe9,0x7a,0x30,0x9f,0xc5,0x34,0xaf,0xc8,0x1c,0x8a,0x7c,0xa6,0xf4,0xdc,0xa6,0xdb,0x68,0xc1,0xa1,0x13,0xb0,0x54,0x49,0x25,0x43,0xc0,0xd4,0x93,0xd6,0x70,0x53,0x3e,0x5f,0xd5,0x42,0x6e,0x78,0xb8,0x15,0x07,0x6a,0x91,0xe8,0xf1,0x2f,0xcf
+.byte 0x07,0x84,0x25,0xb3,0x20,0xb9,0x35,0x25,0xbb,0x26,0x96,0x02,0x25,0xd5,0x83,0x23,0x71,0x6d,0x62,0xa7,0x99,0x73,0x63,0x2a,0x51,0x25,0x34,0x3d,0x51,0x95,0xc7,0x9b,0x01,0x0a,0xab,0x11,0xb2,0x32,0xcd,0xe3,0xef,0x63,0xa4,0x6d,0xdb,0x7b,0xf6,0x5f,0xc5,0xf3,0xe5,0x8c,0x6b,0x0a,0x04,0x33,0x53,0x0d,0xf6,0x13,0x8c,0xb8,0xc7,0xba
+.byte 0xc2,0xf0,0xd4,0xa7,0x1a,0xce,0x7c,0x54,0x72,0x2b,0x89,0xf4,0x05,0x5c,0x30,0x42,0xe5,0x58,0x65,0x3a,0x2e,0xf9,0x40,0xab,0x2b,0xf9,0xc3,0x99,0x40,0x3c,0xb1,0x7b,0x2c,0xdc,0xfe,0x41,0x21,0x71,0x00,0x75,0xbd,0xea,0xf3,0x84,0x88,0x6b,0x9c,0xe2,0x80,0x2f,0xad,0x9f,0x9d,0x0a,0xdf,0xb5,0x38,0x61,0x89,0xfb,0x67,0x45,0x9c,0x39
+.byte 0xf9,0x84,0x54,0xc4,0xd6,0x6f,0x00,0x39,0x90,0x82,0xfa,0xce,0xae,0xe8,0xaf,0xa4,0x97,0x3a,0xfe,0x71,0xaf,0x5e,0x00,0xd1,0x9e,0x33,0x41,0x63,0xca,0xa5,0x5a,0x8b,0x09,0x2a,0x26,0xef,0x96,0xb7,0x5d,0xc4,0x92,0xfa,0x51,0xdb,0x1d,0x63,0x5f,0x7c,0x94,0x53,0x84,0xed,0xa3,0x99,0x07,0x9f,0xdc,0x55,0xb3,0x31,0x67,0x1a,0x63,0x05
+.byte 0xec,0x36,0x79,0x57,0xf8,0x39,0xc3,0xdd,0xd5,0x6a,0x21,0xfc,0x54,0xe6,0x28,0xc4,0xf1,0xd2,0xce,0x02,0x43,0x50,0x30,0x15,0x4d,0x3c,0xd0,0x1c,0xf6,0x7e,0xd0,0xa4,0x86,0xe7,0xf5,0xc2,0x06,0xc5,0xc4,0xa8,0xe2,0xd3,0xc7,0xcf,0xbd,0xab,0x9f,0xe3,0x42,0xc4,0xcd,0x65,0xfa,0xd3,0xcd,0xdf,0x55,0xc4,0xce,0x6e,0xe8,0xfc,0x96,0x0f
+.byte 0xe2,0x92,0xca,0xde,0x37,0x7c,0xc9,0x80,0x4a,0x54,0xe9,0xfd,0x3c,0x4b,0x81,0xb8,0xd9,0x1a,0xf1,0x91,0x5d,0x9d,0xef,0x3e,0xd1,0x78,0xe2,0x1e,0x0e,0x09,0x62,0xdd,0xc6,0xb9,0xde,0x29,0xba,0xb0,0x62,0x49,0x53,0xb6,0x8d,0x9f,0xbf,0x4d,0x77,0xa4,0xd1,0x0b,0xf0,0x31,0x2e,0xe5,0x71,0x2e,0x18,0xa4,0xa7,0xcb,0xa6,0x30,0x24,0x11
+.byte 0x8d,0x16,0x21,0x71,0x6a,0x19,0xde,0x3c,0x5a,0x00,0xa6,0xe2,0x43,0x98,0xe8,0x83,0x10,0x76,0xef,0xca,0x67,0x61,0x80,0x98,0x48,0x06,0xa9,0xcd,0x13,0xa6,0x1e,0x5b,0x2b,0xef,0xb7,0x3a,0x24,0xf7,0x10,0x8d,0xc2,0xaa,0x9c,0x78,0x0d,0xd1,0x54,0xb1,0x4e,0x5a,0x21,0xc2,0xb4,0x11,0x15,0xdb,0xb3,0x9c,0xe4,0xf1,0xfc,0xa5,0x66,0x0c
+.byte 0x56,0x34,0x05,0x14,0x88,0x2c,0xfc,0x3f,0x97,0x30,0xd5,0xd0,0xba,0xa3,0xf1,0x47,0xc0,0xf1,0x59,0x3c,0xda,0x1a,0xc1,0x90,0xae,0x4b,0x26,0xd3,0x5f,0xc9,0x8f,0x62,0x56,0x9c,0x64,0xec,0xda,0x63,0x37,0xa1,0xa2,0x87,0x74,0xcb,0xcc,0x27,0xcb,0x2a,0x97,0x57,0xa3,0xb9,0xac,0xe2,0xbd,0x97,0x93,0x21,0xb9,0x8b,0x82,0xa1,0xe7,0x76
+.byte 0xc1,0x49,0xd6,0xb2,0x52,0x7b,0xd6,0xbb,0x31,0x0f,0x87,0xc0,0xaa,0x91,0x70,0x19,0x76,0xa5,0xea,0xf0,0x87,0x47,0x50,0xc1,0xff,0xf7,0xa6,0x6c,0x65,0xff,0xdf,0x83,0x5c,0x54,0xf0,0xb1,0x18,0xe0,0x13,0x58,0x74,0xc0,0x67,0x0e,0xb8,0xdc,0x59,0x6c,0x19,0xf4,0xee,0x3a,0x07,0x63,0x68,0x1d,0x62,0x60,0xb5,0x71,0xce,0x21,0x61,0x8c
+.byte 0xa5,0x74,0x9b,0x77,0x8e,0x15,0x20,0x18,0x19,0x96,0xf6,0xfa,0xd2,0x6c,0x03,0xcb,0xcb,0x8c,0x91,0x0d,0x29,0x91,0x70,0xc5,0x96,0x60,0x18,0xad,0x65,0x66,0x43,0xf9,0x13,0x97,0xe3,0xe3,0xcb,0xbf,0x68,0x0b,0xb2,0x87,0x9c,0xfa,0x96,0x48,0x14,0xef,0x6e,0xbd,0x45,0xb9,0x2f,0xbb,0x80,0x80,0xc5,0xf6,0x22,0x41,0x9a,0xec,0xdd,0x41
+.byte 0xfc,0xf3,0x0d,0x8e,0x2e,0x3c,0xda,0xef,0x2c,0xbd,0xbc,0x0e,0x88,0xd2,0x97,0x3d,0x40,0x37,0xa6,0xde,0x1d,0x00,0xeb,0x39,0xea,0x44,0xee,0x8a,0x2f,0x77,0xea,0xea,0x1d,0x90,0xd1,0xec,0xe4,0x31,0x0c,0xde,0x6f,0x55,0x17,0x5c,0x1e,0x19,0x91,0xac,0x36,0x00,0x26,0x17,0xa6,0xcd,0x8b,0xe2,0x72,0x6f,0x8f,0x3c,0xc6,0x76,0x6e,0x3d
+.byte 0x4e,0x93,0xb3,0x8b,0xad,0x24,0x17,0x39,0xc0,0xfe,0xba,0x90,0xc5,0xbd,0x4b,0xe4,0xae,0xac,0xf6,0x55,0x72,0x3e,0xf0,0x12,0x32,0x5a,0xdd,0x8a,0x3f,0x67,0xb6,0xdf,0xf6,0x11,0x02,0xf5,0x84,0xcc,0x7d,0x36,0xe7,0x1b,0xf0,0x9a,0x52,0xbe,0xf3,0x06,0xd6,0xdb,0x02,0xd4,0x80,0x0b,0xcd,0xf0,0xfe,0xec,0x86,0x3f,0x89,0x34,0xcb,0x88
+.byte 0x34,0x28,0x57,0x00,0x33,0xeb,0x4f,0xfa,0xdb,0xd8,0x09,0xd9,0x56,0x53,0xc1,0x02,0xc0,0xa8,0x4c,0xdc,0xfd,0x26,0xb3,0x55,0x1d,0x47,0x0d,0x68,0x50,0xb8,0xa3,0xb4,0xf1,0x31,0xfa,0x16,0x33,0x94,0x40,0x95,0x53,0x9c,0x9f,0x5b,0x25,0x47,0xb1,0x27,0xbc,0x38,0x7d,0x23,0x01,0x7f,0x70,0x7a,0x61,0x0e,0x46,0x5c,0xcc,0xd7,0xcc,0x15
+.byte 0x15,0x0a,0xed,0x4c,0x99,0x66,0x3a,0xc3,0xc1,0x9a,0x7a,0x38,0x6a,0x0c,0xde,0x13,0x67,0x65,0xfc,0x06,0x99,0x7c,0xa5,0x90,0x8a,0x90,0x58,0xce,0xf3,0x23,0x76,0xfc,0x03,0xfb,0xb3,0x36,0x54,0xa9,0x33,0x35,0xfe,0xe3,0x3d,0x53,0x7e,0xe0,0xae,0xcf,0xc0,0xa2,0xe1,0x28,0xb9,0x97,0x96,0x87,0x90,0xa1,0x13,0xd0,0x1d,0x5b,0x43,0xf1
+.byte 0xa5,0xfa,0x81,0x83,0xe7,0x7b,0xa1,0x5f,0x9f,0xf5,0xd3,0xb6,0x80,0x8b,0x91,0xed,0x31,0x14,0x05,0x78,0x85,0x9d,0xea,0x59,0x69,0xa5,0x29,0xc5,0xf1,0xd7,0x9d,0xa3,0x8b,0x9d,0xe0,0x8d,0xc3,0x4e,0x2d,0xfa,0x1c,0x6c,0xd2,0xd7,0xcb,0xda,0x86,0x5d,0xb3,0x1a,0xb4,0x12,0xe3,0xa8,0xd7,0xe1,0x84,0xce,0x0e,0x06,0xd0,0x9e,0xf0,0xb1
+.byte 0x5b,0x2f,0x77,0x10,0x6f,0x41,0x2f,0x5b,0x48,0x43,0xf3,0xef,0xdb,0x09,0xdb,0x01,0x89,0xfc,0x7a,0x4a,0xc0,0x96,0x33,0xdf,0xbe,0x49,0x85,0xa7,0x88,0x93,0x05,0xf2,0x15,0x12,0x85,0x04,0x20,0x7d,0x8c,0xe2,0x0a,0xea,0xfe,0xed,0xbf,0x98,0xdb,0x9d,0x1f,0xaf,0x0f,0xbf,0xf7,0x12,0x4f,0x69,0x4e,0x87,0x09,0xf0,0xae,0x2a,0x4d,0x4c
+.byte 0xbf,0xaa,0x08,0x2c,0x78,0x2d,0xbe,0xb9,0xf5,0x3c,0x4c,0xcd,0x75,0x93,0xc3,0x3c,0xc2,0x86,0x47,0xca,0xc1,0x9c,0x1c,0xe5,0x0d,0x8d,0x36,0x9c,0x44,0x40,0x89,0xfa,0x17,0x57,0x08,0xd4,0x22,0x9a,0x5b,0x94,0xbf,0x39,0xcd,0xbe,0xf7,0xd1,0xcd,0x35,0x74,0xdf,0xfa,0x5d,0x00,0xaa,0xaa,0x82,0x6d,0x9b,0xf8,0x69,0x51,0x9c,0xaa,0xaa
+.byte 0xc8,0x2c,0xa2,0x68,0x57,0x3c,0x5f,0x10,0xa2,0x7b,0xee,0xc9,0x97,0x8d,0x5c,0x41,0x08,0x0d,0x30,0xd5,0x2b,0x5f,0x8d,0xdd,0xdc,0x2c,0xa8,0x52,0x6e,0xea,0x61,0x77,0xca,0x75,0xc3,0x56,0x6e,0x17,0x51,0x0e,0x00,0xb6,0x18,0xa0,0xe5,0x9d,0x49,0x4e,0x20,0x78,0x1e,0x5f,0x3e,0xec,0xc3,0x4a,0x41,0xf3,0xfe,0x89,0x64,0xac,0x4c,0x4d
+.byte 0xa8,0x73,0x4f,0x31,0xc4,0xe2,0x62,0x69,0x2b,0x40,0xdf,0xef,0xed,0xf0,0x62,0x4e,0xc3,0x65,0xcc,0xcb,0xef,0xc1,0x28,0x61,0x71,0xac,0xa5,0x89,0x52,0x7b,0x32,0x59,0xc2,0x16,0x1a,0x63,0x18,0xb0,0xd8,0xe4,0x28,0x92,0xff,0x45,0xc1,0x24,0x56,0x86,0x66,0x23,0x7a,0xff,0xf7,0x33,0x30,0xdc,0xd1,0x7d,0xaf,0x68,0x10,0x4b,0xde,0x3e
+.byte 0x4a,0x70,0xbe,0x31,0x1a,0x37,0x28,0xee,0xe0,0xba,0x65,0x8b,0x7d,0xea,0x07,0xce,0xf2,0x51,0x3d,0xcb,0xb2,0x33,0xd8,0xf3,0xa4,0xa0,0xcd,0x53,0x76,0xf9,0x46,0x5b,0x82,0xf9,0x9d,0x0e,0x29,0x5b,0xcf,0x76,0xd4,0x5c,0x47,0xf1,0x98,0x02,0x5a,0x16,0x18,0xf2,0x61,0x6d,0x3e,0x64,0x7f,0xbe,0x13,0x18,0xc2,0x45,0xd2,0x87,0x17,0xff
+.byte 0xf1,0x01,0x0b,0x5d,0x21,0x0d,0x73,0x9a,0xeb,0x82,0xc4,0x9a,0xb3,0xe4,0x31,0x44,0x58,0xa2,0xfd,0x76,0xf6,0xbe,0x6f,0x75,0xcc,0xbb,0xe3,0xa2,0xa9,0x78,0x0f,0x4b,0x1d,0x47,0x2d,0x32,0x2c,0x45,0x5e,0xcd,0x8f,0x13,0xe2,0x9a,0x9d,0xa2,0xce,0x73,0x54,0x20,0xc0,0x44,0x1c,0x26,0xde,0x0d,0x72,0xb2,0xfa,0x4d,0x32,0x35,0xac,0x69
+.byte 0x4d,0x16,0x4a,0xd5,0x51,0x33,0xc1,0xe0,0x90,0x9c,0x93,0x66,0xed,0x16,0xac,0x7e,0x79,0x2b,0x0f,0xb4,0x42,0xaf,0x80,0x22,0x80,0x07,0x7d,0x72,0xe4,0xb3,0x3a,0x2c,0xb8,0x68,0x14,0x4d,0x31,0x5f,0xbb,0xac,0x43,0x3b,0x28,0xd6,0x81,0x81,0x26,0xe5,0xc4,0x67,0x7c,0x4a,0x42,0xc4,0x1a,0x59,0x04,0x2d,0xb8,0x26,0xfc,0x4e,0xc7,0xfc
+.byte 0x11,0x61,0xe3,0x4b,0x2c,0x3f,0xdb,0x43,0xe4,0x24,0xb4,0xd1,0xc0,0xc0,0x01,0xe1,0xeb,0x84,0x0b,0x6d,0x93,0x83,0x07,0x9f,0x01,0xb8,0x9d,0xe5,0x7e,0x4d,0xa2,0x05,0x3e,0xf2,0x40,0x59,0x88,0xc8,0x8c,0x62,0x44,0x95,0x20,0x96,0x28,0xa9,0x3f,0x7c,0xed,0x85,0x03,0x65,0x49,0xf7,0x94,0x3d,0x51,0xe2,0x8e,0x21,0x19,0x7b,0x55,0x5f
+.byte 0x55,0x70,0xf8,0xf0,0xce,0xd9,0x1a,0x10,0xbb,0xfe,0x65,0x72,0x8a,0x5b,0x6c,0x27,0xd3,0x57,0x61,0x07,0x7b,0x85,0xd6,0x21,0xd2,0x07,0x81,0xaa,0x17,0x73,0xb5,0xef,0x2d,0x84,0x7b,0x8f,0xe0,0xb3,0x9e,0x9f,0x31,0x82,0x33,0x07,0x14,0x84,0x79,0x18,0xc4,0xec,0x20,0xb5,0xec,0x21,0x4b,0x51,0x78,0x96,0xc6,0xe7,0xf0,0x6a,0x7a,0xb5
+.byte 0xe5,0xc2,0xef,0x24,0x4c,0x57,0xb6,0xf5,0xee,0xe5,0x69,0x2b,0x73,0x9e,0x66,0x91,0x9d,0xd4,0x24,0x58,0x4b,0x72,0x68,0xf6,0x62,0xb4,0x0c,0xe3,0xbd,0x1f,0x0b,0x42,0x6c,0xf9,0x6e,0x6a,0x64,0x64,0x69,0xa5,0x6d,0xe7,0x38,0x9f,0xb2,0x65,0x35,0x6b,0xd9,0x20,0x84,0xe4,0x5f,0x8b,0xfd,0x58,0xab,0x5f,0xe1,0x4c,0xf7,0xd7,0xf5,0xe7
+.byte 0xae,0xe8,0xc1,0x68,0xfe,0x0c,0xb1,0xe2,0xe4,0xca,0xf0,0xf1,0x20,0xbc,0xf9,0x99,0xef,0x4e,0x63,0xca,0x89,0xe4,0x7c,0x17,0x49,0x40,0x47,0xce,0x67,0x8e,0xbd,0xd0,0x96,0x8b,0x5a,0x0d,0x2f,0xd0,0x8f,0x4f,0x42,0x06,0x01,0x8e,0x47,0x35,0x13,0x9e,0xd1,0x24,0x85,0xe4,0x17,0x59,0xe8,0x1c,0xb3,0x25,0x53,0xf9,0xb4,0x96,0xb1,0x33
+.byte 0x97,0xb2,0x60,0xc7,0xb3,0x48,0xa2,0xfc,0x7f,0x86,0x94,0x2a,0xd3,0x94,0xfe,0x6d,0xa6,0x7a,0xa1,0xe1,0x96,0x5b,0xe8,0xe4,0x91,0xfb,0xf3,0x2c,0x84,0xb4,0x2f,0xbe,0xc9,0xdd,0x1c,0x9f,0x72,0x12,0xcb,0xbd,0x22,0x07,0xc4,0xec,0x05,0xe8,0x32,0x47,0x21,0x27,0xf6,0xc1,0x36,0x59,0x25,0x6c,0xbe,0xb9,0x3e,0xd4,0x1b,0x59,0x11,0x27
+.byte 0x6b,0xa3,0x64,0x71,0x98,0xeb,0x21,0x65,0xc0,0x4c,0x30,0xbd,0x51,0x2b,0xc3,0xfb,0xb1,0x33,0x56,0x1e,0xf0,0x92,0x0f,0x4b,0x63,0x3a,0x9c,0xfb,0xd1,0xac,0x8c,0xf0,0x3e,0xb7,0x0b,0xd2,0x52,0x62,0xd8,0x37,0x9a,0xef,0x79,0xdc,0xcb,0x87,0x1e,0x3d,0x9d,0x91,0x12,0xba,0x78,0x8a,0x11,0x57,0x96,0x44,0x8e,0x2b,0xd2,0xe3,0x4d,0x27
+.byte 0xec,0xba,0xef,0x1c,0x04,0x8d,0x56,0x56,0x11,0x74,0xc0,0xcc,0x1f,0x3d,0x7a,0xad,0x79,0x49,0x59,0xa3,0x71,0xe0,0xf5,0x89,0x89,0x8f,0xcf,0x1e,0x63,0x77,0x91,0x91,0xf1,0x0c,0x1c,0xcc,0x77,0x00,0xd7,0x28,0x9f,0x68,0xbc,0xb6,0x9d,0x33,0x43,0xb2,0x4a,0x72,0x3e,0x57,0x26,0xd0,0x00,0x93,0xc9,0x4c,0xc9,0x53,0x52,0xd9,0xe2,0x31
+.byte 0xc5,0x7f,0xf6,0xb6,0xc2,0x10,0x51,0x67,0xae,0x63,0x35,0x74,0xcc,0xd4,0x05,0xb3,0x08,0x23,0x35,0x37,0x8e,0xf1,0xbb,0x1d,0x56,0xff,0x62,0xa2,0x13,0x7b,0x01,0x75,0x6d,0xb3,0x92,0x51,0xdc,0x6e,0x08,0x76,0x25,0x52,0xbf,0x9a,0xea,0x89,0x0f,0x96,0xcc,0x79,0xd4,0x72,0xcf,0x65,0x79,0x4e,0x40,0xa3,0xae,0x67,0x0c,0x82,0x85,0x05
+.byte 0xfd,0x43,0x84,0x17,0x24,0x79,0xa9,0xa7,0x7f,0x24,0x76,0x57,0x66,0x11,0xd5,0x33,0x30,0x42,0x5b,0x5f,0x7c,0x04,0x4b,0x45,0xc3,0x69,0x20,0x02,0x92,0xe3,0x6a,0x06,0x8f,0xdf,0x30,0xf6,0x17,0x8f,0xc6,0x8c,0x5e,0x42,0xf3,0x59,0x7a,0x3a,0x55,0x3a,0xc1,0x96,0xd5,0x67,0x3d,0xab,0x32,0xee,0xf0,0x08,0x28,0x73,0xb0,0x11,0x1a,0x92
+.byte 0x4d,0xcc,0x0c,0x86,0xb2,0xa1,0xbf,0x9f,0xcd,0xc7,0x1c,0xbc,0xee,0x39,0x77,0x75,0xfc,0xe6,0x3b,0x62,0xf2,0xaf,0xd5,0xb6,0x77,0x2d,0x86,0x38,0x13,0x00,0xdb,0x71,0x4a,0x87,0x03,0x6d,0x99,0x28,0xf8,0x6a,0x23,0x2e,0xe2,0xb8,0x9c,0x18,0x02,0x00,0x9e,0x5b,0xf0,0x6f,0x9b,0x32,0xdc,0x6b,0x61,0xeb,0xeb,0xe9,0xfc,0xee,0x44,0xbc
+.byte 0x4a,0x88,0x04,0xc0,0x10,0xc8,0x65,0x6c,0xa4,0xae,0x9a,0x36,0xb6,0x68,0xd5,0xbf,0x6d,0xe3,0x6f,0x5d,0xad,0xd6,0xf9,0xc8,0x06,0x36,0x25,0x64,0xc9,0x5b,0x71,0x7f,0xbf,0xe3,0x56,0x31,0x2a,0x93,0x47,0x46,0x39,0x91,0x80,0xc5,0xdd,0xdd,0xa1,0x25,0x85,0xd9,0x05,0x49,0x4f,0x1b,0xeb,0x2f,0x6e,0xd9,0xe4,0x65,0x3d,0xcd,0xbd,0x47
+.byte 0x37,0x27,0xb0,0xd1,0x9b,0xa4,0x89,0xd5,0xa0,0x0f,0x8b,0xc5,0xfd,0x91,0xa8,0x86,0x22,0x65,0xf1,0xe1,0x1e,0xb6,0xf7,0x50,0xe6,0x1e,0xf0,0x2b,0x9d,0x02,0xc9,0xe8,0x2a,0xb8,0x9b,0x89,0x28,0x25,0x43,0xcf,0x23,0x08,0xe2,0xa7,0x70,0x31,0x89,0xab,0x5b,0xd9,0x2e,0xa9,0xe4,0xe9,0x1d,0x63,0x7f,0xc6,0xc1,0xfb,0x63,0x45,0x9c,0xf1
+.byte 0xd4,0xc3,0x56,0xb6,0xad,0xb3,0x00,0xce,0x12,0x9e,0x63,0x33,0x25,0xd3,0xb2,0xee,0xa7,0x6b,0xa1,0xfd,0x20,0xa3,0xb2,0x07,0x1a,0x9d,0xed,0xe0,0x1d,0x70,0x5b,0x9f,0xc0,0xbc,0x83,0x09,0x94,0x47,0x8c,0x05,0xef,0x73,0x96,0x31,0xc7,0x35,0xc2,0x2c,0x00,0x2a,0x68,0xd1,0xc4,0xb3,0x3d,0x84,0x44,0x8c,0x93,0xfd,0x64,0x00,0x77,0x46
+.byte 0x18,0xac,0x83,0x9d,0xe5,0xe5,0x46,0x61,0x37,0x72,0x9f,0x0e,0x76,0x55,0xf7,0xca,0x36,0x57,0x24,0x16,0xfc,0x11,0x27,0xaa,0x44,0xa4,0xb0,0x58,0x41,0x46,0x94,0xc7,0x3b,0x9c,0xa3,0xe4,0x89,0xd9,0xdb,0x7b,0x64,0x69,0x84,0x9f,0xc8,0x09,0x6f,0xf7,0xf0,0x58,0x10,0x56,0x9f,0x26,0xf0,0x74,0x0c,0x76,0xcb,0x9d,0x45,0x3d,0xe7,0x94
+.byte 0x54,0xa3,0x84,0x08,0xb5,0x9c,0xff,0xdb,0xba,0x62,0x5e,0x87,0x0d,0x11,0x5d,0x96,0x06,0xd6,0xec,0xf4,0x3e,0x9d,0x66,0xbd,0xc4,0x64,0xed,0x03,0xe0,0xad,0x3f,0x4e,0xb4,0xef,0x16,0xdd,0xee,0xd6,0x00,0x27,0x62,0x74,0x0a,0xe0,0x68,0x72,0x4c,0x6d,0x62,0x15,0x87,0x6a,0xf0,0x25,0x9f,0x33,0x1d,0x92,0x3b,0xa3,0xa4,0xf1,0x81,0xdf
+.byte 0xa8,0xed,0xaf,0xa5,0x8d,0x19,0x20,0x72,0x03,0x91,0xf0,0x34,0x60,0x70,0xbe,0xaa,0xdf,0xaa,0x24,0x1a,0x1f,0x1a,0x8d,0xb0,0x7b,0xef,0x10,0x43,0x69,0x24,0x74,0xf2,0x72,0x71,0xa1,0x8f,0x85,0x75,0x3e,0x8c,0xf6,0x0e,0x88,0xe2,0x1d,0x5c,0xb8,0xf1,0xc4,0x8a,0x21,0x76,0x20,0x50,0x3f,0xb3,0x8b,0x9f,0xa4,0x45,0x9e,0x07,0x60,0x22
+.byte 0x2c,0xa6,0xb1,0xc2,0xd2,0xcb,0xc6,0xd8,0xe9,0x94,0x66,0xfb,0x10,0x73,0x92,0x25,0x7e,0x31,0x42,0xf4,0x4a,0x75,0xac,0x78,0x43,0xcb,0xc0,0xc9,0xb0,0xaf,0xb4,0x22,0x8f,0x51,0x36,0x0f,0x5a,0xb8,0xbb,0x44,0x03,0x09,0xd0,0xf9,0x04,0xc8,0x73,0x8e,0xa1,0x76,0x27,0xde,0x72,0xf4,0x3a,0x79,0x63,0x85,0x32,0x09,0xad,0x12,0xe4,0xd7
+.byte 0x8f,0x8e,0x24,0x03,0x4f,0xde,0x39,0xac,0x81,0xe8,0x64,0x09,0x17,0xd7,0x99,0xe6,0x62,0xb7,0x53,0x20,0x9f,0xb9,0x3a,0xb9,0xb1,0x81,0xfa,0x6e,0x33,0xe7,0x4a,0xca,0xd7,0xa7,0xfa,0x7a,0xbf,0x0b,0x0a,0x99,0x3c,0xc7,0xbd,0xef,0xc7,0x90,0xda,0x62,0x30,0xc6,0x94,0x94,0x6b,0xee,0xbd,0xb7,0x0d,0x86,0xc5,0xb1,0x9a,0xb9,0x86,0x34
+.byte 0xc2,0x81,0x2b,0x09,0x7a,0x88,0x09,0x65,0xcf,0x51,0x78,0x19,0x1d,0x5a,0x62,0x2f,0xb3,0x43,0x8d,0xf5,0x9d,0x26,0x2f,0x4a,0x27,0x96,0x22,0x1b,0x4c,0xc8,0xd9,0x73,0x4b,0x32,0x01,0x11,0x7b,0x59,0x85,0xda,0x50,0x92,0x17,0x45,0xd4,0x1f,0xcf,0x98,0xf6,0x2c,0x69,0xba,0x43,0x22,0xdc,0x36,0x31,0xfb,0x1e,0xe8,0x54,0x24,0x0f,0x24
+.byte 0x4c,0xcd,0xbe,0xdb,0xd8,0x23,0x69,0xe2,0x97,0xf5,0x66,0xb2,0x66,0x6c,0xf2,0x90,0xd0,0x15,0x14,0x9a,0x47,0x65,0x97,0xb0,0xf2,0x3e,0x35,0x09,0xd2,0x3d,0x01,0x9c,0xb3,0xfd,0xf3,0x32,0x46,0x4e,0x11,0xab,0x88,0x9e,0x04,0x6d,0xf0,0xe1,0x9d,0x48,0x01,0x24,0xc3,0x87,0xdf,0x58,0xb6,0x6d,0x6d,0x4f,0xb9,0x1b,0x13,0xee,0x03,0x5b
+.byte 0x75,0x39,0x28,0x31,0x90,0x70,0x49,0x10,0x71,0x87,0x76,0x30,0xac,0x88,0xb0,0xf6,0x6c,0xaf,0x5b,0xf4,0xf3,0xe7,0x25,0x75,0x8c,0xa3,0xf4,0xa7,0xd8,0x94,0x78,0xc8,0x77,0xc1,0x48,0x6c,0x62,0xf6,0x2c,0xb5,0x41,0x59,0xf6,0xd3,0xae,0x1b,0x55,0xed,0xdf,0xd1,0x59,0x63,0x76,0x03,0x65,0xd3,0xd0,0xcd,0xb6,0x5b,0x8f,0x1a,0x78,0x88
+.byte 0x78,0x07,0x14,0x3f,0xc3,0xd4,0x1c,0x69,0xd8,0x15,0x25,0xca,0x76,0x15,0x24,0x7d,0xed,0x69,0x2a,0xb5,0x04,0xd2,0x3b,0xbd,0x7a,0xb2,0xae,0x04,0x51,0x85,0x2b,0x1b,0xb0,0x3f,0x6d,0xbc,0xa0,0xc7,0x19,0x40,0xab,0x75,0x51,0x4b,0xa8,0x5a,0xd7,0xb5,0xc7,0xa8,0xfc,0x4a,0xcf,0xa9,0x9c,0xe6,0x2e,0x35,0x51,0x3b,0x05,0x41,0x43,0x7c
+.byte 0x1f,0x2e,0x16,0x5d,0x2f,0xa8,0xe9,0xce,0x6d,0x06,0xa7,0x5a,0xed,0x07,0x39,0xe4,0x7e,0xc3,0x01,0x2d,0x97,0xe4,0xc1,0x89,0x2c,0xb4,0xb1,0xb5,0x7f,0x0a,0xe2,0x9f,0x82,0x36,0xee,0x9b,0x76,0xbc,0x9d,0x37,0xdf,0x5e,0x81,0x95,0x9b,0x2b,0xc4,0x58,0x20,0x6a,0xd2,0xc7,0xb6,0x82,0xe6,0xa2,0x52,0x73,0x4a,0xaf,0x37,0x5a,0xf6,0x6b
+.byte 0xc4,0x2b,0x53,0x4e,0xca,0x44,0x17,0x9f,0x1c,0xeb,0x4d,0xf2,0xd1,0xb0,0x35,0xaa,0xc3,0xfe,0x77,0x34,0x2a,0x4a,0xe8,0x85,0x96,0x2f,0xa4,0x7d,0xdf,0xd0,0x6a,0x4a,0x0c,0x9b,0xd9,0x6a,0x00,0x92,0xb4,0xb1,0x9f,0xc3,0x56,0xee,0xcb,0xa5,0x3a,0x37,0x68,0xc8,0x7c,0x1e,0xa8,0x0a,0x3d,0xbc,0xd1,0xd0,0xd7,0x8b,0x32,0x34,0x20,0xfc
+.byte 0xd3,0x9e,0xf5,0x18,0x3a,0xb9,0x87,0xae,0xde,0x6c,0xc0,0x7d,0xbd,0x20,0x00,0xe5,0x7b,0xcb,0xf9,0x7d,0x70,0x9a,0x10,0x45,0xc9,0x33,0x13,0x9d,0x2c,0x16,0x67,0xe6,0x36,0x38,0xcf,0xa2,0xf1,0xad,0xec,0x48,0x7f,0x9b,0x2a,0xdc,0x13,0xe2,0xee,0xef,0xf2,0x5c,0x3f,0x52,0x3a,0x72,0x79,0x9b,0xba,0x50,0xb2,0x2b,0xfb,0x97,0x8e,0xe6
+.byte 0x27,0x39,0x63,0x72,0x05,0x11,0x7d,0x2e,0xa8,0x44,0x08,0xf7,0xf3,0x26,0xe5,0xe4,0x6c,0x98,0x7b,0xb1,0x42,0x6d,0x74,0xd4,0x3b,0xfa,0x35,0xfa,0x0a,0xac,0x5e,0x9e,0x8f,0xc7,0x07,0xc5,0x50,0x25,0xfd,0xbf,0x13,0x52,0x3d,0xf1,0x18,0x1e,0x19,0x8c,0xf3,0x8b,0x4d,0xc8,0xfb,0x76,0xa4,0xe3,0x3f,0xb2,0x47,0x9c,0x50,0x97,0x32,0x65
+.byte 0x9e,0x42,0x81,0x21,0xd1,0x92,0xd2,0x81,0x4a,0x93,0x68,0xa2,0xc1,0x76,0xc8,0x40,0xce,0xfe,0x4e,0xc5,0xa7,0xb2,0x77,0x9f,0xc8,0xe5,0x41,0xb1,0xda,0x15,0xf6,0xfa,0x21,0x3f,0x11,0x5c,0xc6,0x62,0xda,0x01,0x7f,0x0f,0x9f,0x9e,0x98,0xfe,0x38,0x53,0x6c,0x7f,0xba,0x8b,0x55,0x01,0x36,0x33,0x41,0x5e,0xa9,0x78,0xbf,0x2e,0x60,0x4f
+.byte 0xcb,0xe9,0x27,0x09,0x8c,0x01,0x2d,0x82,0x7d,0x3f,0xaf,0x8f,0x1e,0x37,0x79,0x35,0xfb,0xce,0x83,0xc5,0xf8,0xc5,0x54,0xfd,0x50,0xec,0x31,0xd1,0xb5,0x8a,0x4d,0x37,0xf6,0x7f,0x0e,0xbe,0x35,0xdd,0xa8,0x9e,0x5e,0xb9,0x3c,0xf4,0x2b,0xd2,0x97,0x56,0xd0,0x28,0xcb,0x60,0x27,0xcf,0x27,0x68,0x8a,0xa1,0xbf,0x9f,0xa3,0x45,0x4a,0x44
+.byte 0x71,0xe2,0xb2,0x9c,0x69,0x0b,0x18,0x69,0xcf,0x03,0xcc,0xc3,0x93,0xe0,0xf5,0xb7,0x4e,0xa4,0xdc,0x96,0xe0,0x2e,0xf8,0x3b,0xc6,0x67,0x30,0x06,0x5e,0xb9,0xb9,0x7d,0xaf,0x97,0x38,0x9a,0xf4,0x22,0x20,0x5a,0x9e,0x83,0x26,0x3c,0xcc,0x93,0x84,0x20,0x15,0x2e,0x85,0x23,0x17,0x1d,0x28,0xb4,0xe2,0x8f,0x2d,0x22,0x99,0x66,0xfd,0x6a
+.byte 0xa8,0xe6,0xb7,0x19,0x18,0xec,0xbd,0x54,0xc2,0xcc,0xb7,0xb4,0x6b,0x10,0xdd,0xb5,0xe3,0x3b,0xb7,0x77,0xbf,0x66,0x65,0x82,0x6a,0xc6,0x0d,0x26,0xe6,0xe8,0xe1,0x96,0xe4,0x0b,0x3c,0xe3,0xf2,0xfb,0xd6,0x91,0x5d,0xb6,0x08,0x15,0x67,0x10,0xfa,0xf8,0xdc,0x72,0x84,0xca,0x48,0x29,0x75,0x98,0x62,0x30,0x43,0xa9,0xf1,0xde,0x58,0xb5
+.byte 0x6e,0x67,0x53,0x62,0x0d,0x06,0xa8,0x97,0x35,0x04,0x02,0x34,0x3f,0xd7,0x77,0x38,0xed,0x51,0x32,0x7c,0x6f,0x25,0x94,0x04,0x30,0xa5,0xfc,0xf1,0xb0,0x65,0x77,0x16,0xec,0xb0,0xf9,0x6d,0xaf,0xbc,0x75,0x6e,0x29,0x44,0x20,0x86,0x36,0xbe,0x22,0xe0,0xe1,0xc4,0x0c,0x97,0x10,0x45,0x3e,0x06,0xc3,0xee,0xa5,0x1f,0x97,0xc7,0xde,0xdb
+.byte 0xf1,0x05,0xe3,0xb7,0x24,0xc5,0xa5,0xca,0x4e,0x8e,0x9e,0x44,0x7e,0x98,0xb1,0x3c,0xe9,0xa6,0xe5,0xa6,0x08,0xcb,0x08,0xd7,0xf6,0x38,0x37,0xa4,0x46,0xd1,0xdc,0x53,0x6f,0x6c,0x3f,0xca,0xa1,0x9b,0x7c,0xa6,0x44,0xd4,0x08,0x33,0xd2,0xf8,0x32,0xd2,0x4f,0x60,0x75,0x0f,0x49,0xf1,0x70,0x52,0x56,0x16,0x5b,0x3e,0x34,0x0e,0xe4,0x94
+.byte 0xc3,0xa9,0xd4,0x1c,0x9e,0xa4,0x10,0xce,0xc1,0x69,0x5b,0x3a,0xc9,0xd5,0xab,0x98,0x81,0x78,0x42,0x7e,0xf2,0x76,0x10,0xad,0x97,0x85,0x98,0x2f,0xe2,0x3f,0xb1,0x1d,0xc0,0x4d,0xa4,0x0b,0x54,0x7e,0x19,0x16,0x0a,0x71,0x74,0x37,0xfd,0x67,0x23,0x86,0xb2,0x3b,0x1e,0x49,0x92,0x92,0x1b,0x5f,0x65,0x56,0x76,0x6d,0x97,0x3b,0x91,0xc0
+.byte 0x5a,0x7e,0xf1,0x5b,0xe9,0x83,0xb9,0x67,0x2f,0xe1,0x0c,0xcf,0xe9,0x51,0x26,0x45,0x03,0x06,0x63,0xa4,0xb2,0x06,0xe0,0x8e,0xa3,0xbf,0xf5,0x7c,0x19,0xdf,0xfe,0x38,0x28,0x98,0xa1,0x23,0x16,0x69,0xc4,0x9f,0x20,0xe4,0x42,0x27,0x4e,0x7b,0xc9,0x42,0x5e,0xd2,0xb9,0xbf,0x33,0x03,0xbb,0x96,0x6d,0x80,0x65,0x90,0x3b,0x82,0x5b,0x68
+.byte 0x46,0x4f,0xe3,0xe0,0x0e,0xc5,0x90,0x91,0x80,0xf8,0xf4,0x9c,0xfe,0x03,0xaf,0x31,0x44,0xb7,0xfc,0x1f,0x65,0xc8,0x65,0x68,0xcc,0x27,0xb4,0x0d,0x81,0x14,0x9e,0x52,0xab,0xdd,0x71,0xf6,0xd9,0xcf,0x29,0x04,0xcd,0xae,0x6f,0xd6,0x41,0xb5,0xfd,0x1d,0x0f,0xbf,0x71,0xc2,0x60,0x98,0xb9,0xc0,0x6e,0x8a,0x2c,0x7d,0xec,0x31,0xa5,0xea
+.byte 0x1a,0xb1,0xe4,0xc2,0x36,0xcb,0xf0,0xf4,0x3f,0x1d,0x03,0x01,0xcd,0xac,0xd0,0x9d,0x2e,0xa3,0xc4,0x54,0x49,0x75,0x90,0xac,0x7e,0x1e,0xc3,0x90,0xab,0x55,0xb0,0x34,0x0d,0xd6,0x99,0xb5,0x40,0xda,0xdd,0x30,0x57,0x61,0x15,0xec,0x8f,0x8c,0xc7,0xda,0xfc,0xf5,0x0a,0x86,0xd8,0x6b,0x0f,0x6e,0x09,0xb8,0x50,0x2a,0xea,0x51,0x84,0x33
+.byte 0x7a,0x97,0x0c,0x56,0x61,0x2c,0xd9,0x83,0xb9,0xb1,0x53,0x31,0x72,0x20,0x79,0x85,0x7f,0xdc,0xb8,0xfe,0xfa,0x9a,0xd4,0x6a,0x3c,0xc7,0xcc,0x75,0x20,0xba,0x9c,0xb9,0x1a,0xff,0x9c,0xbe,0xfd,0x87,0xb4,0xd7,0xe8,0x5e,0x22,0x6a,0x1b,0x91,0x52,0x6a,0x58,0xbc,0xf4,0xde,0xcc,0x18,0x37,0x0e,0xf5,0x22,0x91,0xd2,0x4f,0x08,0x91,0x62
+.byte 0x1c,0xb7,0xa0,0x7e,0x66,0x97,0xda,0xa0,0x3c,0xc8,0xe8,0xdc,0x61,0xa4,0x64,0x8b,0x0a,0x43,0x90,0x0c,0x78,0xd9,0x96,0x8a,0xb0,0x17,0x0f,0x32,0x17,0x11,0x82,0x69,0x9d,0x7c,0xa9,0xfd,0x9b,0xe3,0xeb,0x0d,0x44,0x1d,0xcb,0xf6,0xee,0x26,0x6b,0xd5,0x4c,0x49,0x69,0x18,0xd7,0xf3,0x63,0xd9,0x7e,0x83,0xdd,0xa3,0x2d,0xdf,0x88,0x10
+.byte 0xd1,0x5c,0xb0,0x7e,0x44,0xfe,0x64,0x39,0x33,0x05,0x04,0x54,0x74,0x4d,0xd5,0xbc,0xdf,0x19,0x52,0x81,0x60,0x92,0xc5,0x4e,0xa4,0xff,0xf0,0xa2,0xfd,0x88,0x96,0xde,0xb4,0x8d,0x58,0x06,0xfb,0x96,0x6f,0x0e,0xb0,0x4a,0x2b,0xed,0x15,0xa7,0xfb,0x9f,0xf2,0x30,0xc4,0xce,0x02,0x4d,0x83,0xb8,0x5d,0x10,0x60,0xb8,0xbc,0x05,0xa2,0xd4
+.byte 0xf1,0xae,0x46,0x56,0xb9,0xac,0x68,0x79,0x41,0x90,0xee,0x79,0xda,0x3a,0x91,0x7a,0xf6,0xdb,0xe3,0xea,0x91,0x48,0x77,0x4a,0xa3,0xab,0x9c,0x99,0x49,0x1f,0xc9,0xcd,0xe7,0x2e,0xe3,0xe7,0x78,0x6d,0x07,0x1b,0xc6,0x08,0x48,0xd8,0x20,0xff,0x19,0x8a,0x73,0x1d,0xc6,0xa1,0xd4,0x95,0x33,0xf7,0x45,0xab,0xea,0x05,0x3e,0xdf,0xde,0x68
+.byte 0xb2,0xb6,0xef,0x71,0xb4,0xd1,0x09,0x4b,0x43,0x16,0x35,0x1a,0xb6,0xcb,0x78,0x63,0xca,0x9e,0x9a,0xe3,0x86,0xb2,0x8e,0x7b,0x68,0x89,0xa7,0x5c,0xd3,0x06,0x21,0x88,0x94,0xde,0xa1,0xb1,0x3a,0xe8,0xb7,0xfa,0x58,0xc5,0xc8,0x01,0xfa,0x56,0xe4,0x0e,0x6b,0xeb,0x5d,0x67,0xf4,0x63,0xd4,0x44,0xe2,0xe7,0x42,0xfe,0x09,0x58,0xdf,0xd9
+.byte 0x1d,0xb7,0x14,0x91,0xac,0x88,0x49,0xf6,0x7c,0x03,0x92,0x11,0xb4,0x66,0x68,0x6c,0x94,0x2a,0x22,0xaf,0xa6,0xb1,0x29,0x2a,0xae,0xdd,0xa8,0x65,0xe4,0xa9,0x39,0x00,0x1e,0xca,0x17,0x99,0xba,0xd6,0xf2,0x20,0x21,0xbf,0x1a,0xab,0xca,0x7c,0x92,0x22,0xee,0x3c,0x0c,0xc6,0x63,0xcc,0x86,0xfe,0xc0,0x8f,0xac,0x18,0x4e,0x2b,0xa5,0x2e
+.byte 0x46,0x57,0x8a,0xbf,0xdc,0xd1,0xd2,0x2c,0x5b,0xe2,0x96,0x81,0xca,0x41,0xb5,0x17,0x38,0x4a,0xa4,0xd2,0x0e,0xac,0x5d,0xe9,0x44,0x63,0x1b,0xb8,0x81,0xd6,0x69,0x1c,0x99,0xc5,0xdb,0xdd,0x18,0xc1,0x6d,0x28,0x7d,0x36,0x52,0x82,0xaa,0x1a,0x10,0x01,0x9d,0xf1,0x7b,0x09,0x69,0x56,0xb1,0x31,0xa3,0x54,0x3c,0x56,0xf9,0x82,0x8c,0x06
+.byte 0x5a,0x32,0x2d,0xc0,0x7c,0x7e,0x91,0x6d,0x73,0x7b,0x7c,0x45,0x0b,0x2c,0x2a,0x4f,0x3c,0xea,0x6b,0x2b,0x84,0x76,0xab,0x8d,0x4c,0x5c,0x64,0xa3,0x97,0x9f,0x56,0x20,0x05,0xf9,0xc2,0x20,0xf3,0xd0,0x6a,0x7f,0x7d,0x12,0xfc,0x20,0x52,0x5d,0xff,0x92,0xaf,0x4e,0x7f,0x8f,0x2f,0xd0,0x73,0x06,0x23,0x09,0xce,0x11,0xc0,0x1b,0x48,0x7d
+.byte 0x11,0x51,0x06,0x0e,0x05,0x95,0xca,0x42,0x71,0x87,0xa3,0xa3,0xc1,0x27,0xf8,0xb1,0x24,0x92,0x38,0x95,0xf6,0x8f,0x3b,0x70,0x74,0x19,0x9b,0x08,0xb3,0x49,0xe9,0x57,0xd4,0xce,0x5b,0xdd,0xab,0x95,0x26,0xe9,0x70,0x21,0xef,0x16,0xdd,0x36,0x89,0xe5,0x9e,0xaf,0xc5,0x28,0x0c,0xd3,0x67,0x64,0xbc,0xfb,0x18,0x17,0x15,0x1e,0xa7,0xb7
+.byte 0x72,0x3d,0xfd,0x10,0x5c,0xa2,0xc1,0xbf,0x62,0x79,0x2b,0xa7,0xb9,0x1f,0x73,0xe6,0x11,0xd8,0xbc,0x74,0x6c,0x45,0x95,0xef,0xa2,0xda,0x90,0xc3,0x00,0x00,0xbb,0xc7,0x28,0x36,0x82,0xd4,0x5e,0x5c,0x11,0xea,0x7c,0xf6,0x79,0x66,0xff,0x93,0x77,0x49,0x05,0xc9,0xc1,0x8d,0x5c,0xf6,0xff,0xb9,0xf9,0xcd,0xb3,0x01,0x83,0x83,0x43,0x2d
+.byte 0xa1,0x90,0x73,0xc9,0x32,0xae,0xdb,0xd0,0xf3,0x61,0x63,0x72,0x06,0xde,0x21,0x7b,0x3b,0x2d,0xec,0xd3,0x1d,0xfe,0xbd,0x6e,0xd8,0xe3,0x39,0xe0,0xa1,0x9f,0x67,0xaf,0xab,0x79,0xbc,0x59,0xf9,0xa7,0xdf,0x28,0x75,0xea,0x34,0x6b,0x25,0xde,0x49,0x1b,0x07,0x95,0x19,0x47,0x86,0x46,0x7b,0x68,0x30,0x70,0xec,0x9c,0x05,0xb6,0xc9,0x00
+.byte 0x68,0x10,0x4b,0xc4,0xe5,0xf1,0x67,0x3f,0xd4,0x3c,0xd6,0x49,0x98,0x71,0x23,0xff,0x07,0x6e,0x01,0x01,0x08,0x08,0x3d,0x8a,0xa1,0x71,0xdf,0x25,0x1a,0xef,0x60,0x86,0x6d,0x1c,0xd9,0x90,0x29,0x95,0xf2,0x4c,0x96,0xd3,0x17,0xe8,0x96,0x32,0x25,0x8c,0x65,0x38,0xbc,0x44,0x6a,0x5a,0xef,0x5a,0x72,0x12,0x43,0x2b,0xaf,0xc3,0xdc,0xb3
+.byte 0x6c,0x9f,0x57,0x61,0x2f,0x12,0x3f,0x72,0x16,0x4f,0x34,0xe3,0xb5,0xca,0x72,0xca,0x1c,0xdb,0xd2,0x8d,0x70,0x1f,0x19,0x75,0xb3,0x1b,0xdf,0xdb,0xb3,0xbf,0x6c,0x9a,0x70,0x64,0xa8,0xac,0x30,0x2d,0x4b,0x30,0xf5,0x4f,0x12,0x19,0xbd,0x65,0x25,0x70,0x33,0xe1,0x6f,0x18,0xdf,0x17,0xec,0xa3,0x80,0x51,0x6e,0xbb,0x33,0xa5,0xa8,0x58
+.byte 0x95,0x3c,0xab,0x86,0xd1,0x33,0xbe,0x55,0x04,0x8c,0x20,0x0d,0xfc,0x1a,0xa9,0x9d,0xb1,0x16,0x42,0x56,0x20,0xcc,0xa6,0x73,0xa0,0x85,0x3d,0xbf,0x1e,0xe0,0x01,0x51,0xd2,0xd7,0x2e,0x9d,0xd8,0x3c,0xea,0x03,0xf9,0x9a,0xbf,0x19,0x17,0x04,0x99,0xaf,0x8b,0xfc,0x9c,0x86,0xdf,0x58,0x78,0xfc,0x54,0x0d,0xac,0x26,0x27,0x2f,0x2e,0xbc
+.byte 0xdd,0x4a,0xd5,0x6f,0x7c,0xd8,0x93,0xe3,0x51,0x9e,0xcc,0xc8,0xd2,0xfe,0x68,0xfb,0x5b,0x22,0xda,0xef,0x76,0xb9,0xc3,0xdd,0x13,0x52,0x24,0xb6,0x23,0x1f,0x69,0x22,0xb6,0xf5,0x86,0xff,0x2e,0x6e,0xd0,0xe0,0x21,0xbc,0x31,0x81,0xb5,0xc5,0xdb,0x36,0x58,0x44,0xe7,0xb8,0xf7,0xfd,0xd3,0x34,0xee,0xab,0xe6,0x99,0xf2,0x84,0x86,0x9b
+.byte 0x67,0x45,0x08,0x07,0x66,0xae,0x6a,0x55,0xa2,0x74,0x46,0xda,0x02,0x82,0x67,0x93,0x60,0x64,0x5d,0x1f,0xac,0xe7,0x36,0xb6,0xcd,0x31,0x28,0x78,0x93,0xcd,0x54,0xe9,0x42,0xbb,0xb4,0xb3,0x15,0x72,0x12,0x31,0x85,0x15,0x68,0x3a,0x31,0x35,0xd6,0xc9,0x0d,0x3f,0xa0,0x4b,0x36,0x03,0xda,0xfd,0x7a,0xd6,0xce,0x0c,0xf5,0x14,0x23,0x71
+.byte 0x47,0x85,0x64,0xe7,0xe7,0x8b,0x8e,0x25,0x03,0x32,0x5f,0xa9,0x3b,0xdb,0x2b,0x27,0x7c,0x02,0xfb,0x79,0xd7,0x7a,0x76,0x75,0x69,0xfd,0x74,0x24,0xd2,0x72,0x8c,0xdd,0xc5,0xa1,0x45,0x90,0x50,0x65,0x95,0x41,0xae,0x7e,0x5c,0x83,0x3e,0x24,0x3c,0x02,0xa9,0x37,0x49,0x36,0x63,0x2f,0x18,0x92,0x3a,0x8a,0xe5,0x2a,0x6a,0x5c,0xa7,0x3e
+.byte 0x98,0x24,0xfd,0xd9,0x3b,0x2d,0x4c,0xe2,0x8e,0x05,0x5b,0xdd,0x47,0x0f,0x19,0x5a,0x62,0x94,0xd6,0x6e,0x45,0xd8,0x99,0x43,0x78,0xa0,0xb1,0xdf,0x68,0x8a,0x56,0xa8,0xfb,0x2e,0x52,0x4e,0xfa,0x21,0xec,0x62,0x14,0xf5,0x90,0xdb,0x8c,0x02,0xa7,0xff,0x29,0x22,0xb8,0x40,0x87,0x58,0xda,0x4e,0xfd,0xab,0xeb,0xa2,0x40,0xce,0xfc,0x58
+.byte 0x46,0x37,0x3f,0x04,0x4e,0x36,0x76,0x44,0x3c,0xfc,0x54,0xb8,0x6f,0x4b,0x66,0x6a,0x4a,0x78,0x8f,0x33,0x86,0x07,0xe4,0x3c,0xb5,0x0f,0x86,0x2e,0x21,0x7e,0x44,0xce,0x18,0x77,0xe0,0xcc,0xd7,0x7f,0xc9,0xac,0xb7,0x2b,0x94,0xb5,0x91,0xcd,0x2c,0xfa,0xc7,0x98,0xbd,0xb0,0x2a,0x85,0x77,0xcf,0x82,0xd9,0xae,0x76,0x33,0x34,0xc0,0x9d
+.byte 0x3a,0xbc,0x27,0xbc,0x97,0x25,0xf4,0xf1,0x43,0x53,0xac,0xf6,0xde,0xf5,0x1f,0xa6,0x6a,0xd5,0xe3,0x11,0x32,0x49,0x46,0x5b,0x56,0x68,0x07,0xdb,0x03,0xad,0xc2,0x35,0x16,0x8f,0x01,0xcc,0x8a,0xd2,0x0c,0x6b,0xb2,0x62,0x73,0x99,0xb5,0x74,0xf1,0x4b,0x2e,0xbc,0x8e,0xed,0xc0,0x55,0x56,0x40,0xae,0x24,0xf2,0x7e,0x1f,0xba,0x9d,0xc4
+.byte 0xd1,0x69,0xd3,0xba,0x21,0x83,0xf5,0xc4,0xbf,0x78,0x96,0x74,0xa1,0xd8,0x8c,0x35,0xba,0x9f,0xa0,0x0f,0xb5,0x6a,0xb2,0x72,0x52,0xfa,0x02,0x71,0xbb,0x79,0x61,0xbd,0xa9,0xee,0x22,0x7c,0xc5,0xac,0x6b,0x52,0x67,0xab,0xc4,0xd2,0x8d,0x26,0x1c,0x2b,0xaf,0x0c,0xa4,0xce,0xb5,0x11,0x99,0x4d,0x22,0x69,0x68,0xe0,0xc6,0x3e,0x84,0x3d
+.byte 0xeb,0xad,0xc9,0x5b,0xb5,0xb4,0xba,0x06,0x9b,0x0a,0xb2,0x54,0x89,0xf2,0xb0,0x5f,0x41,0xb4,0x8b,0x21,0x31,0x29,0x94,0x52,0x1e,0xa7,0xc4,0xc2,0x97,0xb9,0x74,0x95,0xa3,0x30,0xfb,0x02,0x77,0x01,0x4f,0x32,0x03,0x34,0x8f,0x51,0x2d,0x10,0x61,0xee,0xc5,0x2f,0x89,0x42,0x3c,0xbe,0xed,0x66,0xa6,0x7a,0x10,0xc6,0x06,0x7e,0xb2,0x3d
+.byte 0xf2,0xc9,0xd1,0x08,0x97,0x6c,0x6f,0x6d,0x06,0x9d,0x72,0xd0,0x5e,0x79,0x3b,0xa5,0xa5,0xd0,0xdc,0xc6,0xda,0x73,0xd2,0xf3,0x0a,0xfd,0x94,0xc2,0x9c,0x4b,0x85,0x38,0x8d,0xb2,0xfb,0x29,0xdd,0x90,0xc2,0xb7,0x8f,0x2c,0x52,0xa2,0x32,0x5e,0xa1,0x0f,0x62,0x38,0x58,0xfa,0x46,0x4e,0x87,0x4b,0xcf,0xc5,0xe9,0xfc,0xf2,0x97,0x62,0xdd
+.byte 0x92,0xd2,0x41,0x7b,0xa2,0x2a,0xae,0x6e,0x4d,0xbc,0xef,0x43,0x18,0x6e,0xbb,0xe5,0x06,0x45,0x53,0xa1,0x00,0xef,0xf5,0x4b,0xad,0xbd,0xa5,0x2c,0x77,0x0a,0x37,0x04,0x22,0x95,0xeb,0x7b,0xc1,0x3c,0x20,0x0a,0x44,0xdf,0xa2,0x23,0xc9,0xfc,0x85,0xf3,0x5b,0x9b,0x0f,0x40,0x2a,0xe3,0xc7,0x5a,0xa1,0xf6,0xe4,0x39,0x2a,0xfe,0xd7,0xe7
+.byte 0x33,0xd8,0xbc,0xd6,0x1f,0xef,0xac,0xa9,0x3f,0x2d,0x55,0xb0,0x85,0x74,0xef,0xeb,0xcd,0x9b,0x23,0xa3,0xe6,0x19,0xde,0xea,0x7c,0x9c,0x83,0x48,0x4b,0x12,0xfd,0xe3,0xcb,0x1b,0x70,0x2d,0x9f,0x2c,0x13,0x82,0x87,0x68,0xca,0x60,0x5e,0xc0,0x2e,0x60,0xde,0xf2,0x6b,0x78,0x0a,0x63,0xaa,0x9c,0x9b,0x61,0x63,0xc7,0x0c,0x98,0x92,0x68
+.byte 0xc7,0x44,0x00,0x6a,0x76,0x43,0xa0,0x61,0x7c,0x37,0x62,0x1a,0xd4,0x9b,0x58,0x59,0xe5,0xae,0x78,0x79,0x80,0xf0,0x75,0x68,0x9e,0xab,0x02,0xb8,0x00,0xc5,0x33,0x0d,0xea,0xb1,0x91,0x0f,0x17,0x57,0x96,0x23,0x8d,0x36,0x4d,0x89,0x94,0x42,0xc9,0x61,0x6e,0xf6,0x9f,0x37,0xee,0xa5,0x4b,0x3d,0x06,0x08,0xee,0x9a,0x7c,0x73,0xa9,0x58
+.byte 0xcd,0xcb,0x78,0xa9,0x3d,0x5c,0x11,0x0e,0x5a,0xd9,0xb0,0x7b,0xc4,0x3e,0x83,0xdc,0xe2,0x11,0xe9,0x6d,0x8a,0x8b,0x24,0x28,0x1d,0x7e,0x45,0x1b,0x05,0x5a,0x6b,0x97,0x1c,0x25,0x15,0x84,0x5c,0x3f,0x95,0x44,0xd5,0x4f,0x3c,0x4b,0x52,0xb1,0x0b,0x6a,0xb3,0xae,0x4e,0x1b,0x12,0xcf,0x16,0x78,0xd7,0xcb,0x32,0x43,0x39,0x88,0xf4,0x5e
+.byte 0x26,0x29,0xe7,0x93,0x08,0x19,0x14,0x88,0x8f,0x54,0x91,0x13,0xb6,0x57,0xd1,0x87,0xd4,0x9d,0xf7,0xec,0x9b,0x22,0x6b,0x91,0x79,0x9d,0x6c,0x32,0x47,0x4a,0x79,0x55,0x7d,0xac,0x87,0x98,0x59,0x97,0xa5,0x71,0xbc,0xbf,0x1b,0xf0,0x6f,0xbb,0x81,0x8e,0xc2,0xef,0x7c,0x63,0x2f,0x80,0x37,0xb6,0xc5,0xae,0x59,0x5e,0x57,0x5e,0x1f,0x3a
+.byte 0xe5,0x6b,0x6b,0x5e,0xdb,0x8e,0xd2,0x87,0xf7,0x94,0x7b,0x11,0x0e,0x4b,0xa6,0x9f,0x49,0xc6,0x68,0xc7,0x52,0x5f,0x28,0x87,0x33,0x84,0x52,0x5f,0xc8,0x5f,0x81,0x85,0x10,0xe8,0x92,0xce,0x13,0x6c,0x01,0x28,0x5e,0x59,0x8f,0xbb,0xa9,0x9c,0xdc,0x85,0xd3,0x73,0xa0,0x5a,0xbf,0x5b,0x04,0x80,0x99,0x90,0xc8,0x16,0x44,0x0d,0x09,0x01
+.byte 0xcd,0x24,0xe7,0x59,0xe7,0x42,0xe0,0xdd,0x01,0x93,0x1f,0x9e,0x1f,0x36,0xdb,0xcd,0x49,0xdb,0xea,0xa9,0x63,0x71,0xb9,0x2c,0xcd,0xca,0x1a,0x64,0xe1,0x95,0xbe,0xe1,0x64,0x2e,0xc7,0x59,0x15,0x61,0xe1,0xf9,0x45,0x0f,0x2a,0x3a,0x85,0xf8,0x7c,0x06,0xae,0x53,0x84,0xd2,0xe7,0xee,0x8b,0xbf,0x7a,0x72,0xa3,0x57,0xf1,0xc2,0x12,0x40
+.byte 0x9c,0x93,0xe1,0x04,0x81,0xde,0xc6,0xa8,0xae,0x4f,0x5c,0x31,0x93,0xc7,0x11,0x1d,0x89,0x70,0x85,0xd5,0x6f,0xab,0x58,0x1f,0x3f,0x76,0x45,0x7e,0x19,0xd0,0x6c,0xc1,0x41,0xa9,0x64,0x0a,0x79,0xb5,0xe0,0x9e,0xbc,0x4f,0x10,0x0c,0xac,0xfc,0x54,0xad,0xcf,0xb8,0xd0,0xfd,0x9b,0xed,0xea,0x54,0x05,0xbf,0x4f,0x91,0xbd,0x16,0x4a,0x57
+.byte 0xa9,0xda,0x38,0xb9,0x40,0x0d,0x63,0x68,0x83,0x7d,0xec,0x1c,0xe6,0x7f,0x9c,0xec,0x16,0x4e,0x0b,0xd0,0x91,0xb4,0x2c,0x04,0x65,0xb8,0x12,0xdf,0x3f,0xff,0x6a,0x08,0x4e,0x65,0xdf,0x09,0xa5,0xea,0xb1,0xac,0xa9,0x67,0xd2,0xbb,0x73,0x51,0xd2,0x37,0x72,0xfc,0x3f,0x69,0xe2,0x3f,0x01,0x94,0x3a,0xf7,0x23,0x0e,0x5d,0x23,0x44,0x82
+.byte 0xc7,0x38,0x35,0x9f,0xfa,0x13,0x15,0x47,0x0d,0x18,0xab,0x02,0x39,0x6e,0xb2,0x7c,0x29,0x11,0x9a,0x5a,0x01,0x2d,0xb2,0x10,0xea,0x9d,0xb7,0x37,0x4b,0xf2,0x2b,0x76,0x22,0xf7,0xaf,0x8a,0x5f,0x1d,0x6b,0xb2,0x13,0x9e,0x84,0xf5,0xbc,0x6e,0xad,0x66,0x5c,0x1b,0x5d,0x12,0xb0,0xe1,0x48,0x94,0x83,0xa0,0x26,0x54,0xd2,0xfd,0x3c,0x8d
+.byte 0x81,0xac,0x31,0x9a,0x15,0xc6,0xd8,0xd5,0x07,0x1b,0x21,0x3f,0x04,0x40,0x3a,0x60,0x80,0x5f,0x1f,0x42,0x3e,0xd7,0x2b,0x7a,0x5f,0x71,0x93,0xb4,0x9d,0xf0,0x8b,0x5e,0xf1,0xc6,0x19,0x0a,0xa9,0x43,0xac,0xb2,0xc1,0x73,0x0d,0x44,0x6a,0x92,0x22,0xd0,0xda,0x40,0x14,0x7d,0x88,0xd1,0x5e,0x10,0xc9,0xa4,0x4d,0xd8,0xe0,0x7d,0x74,0x1b
+.byte 0x2b,0xcb,0x50,0x24,0xbd,0x50,0x4a,0xe4,0xed,0x0e,0xe8,0xc0,0x5b,0x50,0x6d,0xf5,0x68,0x59,0xd1,0xc3,0x6f,0x32,0x86,0x29,0xe0,0x32,0x3f,0x05,0x86,0xa2,0x7f,0x93,0xd8,0xb7,0x02,0x68,0xb3,0x16,0xaa,0x0c,0xd3,0x4d,0xec,0x9a,0x66,0x06,0x7c,0x74,0x35,0x6f,0xde,0x8b,0xd9,0xdb,0x79,0x0a,0x15,0x84,0xc4,0x63,0xba,0x42,0xa2,0x3c
+.byte 0x29,0xc8,0x65,0xdc,0x06,0x60,0x0a,0x08,0x4e,0x80,0x33,0x5c,0xfa,0x4b,0x91,0xdb,0xf6,0x57,0xd6,0x25,0x7d,0x70,0x80,0x09,0xb2,0x27,0xdb,0x80,0x4c,0xa7,0xe8,0x35,0xf5,0x18,0x2d,0x10,0x62,0x22,0xf9,0xb1,0x22,0xf3,0x9b,0x74,0xa0,0xc5,0x25,0xd3,0x44,0xc9,0x27,0x7c,0xba,0x01,0xfe,0x32,0x23,0xf7,0x90,0x90,0xbc,0x0d,0xad,0x9e
+.byte 0x22,0x77,0xc5,0xfb,0xf2,0x0e,0xda,0xe5,0x7c,0xb4,0xbb,0xed,0xd4,0xfd,0xb0,0xfb,0x4a,0x4c,0x2a,0x32,0x2d,0x81,0xcd,0xef,0x74,0x3c,0x6a,0x9a,0x0c,0x95,0x58,0x25,0xd0,0x3a,0xb4,0x84,0x8f,0xa5,0xef,0xad,0x91,0xd7,0x2d,0xae,0x61,0xaf,0x9d,0x3f,0x03,0xa8,0xab,0xa4,0x66,0xd4,0x73,0x3a,0x84,0x0d,0x4c,0x6a,0xca,0xbd,0x0c,0x3c
+.byte 0xdc,0x1d,0x37,0xea,0xe6,0x5a,0x7f,0x15,0xbe,0x9d,0xc7,0xce,0xbd,0x46,0x97,0xd3,0x07,0x19,0x82,0xaf,0x58,0x39,0x39,0x95,0x5d,0x4b,0x8e,0x1b,0xe9,0xf1,0xf6,0xa9,0xb3,0xfc,0xe6,0xe0,0x68,0x2c,0xbb,0xfa,0xd9,0x9b,0xc1,0x69,0xf3,0x5a,0x8f,0x67,0xd5,0x9c,0x11,0x1e,0x02,0x20,0x20,0xfe,0x4b,0xc9,0x8b,0x62,0x17,0x9a,0xfa,0x47
+.byte 0x7f,0xa2,0x8b,0xc1,0x3b,0x02,0x78,0x38,0xff,0xce,0xe1,0x54,0x40,0x3f,0x27,0x5c,0x9d,0xdd,0x56,0x38,0x48,0xea,0x39,0xbe,0xa0,0x76,0x43,0x82,0xef,0x74,0x50,0xdf,0xda,0x4c,0xca,0x47,0x46,0x7e,0xc5,0xff,0xce,0x66,0xdf,0xeb,0x5b,0x6e,0x45,0x77,0x19,0xac,0x01,0x1f,0x20,0xa1,0xad,0x01,0x5f,0x87,0x3e,0x3a,0xd0,0x83,0x13,0x17
+.byte 0x53,0x40,0xfe,0x26,0x99,0x42,0xfa,0x54,0xa8,0x82,0x79,0xa7,0x44,0xd0,0x9e,0x59,0x64,0x77,0xec,0x70,0x0e,0xcd,0xb9,0xb1,0xc2,0xe2,0x39,0x93,0xb7,0xd1,0xd5,0x67,0x9f,0xb0,0x5b,0xd9,0x50,0x8b,0x17,0xec,0xbc,0x83,0x64,0x35,0xaa,0x43,0x3f,0x4c,0x8c,0x56,0x83,0x76,0xa2,0x72,0x30,0xe7,0xe8,0x9f,0x88,0x35,0x8e,0x8d,0x11,0x31
+.byte 0x8e,0xb5,0x71,0x75,0x31,0xc8,0x28,0x15,0x50,0xe6,0x0a,0x00,0x4d,0x75,0x51,0x7c,0x33,0x14,0x96,0xff,0xe8,0xf3,0xa0,0xb1,0x9c,0xeb,0x9d,0x8a,0x45,0xcf,0x62,0x82,0xeb,0xce,0xea,0xa5,0xb9,0x10,0x83,0x54,0x79,0xf8,0xcf,0x67,0x82,0x1d,0xea,0xce,0x86,0xcf,0xc3,0x94,0xf0,0xe8,0xf4,0x80,0x8b,0x84,0x96,0x06,0x2e,0xe4,0x58,0x21
+.byte 0x98,0x42,0x1a,0xb7,0x8c,0x5d,0x30,0x15,0x83,0xe8,0x17,0xd4,0xb8,0x7b,0x90,0x57,0x35,0x72,0x6d,0x1b,0x7c,0xc0,0x88,0x0a,0xa2,0xea,0xcd,0x58,0xcc,0xf1,0xb4,0x8b,0xcd,0x66,0x3c,0xa5,0xb0,0xd4,0xc9,0xcc,0x42,0x1d,0xef,0x3b,0x42,0x22,0x9b,0xfb,0x45,0x24,0xcc,0x66,0xd7,0x67,0x73,0xb2,0x12,0x03,0xf6,0xa3,0x06,0x61,0xe2,0xab
+.byte 0x91,0x8e,0x33,0x0b,0x9f,0x6a,0x80,0x5e,0x0f,0x68,0x41,0x5a,0x7e,0xd8,0xe2,0x32,0x50,0xc2,0x88,0x60,0xca,0xe3,0x23,0x86,0xff,0xdc,0x0c,0x19,0xbb,0xba,0x01,0xa3,0x41,0x89,0xf0,0x79,0x55,0x79,0xa6,0xa4,0x66,0x7b,0x46,0xde,0xac,0xae,0xb1,0xde,0xe1,0x1e,0x8d,0x62,0xc1,0xd6,0xeb,0x39,0x2f,0x1d,0x50,0x27,0x53,0xc9,0xea,0xb6
+.byte 0xd3,0x91,0x9b,0xdd,0xc1,0x68,0x8c,0xb6,0xe1,0x5e,0x9f,0xea,0xbe,0x98,0x88,0xeb,0xa8,0x77,0xf6,0x69,0x64,0xab,0x99,0xf3,0x7a,0x08,0xff,0x8c,0xa6,0x17,0x1b,0x2e,0x6e,0xcc,0xd8,0x33,0x30,0xef,0x5a,0x86,0x07,0x49,0xa5,0x13,0x08,0xbc,0xd6,0x88,0x7e,0x19,0xe0,0x1c,0x23,0xa9,0xe5,0x0a,0xa7,0xaf,0x8a,0xe9,0x81,0x3f,0xd8,0x99
+.byte 0xa6,0x01,0x6b,0xec,0x14,0x08,0x90,0xb1,0x76,0x16,0x3a,0xcb,0x34,0x0b,0x91,0x26,0xe9,0xec,0xe5,0xbc,0xd6,0xdc,0xf0,0xa9,0xfd,0xf2,0xe9,0xcc,0xa1,0x9d,0x7f,0x32,0x0d,0x0a,0x2a,0x92,0xff,0xc4,0x38,0xf8,0x9e,0x31,0x78,0x47,0xbf,0x3f,0x27,0x71,0xe1,0x7a,0x33,0x48,0x91,0xe8,0x8e,0x1a,0x66,0xcf,0xa1,0x61,0xc2,0x62,0x30,0x7c
+.byte 0x69,0x35,0x21,0x67,0x9b,0xa7,0x1c,0x72,0x06,0xd8,0x28,0x94,0x6e,0x6d,0xf0,0x22,0x85,0xb4,0x6c,0x89,0xe8,0x2e,0x3a,0xc5,0xdc,0xe3,0xe3,0x0c,0x8a,0xba,0x1c,0x57,0x86,0xef,0x55,0x6a,0x24,0x59,0x5e,0x6e,0x47,0xb8,0xad,0xc5,0x10,0xff,0xbe,0x2d,0x93,0x09,0xfe,0x17,0x03,0x16,0x4d,0x4a,0x9a,0x15,0x38,0x94,0x38,0x18,0x45,0xa7
+.byte 0xcf,0xe4,0x16,0xd3,0x26,0x72,0x49,0xe7,0x89,0x9a,0xb4,0xc7,0x78,0xc3,0x18,0x3b,0xc8,0x08,0x9d,0x66,0x0f,0x48,0xc8,0x23,0x91,0x57,0x61,0xf1,0xf3,0x01,0x3e,0x0a,0xa3,0x4c,0x6c,0x34,0x5b,0x98,0x40,0x47,0x42,0xc1,0xeb,0x58,0x58,0xff,0x1f,0x4b,0x5f,0xf1,0x29,0x2e,0x7e,0x76,0x15,0x56,0x17,0x9c,0xe7,0x55,0x09,0x22,0x0a,0xa2
+.byte 0xd8,0xbf,0xd9,0x44,0x49,0xa9,0x24,0xd7,0x4f,0x12,0x04,0xa2,0x18,0x1c,0xdc,0x54,0xc0,0x22,0x27,0x3c,0xeb,0x1f,0x02,0xae,0xb3,0x33,0xb2,0xa2,0x84,0x23,0x76,0xc6,0x2b,0x94,0x53,0xae,0x7b,0xee,0xbb,0x81,0x64,0x8a,0x3f,0xe0,0x75,0x6b,0x2c,0xd5,0x60,0xad,0x49,0x0c,0xf8,0x65,0x64,0x1a,0x83,0xc7,0xb9,0xd9,0x01,0x5b,0xde,0xb0
+.byte 0x76,0x9b,0x1c,0x0d,0x89,0x2d,0xd5,0x09,0xc7,0xa9,0xbb,0x0a,0x54,0x5c,0xd4,0x5b,0xbf,0xbc,0x5e,0x00,0x29,0x0b,0x30,0x19,0x73,0x66,0xfd,0x3f,0xdb,0xd4,0x1b,0xd4,0xc0,0x27,0xde,0x49,0x90,0x5f,0x65,0x87,0x3c,0xc4,0x43,0xd0,0x49,0x76,0x64,0x39,0x88,0xd7,0x0e,0xfc,0x27,0x52,0xb1,0x8d,0xd0,0x27,0x29,0x84,0xe3,0x49,0xb9,0x0c
+.byte 0x2d,0x4e,0x73,0x95,0x57,0xa8,0x07,0xa0,0xe1,0x5b,0x5a,0xb6,0xbc,0xa1,0x7f,0xfd,0x4b,0x9c,0x4d,0x7d,0x0c,0x5c,0x4c,0x4b,0x42,0x70,0xc3,0x0a,0xc1,0x89,0x12,0xb5,0x46,0x04,0x3c,0x56,0x25,0xc6,0x8f,0x49,0x7d,0x3b,0xf1,0xcd,0xfc,0xb8,0xa6,0x66,0xb1,0xc2,0xa3,0xa7,0x98,0x93,0x0e,0xdb,0xcd,0xce,0xdf,0x7f,0x68,0x5e,0xea,0xf2
+.byte 0x85,0x61,0x8f,0xd6,0x23,0xb4,0x5f,0x2f,0xf8,0x78,0x47,0x15,0x59,0x2d,0xca,0x35,0x0f,0xf5,0x91,0x74,0x3b,0x32,0xe1,0xcf,0x54,0x1b,0xf4,0x9d,0xdb,0x20,0x5e,0xf8,0x71,0x10,0xa3,0x31,0xf1,0xb8,0x98,0x8d,0x76,0x70,0xce,0x4c,0xed,0xd3,0x81,0x6b,0xd5,0x8d,0x73,0x5f,0x8c,0x66,0x7c,0x87,0x73,0xfa,0x20,0xbe,0xcd,0xba,0x41,0x88
+.byte 0x46,0xc3,0x38,0xc0,0xd9,0x08,0x79,0x30,0xda,0x7f,0x2a,0xc0,0x72,0x47,0xb0,0xc9,0x41,0x68,0xb1,0xe8,0xb4,0x86,0xcb,0x5d,0xb0,0x5b,0x7a,0x26,0xfd,0xf2,0x1b,0x4e,0x1f,0x4c,0x6a,0x8a,0x84,0xd4,0x07,0x2f,0xf4,0x06,0x73,0x3d,0x1c,0x55,0x04,0x6a,0xa5,0x8a,0xbb,0xaa,0x8a,0x8d,0x8f,0x05,0xcc,0x63,0x04,0xe0,0xc6,0x6f,0x6b,0xf8
+.byte 0x24,0x56,0xbb,0x9d,0xa9,0xe5,0x4c,0xac,0x9d,0xbe,0xfd,0x70,0x9d,0x1f,0x98,0xc4,0xfc,0xdb,0x3c,0x45,0xe7,0xbb,0xea,0x51,0xb6,0x56,0xe0,0x2c,0xb2,0x77,0x1b,0x80,0x9b,0x43,0xa7,0xb2,0x9a,0x40,0x8f,0xdb,0x2d,0x51,0x7b,0x2c,0x89,0xfd,0x14,0xf5,0x77,0xbf,0x40,0x3d,0x32,0xe0,0x10,0x32,0xcd,0xc4,0x3f,0xe2,0xe8,0xb4,0xdf,0xc2
+.byte 0x43,0x7a,0x0b,0x17,0x72,0xa1,0x0e,0xd6,0x66,0x35,0x8f,0xf4,0x21,0xf1,0xe3,0x46,0x13,0xd7,0xcd,0xc7,0x7b,0xb4,0x9b,0x39,0x1e,0x33,0x3c,0x18,0x15,0x7a,0xea,0x77,0xc5,0x57,0x4d,0xf9,0x35,0x8a,0xc1,0xb5,0x78,0x5d,0xc3,0x3e,0xd5,0xfd,0xb5,0x50,0xee,0x44,0x24,0xa2,0x55,0xb6,0xd8,0x3d,0x5d,0x75,0x2a,0x26,0x37,0xe7,0x85,0xb3
+.byte 0xff,0x70,0x5d,0x99,0x8d,0x99,0xba,0x9d,0x09,0x97,0xf2,0x67,0xe5,0xa3,0x86,0x06,0x21,0xb4,0x03,0x9b,0x63,0x76,0x1f,0xf8,0x09,0xd8,0x4e,0x22,0xcb,0x48,0xcf,0x79,0x72,0xc9,0x3f,0x84,0x5e,0xb8,0x39,0x87,0x27,0x92,0x1e,0x59,0xdf,0xc2,0xe6,0xd2,0xc4,0x5f,0xad,0x6e,0x9c,0xa4,0xec,0xd5,0x7d,0xf6,0x2b,0x9b,0x93,0x56,0xcd,0xa3
+.byte 0xc5,0xfa,0x82,0x39,0x46,0x29,0x57,0x43,0x08,0xe2,0xe1,0x3e,0x80,0x3b,0x8e,0x08,0xe5,0xc5,0xfe,0x05,0x17,0xaf,0xe0,0xf0,0xb7,0x5b,0x34,0x33,0x59,0xfa,0x93,0xbf,0x6a,0xb3,0x6c,0xbc,0x99,0x62,0x34,0x2c,0xf2,0x3b,0x62,0xf2,0x1c,0x48,0x07,0xc9,0x60,0x03,0xa5,0xe1,0x66,0x8d,0x84,0x36,0xc7,0xf9,0xc6,0x3b,0xa9,0xee,0x0f,0x48
+.byte 0xff,0xff,0xad,0x95,0x21,0xb5,0x12,0x63,0x7d,0x0f,0x0d,0x09,0x63,0x51,0x64,0x69,0xb4,0x95,0xd3,0x25,0xf0,0x3b,0x6d,0xc4,0xdd,0x8c,0x80,0x0d,0x3b,0xd2,0x4b,0xe0,0x67,0xcb,0xcd,0x7d,0x2e,0xbd,0x61,0x4b,0x0c,0x32,0x1f,0xfd,0xd2,0x31,0xed,0xa8,0xaa,0x98,0xf4,0x85,0x21,0xbc,0x08,0x14,0x2f,0xbb,0xbf,0x01,0xba,0x24,0x5e,0x5c
+.byte 0xf3,0x72,0xed,0x05,0xec,0xf3,0xd1,0x9b,0xb0,0x63,0x8a,0x14,0xd1,0x9e,0xae,0x9b,0xce,0x4d,0x6c,0xb6,0x7a,0x78,0x9e,0x1d,0xcd,0x1e,0x50,0x66,0x26,0x70,0x74,0x2b,0x43,0x6a,0xc7,0xd7,0xe9,0xa2,0xcf,0xf3,0x09,0x9a,0x81,0x80,0x04,0xb8,0x5a,0x4f,0x2e,0x10,0x35,0xb2,0xb0,0xc6,0x40,0x97,0xa5,0x6a,0x24,0x5a,0x6b,0x97,0xc7,0xc0
+.byte 0x24,0x50,0x8d,0x65,0x21,0x25,0xce,0xb9,0x19,0xfc,0x40,0x08,0xcf,0xfd,0x1c,0xc4,0x30,0xd4,0x06,0x70,0xac,0x8a,0x3c,0x3f,0xfc,0xc3,0xeb,0xdd,0x43,0x56,0x4a,0xf6,0x50,0x92,0x9d,0xce,0x9c,0xea,0x15,0xdd,0x7c,0x5e,0x40,0xf5,0x7e,0x41,0x70,0xdd,0xc7,0x62,0x21,0x5a,0x20,0xc8,0x71,0x10,0x97,0xd5,0x12,0xfa,0x31,0x96,0xfb,0x38
+.byte 0x17,0x66,0x73,0x32,0x7a,0x93,0xf0,0x82,0xb9,0xf1,0x24,0xc5,0x64,0x0b,0xa9,0x24,0x4a,0x47,0xac,0xfb,0xf1,0x55,0xd7,0xb3,0x9a,0x64,0x63,0x0b,0x2e,0x13,0x9e,0x1a,0xee,0x21,0xd0,0x70,0x5c,0x0c,0x25,0xe7,0x38,0x23,0xd7,0x2f,0x6a,0x20,0x59,0xef,0x70,0xb2,0x8e,0xb4,0x15,0xee,0x6f,0x70,0xd0,0x75,0x19,0x9d,0x42,0xa7,0x17,0xad
+.byte 0x99,0xaa,0x0d,0xa3,0x87,0x3d,0xf1,0x7b,0x0e,0xfa,0x62,0x9a,0x20,0x64,0x17,0x64,0x07,0xc2,0x84,0x13,0xb2,0x59,0x81,0x66,0x45,0xab,0x47,0x6d,0xfc,0x7b,0x60,0x05,0xac,0x30,0xb2,0x86,0x7e,0x34,0x6b,0xaf,0x37,0x00,0xa6,0x47,0x4c,0xb9,0x10,0xbd,0x9e,0xce,0x47,0x9e,0xc2,0x0e,0xfd,0x47,0xfa,0xd8,0x08,0xd1,0xc2,0xaa,0x6d,0x8c
+.byte 0x91,0x2c,0x18,0x32,0x52,0x84,0x47,0x71,0x3b,0xc9,0xa1,0xf5,0xfc,0x90,0xb8,0x79,0xbf,0xe5,0x59,0x1b,0x91,0x22,0xcb,0xd3,0x87,0x7e,0xd4,0xb5,0x33,0xb2,0xfc,0x7c,0xee,0x22,0xfb,0xe8,0xb0,0x3c,0xa7,0x8b,0x05,0xd7,0x7f,0x17,0x52,0xbe,0xb6,0xe0,0x1e,0x47,0xce,0xfd,0x79,0xdf,0x16,0x5f,0x01,0x70,0x0c,0x47,0x5a,0x01,0x96,0x08
+.byte 0x3e,0x9b,0xc4,0xb2,0x58,0x73,0xc4,0x38,0xd6,0xf2,0x1b,0x0a,0x2c,0xb9,0x2a,0x96,0xb5,0x89,0x2d,0x33,0xdf,0xa4,0x5f,0x24,0x1b,0x79,0x0e,0xb6,0x9f,0xec,0x46,0xd3,0x27,0x4a,0xc1,0x26,0x94,0x95,0x41,0xd5,0xb3,0x84,0x74,0x62,0x47,0xc5,0x4d,0xb4,0xe2,0xe7,0xdb,0xc3,0xc3,0x7b,0x33,0x2a,0xbf,0x69,0xf6,0x5e,0xdc,0xfe,0xa4,0x81
+.byte 0x91,0xf3,0xa8,0x26,0x82,0x44,0x37,0xea,0xe1,0x20,0xff,0x52,0x33,0x5b,0x0b,0x6f,0xf8,0x33,0x4e,0x02,0x4d,0x38,0x93,0xcd,0xc0,0xfc,0x73,0x1a,0xf9,0xf6,0x9f,0x53,0xfc,0xf7,0xe2,0x4b,0x25,0xdd,0xa7,0x4d,0x1e,0x5c,0x17,0xc3,0xa0,0x41,0x1d,0x67,0x45,0xff,0xcb,0x41,0x49,0xc4,0x18,0x68,0x7e,0x7f,0xb6,0x6f,0xdb,0xbc,0x73,0x2f
+.byte 0xc7,0x9a,0x46,0x8c,0x0b,0x57,0xa3,0xd3,0x0a,0x34,0xb7,0x27,0x67,0xbb,0xe1,0x64,0xa7,0x7e,0x79,0xac,0x4f,0x09,0x54,0x9b,0x43,0x5e,0x9a,0x33,0x02,0x45,0xdc,0x85,0x0b,0x59,0x8d,0x78,0xe8,0xd8,0xb5,0xd3,0x31,0x9d,0x2a,0x60,0x5b,0x91,0xed,0xf1,0xf1,0x37,0x3f,0xdb,0xda,0xd6,0xd1,0x8f,0x14,0x7e,0xe1,0xfc,0x92,0x60,0xa5,0x33
+.byte 0x86,0xef,0x29,0xbf,0x94,0x84,0x2b,0x24,0x20,0xb4,0x5e,0x23,0x34,0x08,0x63,0xc9,0xe6,0x80,0xa0,0x27,0x27,0x2f,0xab,0xc0,0x52,0x44,0x66,0x29,0x32,0x2e,0x91,0x96,0x02,0x1c,0x3b,0xb4,0x6e,0x33,0x49,0x5b,0x60,0x6f,0x14,0x93,0x65,0x0d,0x97,0x01,0xfb,0xf9,0x42,0x74,0xb6,0x21,0xf7,0xc2,0x5d,0xbf,0x91,0x2b,0xf5,0xb1,0x4e,0xe2
+.byte 0xd6,0x24,0x57,0x41,0x7a,0xcb,0xdd,0xb6,0x96,0x8b,0xfc,0x42,0x19,0x21,0x7f,0x41,0x32,0x3d,0x69,0x9b,0xee,0xda,0x97,0x45,0x26,0x71,0x0d,0x12,0xf0,0x20,0x7f,0x44,0x0f,0x4c,0xd2,0xd3,0x34,0x93,0xc7,0xe5,0xe7,0x83,0x62,0x13,0x0b,0x7d,0xc6,0xe4,0xd2,0xae,0x53,0x2e,0xd1,0x18,0x81,0xd0,0x81,0xf6,0xc0,0x98,0xaf,0x1d,0xb2,0x8a
+.byte 0xcb,0xd3,0xde,0x1d,0x53,0x71,0x92,0x0e,0x4b,0x8c,0x7c,0x8e,0x65,0xf6,0xe2,0xc2,0x5a,0x4f,0x8c,0x59,0x0f,0x35,0x5e,0xe4,0x43,0x50,0xab,0xb7,0xdd,0xfc,0x66,0xf9,0xb1,0x9b,0x6b,0x1b,0xaf,0x2e,0x85,0xe6,0x3e,0x4c,0xa2,0xd4,0x55,0x47,0xb9,0x66,0x66,0x7b,0xa3,0xb2,0xd5,0x8a,0x8e,0x88,0x0e,0xfb,0x4e,0xad,0xf4,0x39,0xd2,0xd6
+.byte 0x39,0xef,0xe0,0xee,0x0f,0xf3,0x94,0x47,0xa7,0x32,0x24,0x9a,0xb0,0x82,0x08,0x67,0x00,0x3f,0xe6,0x95,0x76,0x84,0x0a,0x5c,0xb7,0x74,0xc1,0x64,0x5e,0x7c,0xba,0x0b,0x2e,0x6f,0x26,0xc3,0x20,0x2e,0x95,0xc1,0xf0,0x8c,0x55,0x4a,0x45,0x26,0xe6,0xf3,0x55,0x78,0xbd,0xd4,0xdb,0x07,0xbd,0xff,0x61,0x51,0xde,0x7f,0xdb,0x56,0x73,0x6b
+.byte 0x9c,0xa4,0xb0,0x72,0xa7,0xd0,0x93,0x4d,0x1d,0x3a,0x92,0x78,0xde,0x77,0x65,0xe8,0x07,0x41,0x92,0xc1,0xbb,0x69,0x79,0x20,0x43,0xab,0x21,0x2e,0x6d,0xdf,0x43,0xeb,0x73,0x49,0x12,0x1f,0x53,0x75,0x01,0xed,0xce,0xf4,0x05,0x05,0x2b,0xc7,0x2a,0x65,0x29,0xe8,0xcf,0x5b,0xf0,0xc1,0x5b,0xd8,0xa8,0xac,0xbb,0xe3,0xac,0x29,0x0a,0x90
+.byte 0x79,0x2f,0x5b,0x92,0x14,0xf2,0xc7,0x2d,0xe5,0x33,0x6e,0x5e,0x31,0xe2,0xab,0xdf,0x21,0x71,0x4a,0x44,0xaa,0xc6,0xe9,0xb8,0x51,0x1d,0xe2,0xf3,0x07,0x19,0xa1,0x98,0x9e,0x8a,0xed,0xe4,0x9e,0x52,0x16,0x1f,0x2f,0xd3,0x4c,0x97,0x1e,0x38,0x49,0x84,0x2e,0x45,0xb5,0x4b,0x4f,0xfe,0xdb,0x25,0x3e,0xa9,0x6e,0x7d,0x60,0x3b,0xa7,0x7e
+.byte 0xda,0x32,0x1a,0xd6,0x04,0xbe,0x0c,0x92,0x4e,0x6d,0x85,0xf9,0x9c,0x26,0x9a,0x88,0xf5,0x50,0x95,0x7b,0x9e,0x43,0x07,0x97,0xd4,0xdb,0xa0,0x6e,0x30,0x5d,0x44,0xa9,0x41,0xc2,0xdf,0xdf,0x37,0x35,0xc4,0x85,0x83,0x08,0xea,0x22,0xfa,0xae,0xdd,0x95,0xe5,0x35,0x47,0x23,0x86,0x27,0xfa,0x71,0x88,0xa0,0x12,0x00,0xe0,0xa7,0xd1,0x1b
+.byte 0x5e,0x78,0x6f,0x38,0x30,0xa9,0x80,0x75,0xd7,0x61,0xcc,0xfd,0x33,0xd2,0xb8,0xf8,0xd7,0x12,0xf5,0x03,0xf9,0x53,0x6d,0x3b,0x6b,0xff,0x24,0x0a,0x3b,0xe8,0x2a,0xe9,0xae,0xb7,0xc3,0xe3,0x0f,0x26,0x71,0x55,0xc5,0x03,0x60,0xf4,0x47,0x01,0xa3,0x69,0xb2,0x98,0x75,0x5b,0x90,0x4a,0xf9,0x61,0x49,0xd6,0xc4,0xdb,0xab,0x04,0x0c,0x47
+.byte 0x1e,0x31,0x75,0xfa,0xa2,0xc5,0xfa,0x66,0x0c,0x4a,0x93,0xa0,0xea,0x56,0xf9,0x49,0xd4,0xc7,0xcc,0x2c,0xe5,0xdc,0xab,0x61,0x8e,0x0c,0xf3,0x2f,0xb5,0x9f,0x36,0xa1,0x05,0xab,0xb6,0xbc,0x4a,0x6d,0x97,0xe7,0x19,0xe5,0xfe,0x92,0xa5,0x94,0xd5,0xc0,0xf5,0x31,0xf6,0x8a,0xf7,0x24,0x62,0xdd,0x56,0x12,0x84,0xf5,0xc6,0xa0,0x37,0xa3
+.byte 0xfc,0xbd,0x16,0x2a,0xa6,0x36,0x8e,0xd4,0x29,0xfe,0xc4,0xc5,0xcb,0xdd,0xdd,0x8b,0x7e,0xa6,0x9d,0x08,0x28,0x10,0x6b,0xff,0xd7,0x79,0x48,0x35,0x2f,0xbe,0x34,0x9a,0xfb,0xd0,0x7d,0x5c,0xad,0xf0,0xde,0x96,0xea,0x2d,0xc5,0x8b,0xa9,0x7a,0x8b,0xbe,0x97,0xde,0x7a,0x95,0xc7,0x95,0xd9,0x86,0xde,0x3c,0x8d,0x15,0x8e,0x45,0x69,0x27
+.byte 0xd4,0x27,0xa8,0xe3,0xa9,0x1e,0xa0,0x95,0x74,0xf1,0x8b,0xbe,0x3b,0xff,0xa3,0xf6,0x23,0x78,0xd9,0xbd,0xc2,0x44,0x3a,0x93,0xb5,0xa6,0x87,0x7c,0x65,0xd1,0xd8,0xd5,0x43,0x2a,0xb2,0xc8,0x65,0x86,0x83,0x06,0xf7,0x33,0x88,0x3b,0xc0,0x2c,0xb3,0x3b,0x23,0xa3,0x67,0x15,0x49,0x09,0x02,0xbb,0x11,0x08,0xe3,0x37,0x9a,0x9b,0x67,0x8e
+.byte 0x63,0xc3,0x8b,0xff,0x21,0xa6,0xbe,0x3b,0xa6,0x57,0xc1,0x56,0x2a,0x02,0xdb,0x24,0x50,0x4a,0x4f,0x60,0x49,0x03,0xcf,0xba,0x55,0x1c,0x64,0xfe,0x0c,0x58,0xb4,0xb0,0x89,0x91,0xd5,0xbc,0xbc,0x85,0xe6,0x96,0x32,0x89,0x1f,0xa0,0x48,0xd1,0x6e,0xa7,0x03,0x86,0x8a,0xf2,0x5f,0xc3,0x5a,0x57,0x8a,0xa3,0x4a,0x61,0x90,0x18,0xb2,0x0d
+.byte 0xc7,0x94,0xb9,0x3e,0x40,0x8b,0x1d,0x54,0xd0,0x4c,0xe7,0x2a,0xd5,0x85,0xa7,0x93,0x07,0x10,0x58,0xc4,0x8a,0x18,0x0a,0x49,0x30,0x87,0x93,0x0e,0xcf,0xc7,0x95,0x9f,0xd1,0x3f,0x9b,0x06,0xe3,0xf9,0x4f,0x16,0x58,0x04,0xb4,0xf0,0xf0,0xf3,0x3a,0xab,0x4a,0x35,0xf1,0xec,0x23,0x15,0x0c,0x24,0xba,0x90,0xdc,0xd1,0xfe,0x47,0xca,0xb2
+.byte 0x95,0x33,0x30,0x45,0xba,0x18,0x15,0xec,0x58,0x36,0x02,0xdf,0x28,0x09,0x74,0x4b,0x09,0x01,0x24,0x0f,0x00,0x7b,0xb3,0x65,0x45,0x42,0x63,0x15,0xf8,0x50,0x8b,0x4f,0x28,0x73,0x03,0x3a,0x31,0xe5,0x0d,0x56,0x8f,0x6b,0x4b,0x9e,0xda,0x71,0xee,0x68,0xba,0x85,0x81,0x3d,0x5d,0x74,0x5e,0xda,0x60,0x87,0xf4,0x5a,0x38,0xad,0xc5,0x3f
+.byte 0xb5,0x15,0x02,0x59,0x1c,0xd2,0x93,0x66,0x54,0x65,0xf1,0xe7,0x9b,0xf0,0x30,0x2d,0x9e,0xba,0xc5,0x86,0xf4,0xf6,0xc7,0x92,0x73,0x12,0x3b,0x28,0x21,0x1b,0x3d,0x84,0xc0,0x1a,0x7d,0x35,0x8b,0xd4,0x35,0x39,0x35,0xa6,0x51,0xd9,0x19,0x8b,0x92,0xa3,0xea,0x8c,0x7e,0x25,0x05,0x1f,0x1d,0x8f,0x4d,0xba,0xdf,0x20,0x8c,0x8d,0xe2,0xac
+.byte 0xdd,0x3d,0xf1,0x04,0x3f,0x77,0x4b,0x8f,0x39,0x7d,0x01,0xb7,0x71,0x4b,0x7b,0xe1,0x6f,0xd4,0x28,0x1a,0x57,0x96,0x4d,0xe2,0x84,0xf6,0x64,0x10,0xbb,0x0f,0xbc,0xe0,0x19,0xed,0x92,0x9e,0x60,0x15,0x78,0xd1,0x30,0xc0,0x53,0x4b,0x94,0xca,0x4b,0x5a,0x44,0x8b,0xa9,0xda,0x2f,0x08,0x70,0x94,0xe4,0x54,0xe1,0x28,0x6e,0xdd,0x34,0x56
+.byte 0x54,0xb0,0xd4,0x87,0x00,0x72,0x1e,0x46,0x10,0x3a,0x27,0x5d,0xc6,0xb5,0x72,0x20,0x2b,0xbe,0x17,0x01,0xbb,0x04,0x11,0x16,0x7d,0xbf,0x91,0xd3,0x7b,0x44,0x58,0x13,0x2a,0x9c,0xda,0x9d,0x26,0x46,0xf5,0x5f,0x51,0xef,0x6c,0xf6,0x36,0xdb,0xb7,0x21,0xde,0xdb,0x87,0xa0,0xd8,0x60,0x24,0x86,0x6d,0x64,0x85,0x9e,0x94,0xd9,0x21,0x0d
+.byte 0xed,0xda,0x33,0xea,0x3c,0xdf,0x74,0xe3,0xa5,0xc7,0xc7,0x9e,0xe5,0xb1,0x29,0xdf,0xfa,0x20,0x25,0xcd,0x13,0x08,0xee,0xe6,0xba,0xf1,0x62,0x39,0xcf,0xe3,0x29,0xb8,0xaa,0x65,0x43,0x8a,0x48,0xb5,0xb5,0x70,0x35,0x66,0x42,0xf4,0x32,0x70,0x0b,0x0c,0xa7,0x46,0x79,0xdf,0xb2,0x80,0x13,0x72,0x7a,0xeb,0xf9,0x52,0xcb,0xb8,0x9f,0x4b
+.byte 0x4f,0x29,0x2b,0xb3,0x94,0x02,0x0a,0xe1,0x20,0xe5,0x91,0x15,0x6a,0xa1,0x0c,0x71,0x96,0x77,0x01,0x80,0xf7,0x51,0x0b,0xaf,0x54,0x9b,0x3c,0x7b,0x91,0xd2,0xbd,0xaf,0x13,0xa5,0x32,0x17,0x7c,0xca,0xd0,0x22,0xd5,0xe5,0x83,0x44,0x24,0x5c,0xcc,0x24,0x31,0xcd,0x81,0x4e,0x96,0xcd,0x60,0x9f,0x7a,0xe7,0x2e,0x89,0x16,0xd5,0x66,0x6b
+.byte 0xac,0x31,0x11,0x7c,0x76,0xc6,0xde,0xbe,0x46,0x55,0x20,0xdf,0x9d,0x2c,0x33,0xa5,0x80,0x76,0xb1,0xc9,0x1c,0x84,0x17,0x4d,0x15,0xe6,0x6d,0xce,0xed,0xea,0xc7,0xe6,0xff,0x01,0x10,0x60,0x26,0xf7,0x63,0x5f,0x91,0x89,0x7e,0xc1,0x7c,0x76,0x67,0x7b,0x7e,0xfa,0x28,0xa0,0xa7,0x82,0x1b,0x28,0x82,0x6a,0x4f,0x78,0x61,0x48,0xbf,0x13
+.byte 0x0b,0x71,0x0c,0xad,0xee,0xd7,0xf8,0xcc,0x0f,0x77,0x74,0x7d,0x2b,0x8a,0x09,0xd8,0x47,0xa0,0xfc,0x45,0x40,0x24,0xf3,0xce,0xdb,0x81,0xa1,0x50,0x9e,0x0a,0xd0,0x58,0xf7,0xaf,0xf1,0x09,0x12,0xa8,0x24,0xb2,0x34,0x99,0x67,0x17,0x53,0x1f,0x9d,0x09,0x7b,0xcb,0x83,0x6e,0x6a,0x0b,0xbf,0x8f,0x6e,0x3d,0xdb,0x29,0xe5,0xd0,0x06,0xdb
+.byte 0xb8,0xf2,0xf3,0x43,0x4e,0xa7,0xf3,0x73,0x93,0xe8,0xab,0x2f,0xc8,0x75,0xce,0x62,0xda,0x74,0x39,0x57,0xe4,0xe4,0xb1,0x41,0x8f,0x9d,0xda,0x43,0xb4,0x2c,0x4b,0xd5,0x1c,0x10,0xf0,0x29,0x6b,0x94,0x15,0x04,0x3c,0xd3,0x45,0x73,0x29,0xb3,0x60,0x87,0x93,0xdb,0xbf,0x60,0x4e,0xdf,0x4d,0xbb,0xde,0xb2,0x57,0x67,0x14,0x0d,0x0b,0x60
+.byte 0x63,0xd5,0xc6,0x81,0x82,0xd6,0x0c,0xe6,0x4c,0x43,0x13,0x02,0x74,0x56,0x20,0x6b,0x21,0x28,0xe6,0xe2,0x0b,0xc1,0x7a,0xc3,0x08,0x60,0x82,0xe0,0x4f,0xbf,0x1e,0x3f,0xf0,0xa9,0xb2,0x2e,0x0c,0xbf,0xd6,0x03,0x1d,0x0d,0xd6,0x1c,0x36,0xb5,0xb2,0x14,0x56,0x21,0xc2,0xe0,0x1e,0xff,0xee,0x8a,0x70,0xae,0x3f,0x1e,0xe5,0xac,0x05,0x46
+.byte 0x6b,0x81,0x32,0xce,0x50,0xbb,0x82,0x66,0x32,0x93,0x46,0xf7,0xee,0x77,0x1c,0x9a,0x2f,0x31,0x60,0xa2,0x09,0x7c,0x14,0xd9,0x81,0xe9,0x19,0x27,0x31,0x5e,0xa0,0x98,0x71,0x42,0x2f,0x30,0x71,0xd6,0x31,0x94,0xe0,0x61,0xed,0x50,0x66,0xfa,0xba,0x12,0x5e,0xc6,0xc8,0x67,0xe5,0x8e,0xfd,0x34,0xa9,0xeb,0xde,0x25,0x43,0xbf,0xe7,0xb5
+.byte 0x16,0xf5,0x62,0x66,0x5d,0x0b,0x13,0x9a,0xd4,0x8c,0x2b,0x8f,0xe6,0x91,0x33,0xcb,0xa0,0x70,0x48,0x3e,0x22,0x7d,0xe4,0xf3,0x75,0xc9,0x49,0x82,0x50,0xc9,0x90,0x04,0x32,0xab,0x99,0x6e,0xf1,0xf0,0x0b,0x60,0x80,0x35,0x25,0x45,0x88,0xe9,0x82,0x06,0xe1,0xbb,0x85,0x11,0x40,0xf8,0x0e,0xbd,0x19,0x7a,0xdd,0x78,0xf9,0xc2,0x46,0xe4
+.byte 0xb5,0x27,0xfb,0xb6,0xba,0xbc,0x7d,0xb8,0x27,0xe7,0xbf,0xfe,0x8e,0xfe,0x7e,0x83,0x63,0x43,0x92,0x26,0xf0,0xbb,0xde,0xb6,0x93,0x4f,0x55,0x0c,0x07,0x99,0x3c,0x98,0xa1,0x8c,0x73,0xc1,0x4c,0x9a,0x09,0xa8,0xea,0x16,0x0b,0x49,0x2a,0x43,0xee,0x90,0x61,0x6f,0x09,0x1b,0xc3,0x2d,0x62,0x4b,0xfc,0x90,0xa1,0x8e,0x84,0x2e,0x90,0x8d
+.byte 0x5f,0x80,0xff,0x6a,0x3c,0x61,0x0f,0xf2,0xac,0x70,0x20,0xc1,0xf2,0x85,0xcf,0x94,0xc8,0x94,0xe7,0xa0,0x04,0xdf,0xaf,0xef,0x26,0xd2,0xbc,0x07,0x70,0xc1,0x48,0xd6,0x87,0xd6,0xbe,0xea,0x95,0x6a,0xce,0xa2,0x48,0xac,0x46,0x46,0xb1,0x74,0x70,0x96,0x6c,0x26,0x58,0x75,0x9d,0x84,0xd7,0xd9,0x17,0x9a,0x46,0xe9,0xd7,0x3d,0xde,0xfd
+.byte 0x7e,0xf4,0xd8,0x7e,0xf8,0x8f,0x1c,0xb5,0xfb,0xe9,0xc4,0xca,0xba,0x52,0x5f,0x17,0xee,0x75,0x7d,0x1d,0x50,0x16,0x9f,0x16,0x1e,0x00,0x8b,0xc1,0x2f,0xab,0x73,0x65,0x88,0x7b,0x80,0xa6,0x71,0xb7,0xfb,0xb0,0xda,0xd1,0x96,0x18,0x5c,0x48,0x6e,0x18,0x45,0x59,0x45,0xef,0x5c,0x65,0x35,0x99,0x5e,0xb9,0xd4,0x1a,0x07,0x7d,0x1e,0xa6
+.byte 0x69,0x42,0x9d,0xfa,0xec,0x02,0xdc,0xc4,0x19,0x6b,0x9c,0xb1,0x5e,0xa3,0xb4,0x6d,0xb4,0xa6,0x25,0xa8,0xe4,0x3f,0x3d,0x6e,0x2c,0x95,0xf7,0xcd,0xa5,0x4e,0x32,0xca,0x7e,0xe0,0x7b,0x11,0xf9,0x0a,0xe1,0x61,0x41,0x60,0xec,0xb3,0xb1,0x92,0x89,0x33,0x17,0xe9,0xaf,0x70,0x7f,0x1c,0x07,0xb5,0x24,0x3a,0x37,0x84,0x38,0xf5,0xb6,0x11
+.byte 0xfc,0x0c,0x12,0xc1,0xfc,0xa9,0x82,0x67,0x4d,0x17,0xe8,0xea,0xd0,0x62,0x17,0xb2,0x9c,0x59,0x01,0x87,0xfb,0x54,0x8e,0xa7,0xa5,0x85,0xa9,0x8a,0xec,0xfe,0x29,0xc0,0x73,0xc6,0xa0,0xbf,0x66,0x9a,0xc5,0xf8,0xee,0xa4,0xcb,0x09,0x44,0x74,0xfe,0x32,0xf5,0x42,0xea,0xf0,0xa6,0xec,0x74,0xea,0x14,0x5c,0x43,0x51,0xfa,0x3a,0x48,0x1e
+.byte 0xa0,0x2e,0x59,0x2e,0xdb,0x3a,0x19,0xfe,0x1f,0x95,0x25,0xee,0x27,0x2b,0x99,0xb4,0xe1,0xd0,0xe6,0x33,0x91,0xa1,0xaf,0x30,0xa0,0x89,0x00,0x3c,0x13,0x31,0x18,0x70,0x90,0x42,0x55,0x0a,0xc9,0xc5,0x0c,0x43,0xa5,0xee,0xd6,0x90,0x07,0xae,0xc4,0x8c,0xdc,0xe4,0x07,0xbb,0x61,0x70,0xd1,0x10,0xe4,0x68,0x96,0x70,0x78,0xab,0xe9,0x3a
+.byte 0x6e,0xc7,0x75,0x93,0xa0,0xba,0xff,0x6a,0x2d,0x57,0xaa,0x93,0x09,0xc3,0x6b,0x81,0xf3,0xde,0xc2,0xee,0xac,0x86,0x0a,0xfb,0xad,0xdb,0x6f,0x2a,0xa0,0x15,0x7b,0x96,0x77,0x38,0xf8,0x86,0x51,0x33,0x7a,0x6f,0x1c,0xf8,0xd5,0x15,0xcd,0x76,0x7f,0x37,0x68,0x82,0xdf,0xab,0xc3,0xdb,0xbe,0xeb,0x2b,0xa8,0x34,0x72,0x20,0x34,0xfb,0x12
+.byte 0x64,0x17,0x05,0x64,0xc0,0xa1,0xca,0xd3,0xac,0x27,0xc2,0x68,0x28,0x40,0x42,0xe2,0x0a,0xdd,0xd7,0xd6,0xf6,0x92,0x95,0x3c,0x10,0x17,0x4e,0xef,0x75,0xae,0x98,0x2d,0x10,0xc8,0xa8,0xac,0x15,0xf7,0x5b,0x81,0xc1,0xdf,0x5e,0xbe,0x88,0x49,0xe3,0xd1,0x88,0x1c,0xcb,0xce,0x20,0x01,0x12,0x60,0x57,0x0b,0xf6,0x32,0x57,0xaf,0x59,0xef
+.byte 0xc9,0xe7,0xbf,0x62,0xf3,0xb6,0xe6,0x5c,0xee,0x36,0x7e,0x11,0x90,0xd1,0xeb,0xfa,0x62,0x0b,0xc6,0xf3,0x1a,0xd5,0x8b,0x95,0xec,0xb4,0x38,0xfe,0x45,0xb0,0xb5,0xff,0x84,0x0a,0x27,0x3a,0xa2,0x5a,0x2a,0xc9,0xa4,0xc0,0x11,0xc6,0x61,0x13,0xb7,0x53,0xa3,0x47,0x45,0x6d,0xc6,0xa9,0x00,0xd1,0x40,0xf4,0x77,0xac,0xb3,0xd3,0x26,0x99
+.byte 0xf1,0x36,0x59,0x28,0xb4,0xd0,0xdd,0x0e,0xed,0x53,0x33,0x45,0x71,0x9c,0x5c,0x11,0x27,0x2c,0x2f,0x10,0x9e,0x5b,0x8a,0x5b,0xc5,0x1f,0x36,0xc9,0x2a,0xba,0xc7,0xa5,0x31,0xd7,0x9f,0x2b,0x0a,0x09,0xcb,0x7c,0x4f,0xa2,0xdc,0xc5,0x64,0x0d,0xe6,0xfe,0xb0,0x9d,0x3b,0xf0,0xa7,0x19,0x8c,0x84,0x21,0x6b,0x9e,0x1c,0xb5,0x7b,0x66,0x77
+.byte 0xd0,0x85,0xb4,0x22,0x93,0x6e,0x84,0x29,0x9b,0x60,0x90,0x37,0x9d,0x8c,0x94,0x95,0x95,0x3b,0xf1,0x2d,0x56,0x5b,0x53,0x60,0x2d,0xe5,0x7f,0x80,0x71,0x56,0xa7,0x6e,0x66,0x76,0x1f,0xaa,0x0d,0xba,0xfb,0x0e,0xcf,0x20,0x68,0x74,0x2b,0x99,0x13,0xe1,0xa8,0x33,0xc9,0xf6,0xbc,0xd3,0xf4,0x46,0x01,0x02,0x85,0x27,0xf4,0x20,0x97,0xa3
+.byte 0xba,0xbc,0x47,0x30,0x48,0xed,0x60,0xe6,0xca,0xbf,0x76,0x8c,0x2c,0x6a,0x43,0x32,0xfd,0x90,0x04,0x95,0xc2,0x42,0xcb,0xca,0xc4,0x33,0xe1,0xd3,0x23,0x92,0xa1,0xde,0x09,0x38,0xce,0x00,0x93,0xb3,0xed,0x82,0x8e,0xfb,0xce,0x4c,0x9a,0x10,0x6e,0xce,0x4a,0x37,0x05,0x75,0x37,0x58,0xc3,0x8e,0x57,0x50,0xa0,0x7d,0x80,0x2d,0x51,0xea
+.byte 0x08,0xcd,0x1b,0xd2,0x81,0x85,0x19,0xc1,0xe8,0xce,0x31,0x18,0xcf,0x54,0x37,0x96,0x77,0x3d,0x64,0xfb,0xc2,0xa9,0xdb,0xb8,0x37,0x03,0x83,0x34,0x3c,0x25,0x6a,0x22,0x33,0xfa,0x27,0x70,0xc7,0x0a,0x27,0x12,0x1e,0xb3,0xd0,0x59,0x6f,0xa3,0xc5,0x73,0x95,0x4c,0x1f,0xf1,0x3c,0xb3,0xc2,0xa2,0xc6,0x45,0x17,0x53,0xa8,0xfc,0x00,0xff
+.byte 0x77,0x40,0x28,0xd2,0x53,0x90,0x92,0xe9,0x86,0x6c,0xa5,0x40,0xce,0xbc,0x79,0x6f,0x8f,0x12,0xef,0x1b,0x38,0x1f,0xb3,0x24,0xf0,0x75,0x17,0x20,0x9e,0x03,0x9c,0x2b,0x51,0x57,0x93,0x44,0xce,0x74,0xc9,0x12,0xe7,0xcb,0x2f,0x5e,0x1b,0x95,0xf2,0x4d,0x2e,0x51,0x8d,0x52,0xd5,0x21,0xe3,0x1b,0x33,0xe7,0xf2,0x18,0x61,0xa2,0x53,0xdb
+.byte 0x73,0xaa,0x6a,0x6c,0xf9,0xf4,0xef,0x3d,0x40,0xa3,0x00,0x80,0x82,0xed,0xe6,0x66,0xd1,0xd6,0xe9,0x93,0xd8,0x92,0xfa,0xdf,0xf9,0x9c,0x7a,0xfb,0x2b,0xc7,0xa7,0x73,0x67,0x2b,0xed,0x76,0xb1,0x52,0xaa,0xcf,0x34,0x84,0xa1,0x6d,0x56,0x85,0xef,0xcb,0xbc,0xa3,0xc6,0xf3,0x5a,0x88,0x04,0xd5,0xd8,0xf1,0x7b,0xf8,0x11,0x6f,0xa0,0x44
+.byte 0xa5,0x0f,0x76,0xed,0xd7,0x98,0xe3,0xda,0xb8,0x1b,0xc7,0xe6,0x89,0x08,0x19,0x1f,0xf8,0xe3,0x32,0x32,0xa5,0x3c,0x71,0x9f,0x11,0xde,0x50,0x29,0xb0,0x54,0x7e,0x3b,0x5e,0xeb,0xf7,0xab,0xa8,0xa0,0x35,0x96,0xc7,0xc5,0xea,0x60,0xc0,0x37,0xca,0x61,0x55,0x96,0xac,0xb4,0xd0,0x29,0x9a,0x1a,0x3f,0x9e,0xf5,0xf5,0x3d,0xed,0xc5,0x7c
+.byte 0x2c,0x9d,0x67,0xf8,0x4d,0x82,0x6e,0x2a,0x9a,0xfc,0x5f,0xdc,0x02,0xb0,0x3d,0xa5,0x1c,0x08,0x5d,0x4a,0xaa,0xd0,0x38,0xfb,0xbc,0xbb,0x7f,0x37,0xfb,0xec,0xc0,0x62,0x79,0xaa,0xde,0xfd,0x23,0x9c,0x4c,0x4a,0xe1,0x48,0x40,0x36,0xc0,0x0a,0x6f,0x43,0xb7,0xad,0x4c,0xf6,0x56,0xb5,0x44,0xf4,0x72,0xcd,0x13,0x10,0xea,0x0d,0x24,0xc1
+.byte 0xa9,0x36,0x3b,0x36,0xf2,0x6e,0xf9,0x0a,0x67,0xcd,0x02,0x67,0xb3,0x5c,0x63,0x3a,0x7c,0xc1,0x3b,0xf2,0x1d,0x3d,0xf1,0xff,0xbf,0xf7,0x97,0x9f,0x30,0x1f,0xaa,0xd8,0xdb,0x53,0x9b,0x0a,0xbd,0x38,0xd8,0xb6,0xf1,0x4a,0x78,0x1a,0xc2,0x46,0xd2,0x0c,0xa8,0xcd,0x7b,0x39,0xc7,0x42,0x55,0xc8,0x3e,0x02,0x1d,0xf4,0xad,0x55,0x01,0x6a
+.byte 0x11,0x2d,0xfa,0x67,0x48,0xae,0x45,0x31,0x9b,0x09,0x7d,0xd9,0xdd,0xaf,0x5c,0xd5,0x40,0x51,0x2a,0xa1,0x0f,0xb3,0x6e,0xc2,0x94,0xfe,0xde,0x70,0xaf,0x6c,0xea,0x5f,0x7d,0x3c,0x72,0x85,0x86,0x24,0x20,0x0a,0x7a,0xe7,0x69,0x32,0x66,0x7d,0x34,0x13,0x60,0x62,0xc7,0x68,0x32,0xde,0x34,0x30,0x36,0xc8,0x8e,0xb7,0x13,0x66,0xf1,0xce
+.byte 0x5f,0x7a,0x3a,0xfe,0x62,0xd6,0x72,0xb6,0x1b,0x80,0x43,0x8a,0x3e,0x13,0x15,0xe4,0x1c,0x7b,0x08,0x70,0x0b,0x6e,0xb3,0xfe,0x07,0x91,0x23,0x21,0x57,0x48,0xc6,0xa9,0xa3,0xa8,0xc7,0x19,0x89,0x8a,0x49,0x12,0x25,0x88,0xd2,0x11,0xa5,0xa8,0x9e,0x0e,0xa7,0x71,0xfe,0xaf,0x88,0xee,0xa7,0x1c,0x3b,0x27,0x27,0x7e,0x79,0x92,0xed,0x77
+.byte 0x74,0x65,0xbd,0x46,0x41,0x25,0xd9,0x8b,0x21,0x73,0x9f,0xaa,0x35,0xa0,0x22,0xb3,0xc8,0x71,0x28,0x72,0xd2,0xcb,0xf4,0x2a,0x06,0x0a,0x63,0x96,0x55,0x2e,0x83,0x0b,0xe8,0x07,0x99,0x9d,0x59,0xde,0xde,0x62,0xbd,0xb4,0x3e,0x70,0x15,0xed,0x95,0xa8,0x2f,0xb7,0xa2,0xb6,0x65,0x56,0x9d,0xe5,0x81,0xa0,0x05,0x5b,0xce,0x00,0xd4,0xb9
+.byte 0x28,0x5a,0xc1,0x9a,0x74,0xc6,0xd7,0x27,0xdd,0x7c,0xbe,0xe8,0x0d,0x47,0xfc,0x81,0x05,0x6b,0x4f,0x68,0xc7,0xcc,0x5d,0xd5,0x66,0x83,0x34,0x72,0x35,0xab,0x39,0x64,0x19,0x67,0xbd,0xff,0x15,0x44,0x20,0x18,0x2a,0xaf,0xbc,0x58,0x94,0xdb,0x18,0x50,0x55,0x11,0x6a,0xc4,0x1d,0xee,0xe2,0xe0,0x75,0x73,0xf1,0xa1,0x83,0xf4,0xcb,0x40
+.byte 0x96,0xf4,0x77,0x45,0x61,0x8b,0x1a,0x8c,0x0c,0xfc,0xd2,0x7e,0x0b,0x1e,0x18,0xd2,0x95,0xa5,0x4c,0x5b,0xd6,0x9d,0x40,0x8b,0xc0,0x51,0xe8,0x2d,0xe5,0x16,0xbf,0xd7,0x98,0x8a,0xa0,0x46,0x1f,0xc4,0xe9,0x12,0x31,0x40,0xc5,0x2d,0x59,0xf8,0x9b,0x5f,0xe3,0x3a,0x10,0xdf,0xda,0x72,0x9e,0xab,0x13,0x7b,0x8f,0xc8,0x52,0x9f,0x58,0x45
+.byte 0x7a,0xe6,0x3a,0xbb,0xdd,0x1d,0xc7,0x3b,0xc4,0x26,0xdc,0x99,0x29,0xf2,0x74,0x16,0x84,0xe9,0x8a,0x86,0xc0,0x1e,0x49,0x96,0x2f,0x5c,0x2a,0x49,0x71,0x88,0xe6,0x82,0xb2,0x18,0x88,0xc1,0x86,0xcb,0x26,0x3c,0xa5,0x50,0x31,0x22,0x9a,0x8f,0x45,0x2b,0xde,0xf0,0x86,0x8e,0x13,0x86,0xc4,0x4a,0x9b,0x35,0x27,0x93,0x0b,0x13,0xc8,0xef
+.byte 0x96,0x74,0x97,0x85,0x09,0xc0,0xa0,0x32,0xfe,0xc3,0xe3,0x92,0x2e,0xe8,0x54,0xbd,0xc2,0x23,0xeb,0x4b,0x02,0xf5,0x5a,0x0b,0x0d,0x58,0x50,0x45,0xe7,0x01,0xd4,0x17,0x00,0xdb,0x0d,0xd4,0x2e,0xa0,0xde,0x38,0xf4,0xb1,0x1e,0xd0,0xf0,0xa3,0x6b,0x21,0x0c,0xbd,0xae,0x84,0x7e,0x42,0x36,0x4f,0x2e,0x46,0xae,0x23,0x91,0xb9,0x06,0xac
+.byte 0x86,0x7f,0x29,0xca,0xfb,0xe9,0xde,0xdb,0x90,0xfe,0x6f,0xbc,0xdb,0x3c,0x48,0x3d,0x6e,0x06,0x68,0x49,0xbb,0x43,0x8d,0x9d,0xc4,0x5f,0x45,0xcb,0x77,0x28,0xe0,0x35,0xd1,0xb4,0x25,0xb2,0x45,0x6d,0xb4,0x89,0x53,0x26,0x33,0x98,0x83,0x45,0x9d,0xf5,0xad,0xf9,0xa7,0x59,0xb6,0x6e,0xa8,0x25,0xa5,0xef,0xee,0xf6,0x6a,0xd5,0x6c,0x60
+.byte 0x9a,0xea,0x78,0x9e,0xe4,0xa2,0x29,0x0b,0x70,0xb3,0x6e,0x3a,0xfd,0x07,0xc7,0x7f,0x1b,0x07,0xc7,0xca,0x1b,0xb8,0x08,0xe1,0xc9,0x94,0xb2,0x62,0x7c,0x04,0x96,0xa6,0xda,0x65,0x28,0xfd,0xf9,0x70,0x22,0xb7,0x21,0xd3,0xa6,0x38,0x0f,0x1e,0x88,0x7e,0x73,0xec,0x04,0x99,0x8b,0x23,0x91,0x13,0xe6,0x4f,0x74,0x81,0xcc,0x1f,0xdd,0xaf
+.byte 0x58,0xc4,0x80,0x00,0x4d,0x1d,0xbe,0x84,0x7d,0xfe,0x85,0xe7,0x77,0x20,0x3c,0x65,0x4e,0x0e,0x2e,0x5d,0xc1,0xd9,0xcb,0xf7,0xbb,0xc8,0x8d,0xbf,0x16,0xa8,0x1e,0x63,0xf5,0x10,0x5e,0xa5,0x9c,0x63,0xb6,0x9a,0xeb,0x98,0xa8,0xb1,0x59,0x82,0x66,0x51,0xae,0x3c,0xfc,0xa8,0x11,0x92,0xf4,0x45,0x88,0x7c,0x03,0x6f,0xe6,0x87,0xe4,0xa8
+.byte 0x79,0xbf,0xb3,0x0d,0xd6,0x0b,0x8d,0xa3,0x16,0x2a,0xfb,0x79,0xb9,0xe7,0xdb,0xa7,0xdb,0x94,0xd3,0xe6,0x3a,0xdd,0xe9,0x5f,0x30,0x7d,0x68,0x90,0x35,0xfd,0x18,0x91,0x8e,0xc5,0x12,0xd6,0xf9,0x98,0xa0,0x5b,0xcd,0x81,0x76,0x84,0x08,0xd0,0xab,0x59,0x2d,0x3b,0x8a,0xf9,0xd9,0x95,0xde,0x8b,0xbb,0x92,0xef,0x35,0xc3,0x3e,0x46,0x73
+.byte 0xf3,0x3b,0x09,0xbf,0x22,0x2b,0x9c,0x0f,0x70,0x9a,0x16,0x0e,0x4b,0xa7,0x1a,0x96,0x98,0xb7,0x5a,0x40,0x06,0x81,0xf4,0xac,0xa6,0xe6,0xab,0xf2,0xda,0x87,0x18,0x61,0xcb,0xc1,0x67,0xbd,0x2f,0x6f,0x06,0x21,0xaf,0x73,0x98,0xe1,0x3f,0x7a,0x17,0x7f,0x44,0xcb,0x1d,0xdd,0x60,0xb3,0x2c,0x58,0x20,0x8a,0x04,0x74,0x56,0x9b,0x26,0x51
+.byte 0x61,0xb0,0x07,0x50,0x53,0x83,0x31,0x42,0x59,0xb3,0x33,0xfa,0xfe,0xbc,0xad,0x7f,0x99,0x9b,0x86,0xf1,0xaa,0x85,0xf1,0xbb,0xc0,0x0c,0x91,0x8d,0x1a,0x0f,0x8f,0x9f,0xfe,0x62,0x2b,0x35,0xae,0xcc,0x8c,0x09,0xe3,0x29,0x96,0xd1,0xbe,0x7f,0x25,0xd6,0x03,0xf0,0x4c,0x53,0xad,0x5b,0x56,0x66,0x68,0x9a,0xa3,0xc4,0x07,0x71,0xde,0x49
+.byte 0x82,0xbb,0xf7,0x9a,0x2b,0x96,0xcf,0x50,0xf6,0x00,0xf7,0x0b,0x27,0xdd,0xf5,0xf6,0xc5,0xc8,0xbd,0x2a,0xa2,0x06,0x2c,0x42,0x3f,0xa0,0xf8,0xcc,0x1d,0x64,0xcf,0xbc,0xb4,0xc4,0x63,0xde,0x6b,0xd3,0xb4,0x61,0xdf,0xbd,0x73,0x50,0x34,0xc3,0x20,0x45,0x06,0x73,0x9b,0xf0,0xfb,0xa6,0x2b,0xec,0x92,0x32,0xa9,0x1f,0x4f,0x1e,0x38,0x78
+.byte 0x2a,0xd2,0x7c,0x1d,0x89,0xf9,0x70,0xbc,0xef,0x09,0x77,0xd3,0x6a,0x56,0xa1,0x8b,0x4b,0x23,0x1b,0xb1,0x2f,0xec,0x84,0xe5,0x59,0xc5,0x20,0x23,0xbc,0x3f,0x0a,0x43,0x97,0x1c,0x5e,0xf7,0xee,0xfe,0x0b,0x2a,0x42,0x08,0x2a,0x39,0x91,0xce,0x8a,0x33,0x9f,0x63,0x77,0x6d,0xf6,0xf3,0x0e,0x1d,0xb3,0xfb,0xcf,0x2f,0x7f,0x95,0xc2,0x71
+.byte 0x1c,0xa0,0x0b,0xc6,0xb8,0xde,0x4d,0xd8,0xcc,0x4c,0x4f,0xaf,0x07,0x87,0x6d,0x3b,0xab,0x95,0xab,0xa1,0x6a,0x50,0x9f,0x7c,0x35,0xb6,0x65,0xdd,0xe3,0x06,0xe5,0xb3,0x42,0x5f,0x4d,0xe5,0x3e,0xfa,0x6c,0xdf,0x19,0x58,0xd1,0xf6,0xc6,0x94,0x1c,0xce,0x30,0x90,0xd3,0xeb,0xa3,0x7c,0xe5,0x3f,0x57,0x99,0x2e,0x22,0x0a,0x94,0x2f,0xfe
+.byte 0x39,0x16,0xe6,0xfa,0xd0,0xb5,0xf9,0xb4,0x88,0x61,0xa4,0xa8,0xc3,0xb8,0xb7,0x52,0xaf,0x90,0xc1,0xe0,0x19,0x78,0x04,0x2b,0x71,0x04,0x03,0x2f,0x63,0xbe,0x40,0xf5,0x82,0x3b,0x1b,0x6b,0xde,0x6d,0x1e,0x86,0x87,0x82,0xc3,0x31,0x97,0x20,0xdd,0xdd,0xce,0x61,0x64,0x99,0xf6,0xbe,0xbf,0xec,0x37,0x54,0x8b,0x92,0x29,0xda,0xc5,0x7b
+.byte 0x4d,0xc5,0xaf,0xb8,0x4e,0x4b,0x4a,0x2b,0x35,0x30,0xf5,0x19,0x9e,0x32,0xd8,0x2e,0xc1,0x19,0xfe,0xd1,0x61,0xb0,0xaa,0x05,0x58,0x15,0xd9,0x0e,0x4e,0xca,0x4e,0x10,0x83,0xe6,0xe6,0x57,0xe8,0x8d,0x13,0xb4,0x6f,0x85,0x59,0xf2,0x83,0xc8,0x37,0xaa,0xa2,0xe5,0xc8,0x77,0x06,0x82,0x21,0x5d,0x84,0x58,0x67,0x9b,0xcc,0x9c,0xfc,0x1b
+.byte 0x28,0x2f,0xac,0xc8,0x96,0x91,0x26,0x46,0x42,0x2b,0x68,0x57,0xb0,0x79,0x1e,0xb1,0x9b,0x92,0x2c,0xeb,0x67,0x00,0xd4,0x26,0x7d,0xca,0x45,0x97,0x55,0xea,0x2a,0x20,0x70,0x7c,0x20,0x14,0x38,0x40,0x3d,0x4f,0xf5,0x3a,0x1f,0x0a,0xe3,0x9a,0x48,0xcc,0xb2,0x7d,0xee,0x5b,0x48,0x90,0x0d,0x12,0x77,0xd8,0xd3,0xb6,0xd7,0x66,0x9e,0x48
+.byte 0xbb,0x92,0xc1,0x7c,0x4e,0x90,0x4d,0xd5,0x96,0x99,0xea,0x86,0x2d,0xb9,0x5a,0x50,0x05,0xc2,0x6b,0xa7,0x0c,0x43,0x44,0x22,0x09,0xb9,0xc0,0x56,0x47,0x5f,0xdf,0xaf,0x6b,0x91,0xe2,0xd7,0x45,0x77,0x17,0x7a,0x71,0x6d,0x27,0x93,0xe2,0xc6,0x10,0x2f,0xc8,0x3b,0x75,0x78,0x11,0xae,0x07,0xe6,0xba,0x64,0xd4,0x06,0xfa,0xf9,0x1d,0x74
+.byte 0x9e,0x4f,0x6d,0x02,0xfc,0x40,0x80,0x9a,0x2e,0xd4,0x15,0x32,0x15,0xe8,0x97,0x0a,0xd4,0x65,0x6a,0x87,0xd3,0x66,0x4b,0xb8,0x66,0x84,0x8e,0xb9,0x4b,0xa7,0xcf,0x58,0x13,0x66,0x3a,0x4e,0xa5,0x76,0x17,0x13,0x92,0x79,0x42,0x67,0x6d,0xb6,0x65,0xec,0xc8,0xb5,0x5f,0x17,0x2a,0x2d,0x4b,0x19,0xe9,0x00,0x6e,0x38,0xaf,0xe9,0x06,0xb6
+.byte 0xe8,0x99,0x69,0x8a,0x74,0xe7,0x7e,0x70,0x69,0x4b,0xbc,0xce,0x5d,0x61,0x94,0x1b,0x47,0x41,0x38,0x5f,0x2e,0xcf,0x2b,0xe1,0xcd,0xa3,0x98,0x71,0xf7,0x09,0x65,0xfe,0x5f,0x62,0x4b,0x9e,0x91,0x88,0x35,0xa2,0x66,0x02,0x1d,0xc9,0x93,0x0c,0x19,0x50,0x4b,0x95,0x71,0x79,0xdd,0x74,0xe1,0xda,0x5a,0xb7,0x38,0x70,0x61,0x18,0x3f,0x68
+.byte 0x08,0x34,0xd8,0xfe,0xbb,0xd1,0xbf,0x57,0xed,0xc2,0x52,0x6d,0x54,0x3e,0xcb,0x0c,0x32,0xc7,0x09,0xa9,0x31,0x10,0xe8,0xbd,0x70,0xe3,0x0e,0xe9,0x4f,0x7a,0xd6,0x42,0x45,0x2e,0x1b,0x3c,0x0d,0x15,0x6d,0xb4,0xad,0xe9,0xc5,0xa2,0x12,0x77,0x34,0x43,0x20,0x95,0xc1,0xb7,0x51,0x72,0xed,0x78,0xa0,0xae,0x3c,0xae,0xb4,0xd4,0xda,0x58
+.byte 0x83,0x62,0xa9,0xc6,0x01,0x3d,0x14,0x19,0x07,0x00,0x3c,0x82,0x16,0x7e,0x8a,0x91,0x78,0xa1,0x65,0x0b,0x5b,0x3a,0x40,0x72,0xe5,0xf0,0xd4,0x82,0x04,0xe4,0x01,0xf1,0x84,0x87,0x96,0x26,0x91,0x66,0x77,0xf7,0x59,0xd6,0xc2,0xca,0x29,0x3b,0x68,0x2a,0x27,0x99,0x64,0x86,0xc2,0x96,0xbf,0x11,0x3c,0xa8,0x0c,0xf7,0x86,0xb8,0xc1,0x40
+.byte 0x15,0x1a,0x84,0xe3,0x93,0x23,0x73,0xa9,0x8b,0xbd,0xb4,0x8a,0xe4,0xf1,0xa5,0x8f,0x56,0xa3,0xdc,0x77,0xbd,0x7d,0x15,0x74,0x2b,0x18,0x92,0x56,0x45,0xbc,0xaf,0xf2,0x55,0xce,0x9d,0xc2,0xab,0x39,0x90,0xec,0x78,0x3f,0xa5,0x14,0xeb,0x40,0x2f,0x01,0xca,0xeb,0xad,0x73,0x85,0xbc,0xe1,0x91,0xaa,0x77,0xa9,0x6c,0x02,0x66,0x6a,0x65
+.byte 0x63,0x6c,0x50,0x62,0x83,0x83,0xef,0x16,0x4f,0x21,0xfd,0x28,0x8e,0x52,0x66,0x5b,0x6f,0x8f,0xbe,0x8d,0x17,0xb9,0xd5,0x99,0xf7,0x39,0xd1,0xbc,0xa2,0x43,0xd7,0x0a,0x80,0xea,0x42,0xf8,0x38,0x53,0x95,0x07,0x6f,0xb7,0x7c,0xc1,0x16,0x88,0xc8,0xb7,0x59,0xde,0x76,0x51,0x2f,0x92,0xd0,0x40,0xfd,0xd9,0x2d,0xca,0x9e,0x8d,0x28,0xae
+.byte 0x48,0xc1,0x0a,0xe0,0x76,0x9c,0x02,0x0b,0xc5,0xd1,0xf9,0x83,0x90,0x86,0xa4,0xeb,0x5c,0x64,0x65,0xf8,0x98,0x38,0xc5,0xce,0xef,0x6f,0xc3,0x88,0xb6,0x2f,0x8a,0x40,0x55,0x52,0x47,0x06,0x75,0x16,0x46,0x9c,0xff,0x3c,0x68,0x97,0xc3,0xfb,0x10,0x11,0x7b,0xba,0x04,0xcc,0xad,0xba,0xcf,0xf0,0xae,0xba,0xe6,0x59,0x9c,0xf5,0x27,0xeb
+.byte 0xdd,0x5c,0x86,0x25,0xa1,0xb6,0xb8,0x1c,0x94,0x98,0xa5,0x79,0x82,0x4e,0xdf,0x09,0x3f,0x2f,0x8a,0x4e,0x1b,0x5a,0xab,0xd4,0xe6,0x21,0xb3,0x02,0x19,0x39,0xa9,0x2e,0x0e,0xae,0x86,0x30,0xc7,0xa0,0x00,0xed,0x72,0xdc,0x71,0x77,0x42,0x76,0x54,0x68,0xb2,0x8d,0x5d,0xc3,0x5c,0x86,0xf8,0xb1,0x6c,0x67,0xdf,0x24,0x40,0x6a,0x2b,0x1d
+.byte 0xbc,0x0d,0x25,0x7d,0x9e,0x1c,0xbd,0x18,0x85,0xda,0x7a,0x86,0x5e,0xed,0x10,0x80,0x83,0xa6,0xef,0x1e,0x93,0xac,0xce,0xe6,0x32,0x35,0xdf,0xb8,0xc7,0x9b,0xf0,0x0f,0x9d,0x37,0xbd,0xd9,0x58,0x33,0x19,0xa1,0x23,0x51,0x5f,0xa7,0x5a,0x99,0x7e,0x2a,0xfd,0x85,0x3c,0x26,0xad,0xcc,0x7e,0x07,0x32,0x7b,0x24,0x5a,0x6b,0x4b,0x71,0x4e
+.byte 0xca,0x8b,0xc4,0x03,0x26,0x76,0x02,0x68,0x0d,0xa1,0x09,0xe0,0x2e,0xa4,0x82,0x88,0x05,0x5a,0xc4,0xcb,0x31,0x9d,0x56,0xda,0x0d,0x00,0x04,0xbc,0x07,0xca,0x1f,0xdf,0x9e,0x44,0xed,0x36,0xbd,0xa0,0x22,0xff,0x78,0xd1,0xcb,0x62,0xe0,0x0d,0x2e,0xdc,0x2e,0x36,0x28,0x8e,0xd3,0xa9,0xe0,0x38,0xd4,0xc5,0x2b,0xee,0xaf,0xa4,0x08,0x7d
+.byte 0xed,0x2c,0x8a,0xf5,0x86,0x5e,0xed,0x2a,0x0d,0xbf,0xe6,0xfb,0x6f,0xc4,0x02,0x75,0x36,0xe5,0x7b,0xe9,0x4a,0xb3,0xf1,0xf4,0x86,0x6c,0x9a,0x6e,0xaa,0x7a,0xbe,0x4b,0xd6,0xf2,0x6b,0xcb,0x78,0x6f,0xf9,0x42,0x1a,0x19,0x7b,0x7e,0xba,0x59,0x02,0x8b,0xe3,0x5c,0x44,0xa4,0x84,0xa8,0x4a,0x67,0x93,0xee,0xc4,0x17,0x07,0x26,0xfe,0x86
+.byte 0xf1,0xc6,0xba,0xbf,0xc4,0x3d,0x33,0x41,0x4d,0xc4,0xf0,0xa8,0x6d,0xe1,0x06,0x16,0x2d,0xc9,0x5d,0x2a,0xf5,0x4a,0xc6,0xd2,0x8c,0x98,0x55,0xe8,0x8d,0xd0,0x31,0x5f,0xc7,0x05,0xd1,0xca,0xd2,0x72,0xe6,0xd0,0xcb,0x62,0x79,0xac,0x60,0x59,0x94,0x59,0x48,0x9e,0x91,0x17,0xa7,0xa0,0xac,0x4a,0xe5,0x08,0xe5,0x52,0xa4,0xd4,0x83,0x8c
+.byte 0x83,0x57,0xe7,0xe5,0xfc,0x9b,0x43,0x78,0xc8,0x7e,0x94,0xc4,0x35,0x3e,0xac,0x4a,0x8d,0x60,0x80,0xdc,0x72,0xe3,0x15,0x09,0x2a,0xbd,0xcc,0x9a,0xe4,0x1a,0x18,0xa8,0xf1,0x29,0x9b,0xca,0x58,0x0b,0x6d,0x7b,0x33,0x91,0x05,0x27,0x6a,0x48,0xbe,0xac,0x08,0xa5,0x2a,0x64,0xf5,0xae,0x2a,0x90,0xf1,0x2d,0x3f,0xa8,0xff,0x17,0x92,0xc4
+.byte 0xec,0x3a,0x09,0xbf,0xae,0xd3,0xe2,0x1c,0x3c,0xc8,0x6f,0x91,0x72,0x99,0xe3,0x82,0x30,0x4f,0x40,0x5c,0x0c,0x8d,0xfd,0xbe,0x10,0xbc,0xce,0x1e,0x0a,0x09,0xbf,0xde,0xdc,0x72,0x7e,0x4c,0xbc,0xec,0x34,0xe2,0x96,0x8a,0xc6,0xee,0x19,0x6c,0xa8,0xf1,0xa5,0xb2,0x71,0x88,0x13,0xe8,0x11,0xda,0x3b,0x77,0x10,0x9c,0x9f,0x74,0x49,0x21
+.byte 0x16,0xcf,0x6f,0x05,0xc5,0xc1,0x4d,0xfe,0xe7,0x4d,0x67,0xe8,0x12,0x14,0xf7,0xaf,0x66,0x8d,0x55,0x34,0x00,0x18,0x10,0x6e,0x6a,0xd2,0x4c,0xd9,0xd3,0x15,0x40,0xbf,0xce,0x7b,0x10,0x69,0xbd,0x15,0x0e,0x60,0x2b,0x76,0x50,0x80,0x92,0x02,0x3c,0x0f,0xea,0x47,0x03,0xd9,0xf6,0x2c,0x00,0xde,0x29,0xb9,0x2e,0xf6,0x80,0x10,0x81,0x28
+.byte 0x6f,0x41,0xfc,0x88,0x65,0xe9,0xb5,0xd4,0x78,0x53,0xff,0x04,0xc4,0xdd,0xd7,0x35,0x34,0x59,0x85,0x33,0x01,0x33,0x67,0xe1,0x4e,0xc2,0xac,0xe6,0x24,0x24,0xb6,0x83,0x48,0x08,0x0c,0x73,0xe5,0x9c,0x98,0xe4,0x4c,0x3c,0x1f,0x6e,0x77,0xea,0x8c,0x76,0x23,0xbb,0x41,0x5e,0xc1,0x8a,0xba,0x3e,0xe5,0x3e,0x86,0x89,0xab,0x32,0x65,0x1b
+.byte 0x00,0x92,0x56,0xe0,0x62,0xc1,0x8f,0xeb,0x15,0x7f,0x86,0xdf,0xa2,0xc2,0x8d,0xf5,0xb5,0x88,0x72,0x8c,0xba,0x92,0x30,0x53,0x58,0x3e,0x0b,0xe6,0x4f,0xd4,0xef,0x34,0xab,0xbb,0x61,0xe0,0x31,0x3c,0xe7,0xb2,0x5f,0x64,0xcb,0x52,0xc7,0x1d,0x95,0x96,0xd2,0x8c,0x87,0x34,0x92,0xf2,0xad,0xd9,0x78,0x1d,0xa1,0x67,0x58,0xfa,0xfb,0x06
+.byte 0xc8,0x7f,0x9e,0xf7,0x02,0x12,0xd9,0x8c,0x68,0xbc,0x2b,0xd3,0xe1,0x0e,0x1e,0xbd,0x33,0x7a,0xfd,0x03,0x41,0xb9,0x72,0x2e,0x63,0xfe,0xb1,0x39,0xc3,0x0f,0xa0,0xa9,0x76,0x4f,0x7b,0xab,0xae,0xda,0x22,0xec,0x83,0x32,0xb0,0xec,0xd1,0xfd,0xc2,0x28,0x1e,0x42,0x29,0x31,0xd5,0xb3,0x33,0xcd,0x13,0x1d,0x9f,0xac,0x73,0x27,0xf7,0xea
+.byte 0xc6,0x66,0xd2,0x32,0x91,0x60,0x35,0xf4,0x28,0x34,0x43,0x6a,0x74,0x8c,0x05,0x2a,0x84,0x34,0xfd,0x84,0xa5,0xcb,0x1d,0x2b,0x41,0x28,0xa6,0x19,0xed,0xcd,0xad,0xea,0x6e,0xf7,0x14,0x18,0xac,0x56,0x9a,0xf5,0xaa,0x7d,0x4e,0x8a,0x99,0xd1,0xda,0x41,0xaf,0xe8,0xfc,0xef,0x66,0x88,0xd0,0xed,0xfd,0xae,0x2a,0x85,0xc0,0x60,0xa2,0x30
+.byte 0x5d,0x1b,0x48,0xf6,0x3e,0xcf,0x56,0xdf,0x53,0xdc,0x2d,0xf5,0xfd,0x7f,0x2a,0x2a,0x4d,0x4f,0x11,0xcc,0xea,0x72,0xdb,0xb9,0xeb,0x92,0x0e,0x9f,0xc1,0x26,0xe9,0xbf,0x25,0x6a,0x27,0xe1,0x63,0x9b,0xdd,0x62,0x38,0xad,0xd3,0xb2,0x75,0x62,0x45,0xbf,0xbf,0xf4,0xe2,0xd6,0x97,0xe9,0xeb,0xeb,0x98,0xab,0x73,0xdc,0x8a,0xde,0xaa,0x3b
+.byte 0x69,0xfd,0x61,0x6f,0xbb,0xfc,0x28,0xc0,0xff,0x37,0x2e,0xeb,0x31,0x59,0x57,0xfb,0xd3,0x0e,0xed,0x01,0x66,0x50,0x63,0x53,0xa2,0xd1,0x24,0x8c,0xc8,0x8d,0x80,0x03,0x2a,0x1e,0x11,0x3a,0xb9,0x6c,0xf4,0x5f,0x58,0xa2,0xd6,0x58,0x6b,0x85,0x61,0xd1,0xe7,0xdc,0x90,0x07,0x34,0x6e,0xb9,0x0b,0x0d,0xcb,0xd5,0xe3,0xc6,0x9d,0xb8,0x51
+.byte 0x37,0x61,0xd0,0x6c,0x2e,0xed,0xe0,0xbc,0x55,0x74,0x63,0x1b,0x42,0x17,0x6a,0x9c,0x91,0x1b,0x96,0x76,0xc8,0xe4,0x2b,0x2e,0x90,0xd9,0xe5,0x3f,0x56,0x1b,0x2f,0x93,0x81,0x86,0x2a,0xb4,0xdf,0x93,0xcb,0xfa,0x01,0x85,0xd9,0x26,0x46,0x46,0x97,0x2a,0x2e,0xb3,0x91,0xe4,0xcf,0xd9,0x01,0x5a,0x37,0xa6,0xca,0x5e,0xed,0xa9,0x94,0x35
+.byte 0x2c,0x69,0x5b,0x1e,0xf8,0x38,0x61,0x41,0x10,0xf6,0xe9,0x6e,0x96,0xee,0xe6,0x5f,0x78,0x14,0x93,0x12,0xd2,0x57,0xe5,0xf4,0x58,0x46,0xca,0xc8,0x75,0x59,0xbd,0xd0,0xe4,0x70,0x35,0xa5,0x4a,0xfd,0x54,0xe2,0x91,0x76,0x0e,0xe6,0xe3,0xbb,0x31,0x65,0x4b,0x18,0xa8,0xb4,0xfa,0xa6,0x7d,0x7a,0xa9,0x47,0x3d,0x2b,0x2e,0x66,0xac,0x5b
+.byte 0x3e,0x5e,0x8c,0x27,0x0c,0x33,0x04,0x03,0x4e,0x5f,0xcd,0x6b,0x9c,0xaa,0x13,0x83,0x38,0xe9,0x38,0xcf,0x03,0x70,0x5a,0x0f,0x18,0xf5,0xec,0x64,0xf3,0x0c,0xe8,0xb1,0xa9,0x07,0x70,0xf7,0xde,0x0c,0x35,0xf5,0xe2,0xcd,0xed,0xe6,0x4d,0xac,0x5c,0x4d,0x3e,0x03,0x96,0x90,0x7b,0x4c,0x3e,0x18,0x42,0xc0,0xa7,0x23,0x12,0x8e,0x54,0xc1
+.byte 0xa1,0x2f,0x82,0x13,0xe6,0x1f,0x74,0xae,0x7b,0x4a,0xa4,0xbb,0xdc,0xc0,0x68,0x0f,0x83,0xbc,0xda,0xce,0xa2,0xe7,0xbe,0x18,0xcd,0x8b,0x35,0x05,0xa3,0x4b,0x6f,0xf0,0x53,0x12,0x42,0x2f,0x3c,0x09,0x87,0xb7,0xe3,0x36,0x29,0xe1,0xa2,0xb6,0x60,0x05,0xb9,0x66,0x80,0xe9,0xec,0x40,0x2a,0x55,0x78,0x5f,0x1c,0x5f,0xc3,0xc7,0x49,0x69
+.byte 0x87,0x97,0x5f,0xa5,0x31,0xa8,0x83,0x66,0x5a,0xd7,0xaf,0xf0,0x15,0xf3,0x01,0x62,0x9a,0x88,0x76,0x0f,0xb3,0xdf,0xf1,0xc6,0x34,0xc3,0xac,0x68,0x60,0x9a,0x91,0x03,0x13,0xea,0x0e,0x36,0x9c,0xf5,0x51,0xb7,0x0c,0xa4,0xeb,0xf0,0x41,0x85,0x54,0x05,0xed,0x7a,0xc2,0xba,0x3b,0xb8,0x1c,0x41,0x0d,0xbb,0xad,0x16,0x7e,0x64,0x4f,0x88
+.byte 0x7a,0x17,0xae,0x76,0x55,0x78,0x93,0xe8,0x99,0xa1,0x70,0x1f,0xf6,0x8a,0xb9,0xeb,0x41,0xb9,0x08,0xb8,0x9d,0x78,0x57,0xa1,0xe1,0x23,0xa0,0x03,0xd3,0x16,0xbc,0x16,0x24,0xed,0xc5,0x12,0x16,0x0a,0x8a,0x23,0x11,0x22,0xc2,0xfe,0x49,0x9d,0x3d,0x10,0x3d,0x4b,0xeb,0xab,0xcb,0x21,0x9d,0x9d,0xb1,0x64,0x87,0xe5,0x4d,0xb9,0xe7,0x10
+.byte 0x05,0xa0,0x55,0x2f,0xdf,0x53,0x5e,0x03,0xec,0x7e,0xe4,0x1f,0x9b,0x16,0x0c,0xfc,0xd9,0xf9,0x66,0x39,0x93,0x9e,0x49,0x34,0x97,0xd6,0xa5,0x56,0x00,0xf1,0xaf,0x08,0xeb,0x58,0xcf,0x87,0x02,0xc4,0xf1,0x24,0xe8,0x29,0x83,0xc9,0x5d,0x56,0x68,0xa2,0xaa,0xba,0xb3,0x86,0x23,0x59,0x8d,0x32,0x96,0x4a,0xbb,0xe9,0xf2,0x53,0xb2,0x87
+.byte 0x4a,0xf5,0xdc,0x23,0xd4,0x2f,0x36,0x70,0xb5,0x1d,0xee,0x47,0x51,0x6c,0x35,0x2a,0xad,0x35,0x74,0x1b,0x98,0xb5,0x33,0x2c,0x6d,0x4c,0xf8,0x39,0x07,0x92,0x6c,0xc7,0x65,0x10,0x64,0xcd,0x53,0xa3,0xcb,0xcc,0xe4,0xb2,0x46,0xb3,0xb7,0x44,0x01,0x92,0x44,0x12,0x23,0x25,0x3e,0x00,0xe3,0xeb,0x5f,0xe5,0x76,0x48,0x4e,0x4a,0x7f,0x36
+.byte 0xf0,0x0b,0x5e,0xc0,0x97,0x0d,0xc8,0xcf,0xd5,0xb8,0xc0,0x11,0x8d,0xb9,0x1e,0x31,0x0f,0x84,0x36,0x2e,0xe0,0x42,0xe6,0x02,0x9d,0xa4,0xdb,0xa2,0x76,0xfd,0xa1,0x95,0xe0,0x49,0xe6,0xf1,0xd2,0xae,0x27,0x6b,0x11,0x05,0x47,0xb0,0xaa,0x61,0x01,0xd4,0xe6,0xcd,0x9d,0x7e,0x33,0x5d,0xec,0x22,0x96,0x59,0xb7,0xc5,0x50,0x83,0xa4,0x66
+.byte 0x56,0xc7,0x43,0xa6,0xf7,0x5d,0xb2,0x45,0xc0,0x96,0xa0,0x5b,0xb8,0xed,0xae,0x29,0xb3,0x7d,0xbd,0x01,0xde,0xc0,0xe7,0xcc,0xe9,0x55,0x32,0x32,0xbf,0xdd,0x03,0x1b,0xb0,0x4e,0xff,0x53,0x1f,0x4b,0xc6,0xec,0x16,0x9d,0x5b,0x78,0x74,0xc4,0x75,0x51,0x8a,0x1c,0xae,0x6b,0xcd,0x9c,0x77,0x47,0xbf,0xd1,0x38,0x3e,0x9e,0xc0,0xad,0x16
+.byte 0xb7,0x15,0x6b,0xdc,0xad,0xe9,0x13,0xbc,0x48,0xc1,0xaf,0x69,0xce,0xc4,0xcc,0x9b,0x73,0xf9,0xd5,0x7c,0xab,0xf0,0xf1,0x9b,0xea,0xc6,0x0b,0x19,0x47,0x42,0xc1,0xa0,0x02,0x64,0x17,0xce,0x88,0x4f,0x16,0xa6,0xed,0xdb,0xfe,0x61,0xd3,0xd6,0xc0,0x11,0x30,0x16,0xd2,0x45,0xb3,0x7e,0x52,0xd0,0x94,0x77,0xf0,0x0e,0xbf,0x16,0xc0,0x4a
+.byte 0x2a,0x5c,0xac,0x55,0x57,0xb1,0x41,0xb6,0xa3,0x68,0x8c,0x0a,0x66,0x15,0xb4,0xf5,0xd9,0x9a,0xa9,0x68,0xf2,0xbc,0x06,0xc5,0x7c,0xd1,0x18,0x55,0x9a,0x2d,0x94,0x2e,0x04,0x4b,0x7d,0x3c,0xb1,0xe3,0x03,0x7a,0xa7,0xe3,0xe5,0x63,0x49,0x7c,0x3f,0x0a,0xc5,0xbd,0xd3,0x0f,0x04,0xfd,0x99,0xf7,0xe6,0x05,0x35,0x66,0x17,0x05,0x85,0x3b
+.byte 0x98,0x92,0x11,0x26,0xe2,0x21,0x52,0x1b,0x54,0x08,0xc8,0xf0,0x4e,0x75,0x22,0x3f,0xe8,0xb6,0x35,0xa4,0x02,0x52,0x70,0xc2,0xce,0x5a,0x00,0xe2,0xe2,0x92,0x8c,0x97,0xa7,0x1d,0x42,0x52,0x8b,0xf1,0x81,0xa7,0xce,0x60,0x46,0xbe,0xf0,0x1d,0x34,0xdf,0x73,0x2a,0xd6,0x9a,0x2d,0xf9,0xe3,0x91,0x05,0xe4,0x1f,0x31,0x11,0x30,0xb0,0xff
+.byte 0x8f,0x61,0x74,0xf4,0xef,0xcd,0xf6,0xa4,0x9a,0xd2,0x5e,0xba,0x27,0xe8,0x78,0x38,0xfc,0x75,0xff,0x3b,0x6c,0xde,0x4a,0x46,0x47,0x8e,0x97,0x28,0xe4,0x23,0xe0,0x10,0x07,0xca,0xcb,0x6d,0xed,0x29,0xc0,0xee,0x98,0x96,0x7c,0x90,0x1f,0x89,0x12,0x0f,0xd5,0x28,0xcf,0x6e,0x4b,0x9b,0x2d,0xb3,0xcd,0x97,0xb8,0xeb,0x58,0x23,0x26,0xb1
+.byte 0xb4,0x95,0x11,0x1e,0xee,0x00,0xde,0x24,0x28,0xa6,0x3f,0x15,0xa2,0x9a,0xcb,0x9d,0xe3,0x04,0x5d,0xc3,0x60,0x97,0x14,0x2c,0x84,0x2b,0x69,0x9c,0x2a,0xbf,0x08,0xba,0xc4,0x38,0x36,0xaa,0x89,0x11,0x32,0x63,0x01,0xa2,0x44,0x5f,0x50,0xf0,0x5b,0x11,0x15,0xc8,0x80,0xc9,0xa6,0xe7,0x5d,0x70,0xa8,0x34,0x42,0x97,0x2a,0x60,0x99,0x20
+.byte 0xa6,0x60,0xc0,0x70,0x8d,0x2f,0x3f,0x8a,0x14,0x80,0x8a,0xbe,0x05,0xb3,0x50,0x16,0xaf,0x32,0xb4,0x35,0x3e,0x1d,0x31,0x42,0xdd,0x50,0xeb,0x04,0x82,0x4c,0x83,0x3d,0x8f,0xb6,0x1e,0xc2,0xa9,0xd2,0x30,0xba,0x33,0xdb,0x97,0x6d,0x2d,0x97,0x59,0x33,0xc0,0xf8,0xa5,0x59,0xc5,0x44,0x9c,0xf1,0x06,0xc4,0xf2,0x31,0x3e,0xff,0xb8,0x12
+.byte 0x00,0x4d,0x6c,0x2d,0xa1,0xc7,0x83,0xea,0x55,0x93,0x0e,0x89,0x76,0xbf,0x56,0x2a,0x99,0x62,0x54,0xad,0x2c,0xe8,0xf0,0xf9,0x70,0x18,0xa5,0x2b,0x24,0xac,0x59,0xc9,0x84,0xe3,0x1a,0x9d,0xa0,0xdb,0x1b,0x7f,0xd5,0x7e,0xb5,0xe0,0x86,0x36,0xc5,0x71,0x6a,0xab,0xdb,0xa5,0x84,0xf1,0x9e,0x9e,0xf6,0x1b,0xab,0x47,0x94,0x38,0x8e,0x5d
+.byte 0x55,0xb4,0xf5,0xc3,0x59,0xc2,0x2c,0x6d,0x9d,0x28,0x7d,0x33,0xcd,0xc7,0xd6,0xdf,0x10,0xda,0x7c,0xd0,0x6c,0x91,0x88,0xd6,0x6b,0xe7,0x72,0x75,0x18,0xb1,0x87,0xe4,0xbb,0x10,0xe0,0xa3,0x0f,0xea,0x65,0x0a,0x70,0xc8,0xee,0x52,0x05,0x0a,0x27,0x39,0x66,0xda,0xd6,0xa6,0xfe,0x97,0x24,0x09,0x9d,0x20,0x76,0x4e,0x97,0x9d,0xa9,0x9f
+.byte 0x76,0x20,0x27,0x57,0x5b,0xf4,0x76,0x1a,0x4b,0xcf,0x13,0x6c,0x9e,0x63,0x53,0x97,0xca,0x10,0xd6,0x90,0x7d,0xfc,0xe3,0x03,0x2c,0x6c,0x79,0x93,0x1a,0xae,0x0f,0x43,0xdb,0x75,0xde,0x56,0xa6,0x69,0x93,0xce,0x2d,0x94,0x56,0x77,0x90,0x19,0x71,0x7f,0x7a,0x99,0xbd,0x9c,0x79,0x62,0x00,0x49,0x3a,0x62,0x49,0x4b,0x92,0x65,0x8b,0xe2
+.byte 0xa8,0x3d,0xa5,0x89,0x23,0xac,0xea,0xf1,0xbf,0x38,0x84,0xd7,0xe2,0x65,0xb6,0xc7,0xbc,0x02,0x11,0xfd,0xe3,0x4c,0x57,0x38,0xd4,0x36,0x54,0xe8,0xbb,0x63,0x17,0xe9,0xda,0x82,0x50,0xf1,0x8c,0x34,0x4d,0x75,0x2a,0x64,0x49,0xaf,0x98,0xc3,0x1d,0xad,0x31,0xf3,0x90,0x23,0x39,0xf5,0xb5,0xf4,0x37,0x88,0x67,0x12,0x5d,0xfc,0xee,0xe5
+.byte 0x44,0x52,0x2c,0x78,0xb1,0x90,0xc1,0xc2,0x77,0x6e,0x31,0x3e,0xa0,0x36,0x87,0xb0,0xc6,0x6c,0x94,0xc2,0x43,0x4a,0x7b,0xa2,0x73,0xe7,0xa0,0xc3,0x4c,0xaf,0x4f,0xa6,0x92,0x1c,0x9a,0x6d,0xee,0xe8,0x4d,0xe1,0xe0,0xc7,0x67,0xcf,0xcf,0x7d,0x7f,0x0f,0x07,0x0d,0x6c,0x06,0x06,0xc2,0xc9,0x28,0xfc,0x8d,0xcd,0x23,0x01,0x97,0x5b,0x4d
+.byte 0x1c,0xdb,0x34,0x51,0x6e,0xe2,0x56,0x24,0xd7,0xbd,0x12,0xc4,0x2f,0xb4,0x3b,0x02,0xaa,0x47,0xda,0x61,0xf6,0xca,0x44,0xa8,0x02,0xbf,0xbc,0x58,0xfb,0xa2,0xff,0xf3,0x54,0x59,0x5f,0xd7,0xa0,0x7c,0x83,0xa6,0xef,0xeb,0x71,0x51,0x74,0xa1,0x27,0x10,0x97,0x13,0x1f,0x42,0x91,0xdd,0xa8,0xf8,0xc7,0x60,0x90,0xca,0x2e,0xc8,0xaf,0x9f
+.byte 0x65,0x1f,0x24,0x0a,0x30,0x5f,0xb9,0x4c,0xfb,0xcb,0xa3,0x96,0x5e,0xad,0xab,0xac,0x09,0x91,0xf5,0x96,0x1f,0xe0,0x96,0x14,0xc5,0xa0,0x26,0xa1,0xf1,0x91,0x80,0x38,0x7f,0x38,0xdc,0x98,0x96,0x20,0x46,0x50,0x20,0xd2,0x20,0xce,0x79,0xd5,0x81,0x60,0x97,0xb2,0xb0,0xeb,0x58,0x75,0x3c,0x99,0xf0,0xe0,0xfd,0xfc,0x90,0xc5,0xd1,0x3d
+.byte 0x68,0x07,0xfd,0xa1,0x3f,0xeb,0x47,0xd0,0x58,0xe3,0xfa,0xbe,0xbf,0x20,0xdf,0x66,0x08,0x91,0xa4,0x5c,0x52,0x3e,0xdf,0x5c,0xb8,0xee,0xca,0xa6,0x89,0x06,0x97,0xb4,0x8d,0x60,0x35,0xb1,0xff,0x1e,0x39,0xf2,0x67,0xbc,0x71,0xee,0xeb,0x48,0x94,0x19,0x1a,0xee,0xc5,0xe2,0x7e,0x0d,0xf1,0xca,0xe8,0x2c,0xb0,0xaa,0x02,0x58,0x23,0x23
+.byte 0xce,0x37,0x5e,0xcb,0x58,0x40,0x2e,0x1a,0xa6,0x09,0x11,0x95,0xc4,0x6f,0x10,0xb0,0x15,0x22,0x48,0x67,0x74,0x6c,0x2f,0x4f,0x4a,0xb4,0x01,0xe5,0xa3,0x77,0xab,0xad,0xa4,0x04,0x22,0x71,0x58,0x4a,0x71,0xb1,0xe8,0xdf,0x43,0x18,0x0e,0x95,0x7c,0x8c,0x23,0x3a,0xf3,0x9c,0x20,0x60,0x20,0x69,0x51,0x28,0x7e,0x13,0x67,0x5c,0x7d,0x35
+.byte 0xfa,0x1b,0x04,0x8b,0xcf,0x42,0x6e,0x15,0x55,0xcd,0x04,0xdb,0x73,0xdb,0x47,0x5f,0x83,0x6e,0xd1,0x5a,0x15,0xa2,0xbb,0xf7,0xbb,0x84,0x58,0xce,0x75,0xe8,0xd2,0x92,0xd5,0xb7,0x76,0xf2,0x94,0x67,0x27,0x5f,0x32,0x91,0x3a,0xaf,0xd4,0x31,0xf8,0x92,0xce,0x63,0xb7,0x45,0x27,0xb4,0xb8,0x7a,0x1e,0x4e,0xde,0xcb,0xc8,0x5e,0xd3,0xbb
+.byte 0x52,0x91,0xd5,0x72,0xad,0x98,0xec,0x07,0xa1,0x56,0xb4,0x8e,0x04,0xfa,0x48,0x3f,0x17,0x07,0xf7,0xef,0x92,0x61,0x69,0xaf,0xdd,0xfc,0x76,0x03,0xe2,0xe9,0xe2,0xbe,0x5c,0xf2,0x8a,0xc5,0x99,0x51,0x7f,0xa4,0xf1,0xac,0x16,0xec,0x16,0xf5,0xb8,0x95,0x88,0x87,0xdb,0x27,0x2e,0x63,0x12,0x31,0x7d,0x6b,0x2b,0xa0,0x9b,0xb5,0xf9,0x82
+.byte 0x42,0x04,0x94,0xee,0x60,0x6e,0x4e,0x54,0x9b,0xfd,0xeb,0x01,0x3a,0xad,0x42,0xeb,0x08,0x3c,0x6a,0xa3,0xf2,0x46,0xfb,0x18,0x59,0x2c,0xa3,0x0b,0x22,0x1d,0x5d,0x47,0xa6,0x8c,0x06,0x9c,0xa1,0xcc,0x20,0x67,0xbd,0xf0,0x5b,0x94,0x9f,0xc6,0x10,0x8c,0xc8,0x15,0x52,0xe3,0x19,0xa1,0x89,0xfd,0x99,0xad,0x4f,0x10,0x51,0x0a,0xe4,0x4b
+.byte 0x02,0x7b,0x0d,0x73,0x2d,0xae,0xa4,0x68,0x1d,0xb6,0xcf,0x58,0x67,0xc0,0xd0,0xca,0x11,0x34,0x31,0x9e,0xa3,0xbc,0x12,0x28,0x1e,0x8e,0x5a,0x63,0xf5,0xda,0xf2,0x36,0x94,0x63,0x2c,0x39,0x3d,0xf9,0x80,0x9f,0xbf,0x8d,0xef,0x1f,0x15,0xc8,0xdb,0x62,0x58,0x7d,0xdc,0x0a,0x7f,0x87,0xaf,0x6d,0x2e,0xac,0x92,0x4f,0x51,0xdf,0x5e,0x75
+.byte 0x5e,0x0f,0x7c,0x51,0x49,0x88,0x0f,0x7b,0x49,0xa5,0x7c,0x41,0x4e,0x2a,0x0f,0xd0,0x0f,0x78,0xeb,0x42,0xfc,0x07,0x8a,0x8b,0x4e,0x3e,0xf2,0x42,0xc5,0x21,0x01,0x66,0xe2,0x50,0xf6,0x3d,0x28,0x1e,0xbf,0xdc,0x71,0x7f,0xc5,0x6e,0xc1,0xab,0x1a,0x33,0x49,0xdd,0xa2,0xb9,0x52,0xbe,0x93,0x97,0x97,0x7a,0xf0,0x22,0xa8,0xc5,0x01,0xc6
+.byte 0x76,0x6f,0xb6,0x2c,0x09,0x80,0x62,0x5b,0x84,0x05,0x7f,0x79,0x28,0x04,0x67,0xa2,0x0f,0xfc,0xbb,0x17,0xe2,0x85,0xe3,0xa0,0xf3,0x44,0x47,0x96,0x68,0x80,0xb2,0xbf,0xba,0x63,0x53,0x38,0x6c,0x3b,0xcd,0x3c,0xa4,0x10,0x48,0x80,0xd8,0x49,0x5a,0xf0,0x5c,0x38,0x02,0x02,0x5b,0xf2,0x77,0xa4,0xfd,0x16,0xfd,0x13,0xc8,0x8b,0x9b,0xcd
+.byte 0xe1,0x8d,0x70,0xb6,0x3d,0x24,0x65,0xda,0x1a,0x42,0x6f,0x90,0x64,0x9a,0x9b,0xda,0x54,0x44,0xc0,0xe0,0xd7,0xfb,0x73,0x10,0x3c,0xcf,0xa6,0x04,0x99,0xd9,0x45,0xe5,0x74,0xfe,0xdf,0x81,0xac,0xc8,0x30,0xe5,0x66,0x45,0x02,0xca,0xcd,0xd7,0xe6,0x7b,0x0d,0xda,0xe1,0xa0,0xa1,0xa1,0x87,0x34,0x63,0x0b,0xa7,0x82,0x39,0x83,0xba,0x18
+.byte 0x0b,0x16,0x35,0x11,0x53,0x8d,0xbe,0x7d,0xa8,0x7e,0x3f,0xf4,0x71,0xc9,0x37,0x6f,0x1a,0xd9,0x3f,0x8e,0xc4,0xc1,0xd3,0x80,0xdf,0xee,0x0e,0x6b,0x23,0xf7,0xbc,0x42,0x93,0x7a,0x36,0x6f,0x03,0x24,0xb4,0x9c,0x62,0xa0,0xed,0xed,0x0b,0x66,0xa8,0x25,0xe6,0x1a,0xd4,0x13,0xd1,0x16,0x14,0x2b,0x90,0x7d,0x2e,0xa4,0xda,0xb2,0xf9,0x33
+.byte 0x54,0xf9,0x0a,0x04,0x27,0x03,0x14,0xd2,0xd7,0xe2,0xc1,0xaa,0xb6,0xe8,0xe5,0x4c,0xf2,0xdb,0x4c,0xc8,0xb3,0xa4,0xeb,0xbf,0x12,0x5c,0x9d,0x65,0xaa,0x9a,0x66,0x77,0x42,0xb4,0xd5,0x5b,0x1f,0x3b,0xd7,0x91,0x89,0x57,0x2f,0xd0,0x86,0x99,0xb2,0xc8,0xc1,0x31,0xde,0x33,0x43,0x36,0x81,0xdb,0x97,0x7b,0x17,0x3b,0xa5,0x99,0xdb,0x63
+.byte 0x2b,0x48,0x4c,0xa6,0x5c,0x6c,0xd8,0xc9,0x6e,0x72,0x39,0xbe,0x6e,0x55,0x7e,0x9d,0xb7,0x20,0x8d,0x8f,0x81,0x20,0x78,0xae,0xc6,0x1d,0xe0,0x2d,0xb1,0xe7,0x64,0xbb,0xd4,0xc8,0x08,0x61,0x14,0x29,0x08,0xbc,0x1a,0xeb,0xfa,0x64,0x33,0x91,0x7d,0x91,0x41,0x65,0x8e,0x4c,0x0c,0xb2,0x79,0xc3,0x01,0x68,0xfc,0xd6,0xbb,0x50,0xcc,0x07
+.byte 0xa5,0xf6,0x2c,0x5e,0x10,0xd6,0xa3,0x62,0x18,0xec,0xa2,0xf2,0x6b,0xad,0xcd,0x02,0x01,0x75,0xbb,0x36,0x27,0x56,0x0f,0x55,0x03,0xe0,0x57,0xe1,0x72,0xeb,0x66,0x00,0x21,0xff,0x9a,0xbc,0xc1,0x1e,0x2c,0x93,0xe6,0x4d,0x93,0x28,0x10,0x7d,0x67,0x6c,0xf1,0xa4,0xe6,0x3a,0xa6,0x30,0xc8,0x50,0x1d,0x8b,0x6e,0x7b,0x76,0x98,0x14,0x4e
+.byte 0xed,0x84,0x67,0x2a,0x5f,0xac,0x0b,0x7b,0x47,0x40,0xb3,0x2d,0x7a,0xc1,0x23,0xdc,0x62,0xf8,0x8e,0x90,0x77,0xd4,0xf9,0x00,0x4b,0x67,0x04,0x72,0xf8,0xc9,0x2c,0x2d,0x0e,0x3c,0x3c,0xf3,0xfc,0xa8,0xe2,0x49,0xa4,0x00,0x82,0x98,0x72,0xa9,0xec,0xea,0xbd,0x3a,0x4e,0xd7,0x32,0xf1,0x11,0xf0,0x0d,0x9e,0xa2,0xe8,0xfe,0xcc,0x67,0xec
+.byte 0xfc,0xd6,0xfe,0x83,0x5e,0x7c,0x2b,0xb3,0x42,0xf4,0x2d,0x9a,0xbe,0x20,0xd1,0x81,0x62,0xe9,0x59,0x19,0x28,0xdf,0x97,0x10,0x54,0xf7,0xde,0x60,0x51,0x6a,0xce,0x32,0x03,0x75,0x5c,0x25,0x25,0x82,0x9c,0x07,0xf7,0x2d,0xa8,0x1b,0x9f,0xd3,0x32,0x46,0x25,0x1f,0xb1,0xc5,0xbb,0x28,0x14,0x3e,0xed,0xa8,0x83,0x20,0xf4,0x9c,0x75,0xf4
+.byte 0xe6,0xc4,0x2d,0x05,0x88,0x31,0xfd,0x48,0xca,0x6c,0x7f,0xab,0xb4,0x77,0x93,0x1d,0x87,0xc3,0x4e,0xb8,0xad,0xb4,0x3d,0x37,0x7a,0xd2,0x77,0xff,0xc2,0xcb,0x9c,0xc7,0xbf,0x02,0x02,0x70,0xc9,0x9f,0x77,0x8a,0x7d,0xa7,0x9a,0x10,0xd1,0x0e,0xb7,0xec,0x61,0xee,0x77,0x24,0xe9,0x3d,0xcd,0x12,0xca,0xee,0x50,0xb0,0x27,0x5d,0xe5,0xac
+.byte 0xa3,0x92,0xc7,0xd0,0x23,0x54,0xb1,0xe5,0x50,0xc3,0x15,0xd7,0x66,0x32,0x38,0x34,0xb1,0x59,0x1b,0xc3,0x59,0xe8,0xad,0x59,0x90,0x58,0x6e,0x02,0x40,0xb1,0x51,0x65,0x78,0x25,0x26,0x01,0xdd,0xcf,0x04,0xa2,0xfe,0xc3,0xbb,0x80,0x1c,0xb0,0x4e,0x9c,0x49,0x48,0xa3,0xe2,0xcc,0x81,0xc5,0xa8,0xd4,0xd5,0xe4,0xab,0x39,0xe7,0xe8,0x97
+.byte 0xc7,0x51,0xb4,0x5e,0x3f,0xe6,0xa7,0xcc,0x45,0x18,0xa2,0x6a,0xb3,0xa8,0x0b,0x7d,0xce,0x1a,0x97,0x4a,0x67,0xe1,0x3c,0x7c,0x4e,0xad,0x90,0xcf,0x2a,0x8f,0xb8,0xb6,0x96,0xaa,0x9a,0xc3,0x73,0xe6,0x71,0xdb,0x11,0x9b,0xd9,0xd9,0xfe,0xba,0x4a,0xf0,0x77,0xa4,0x15,0xb5,0xca,0xe1,0xb4,0x16,0x06,0x46,0xdf,0xc5,0x49,0x07,0x66,0xb3
+.byte 0xf5,0x30,0xe3,0xfb,0x44,0xac,0x80,0x3a,0x21,0xd9,0x5b,0x22,0x54,0x3a,0xae,0xbe,0xbd,0xf0,0x99,0x8d,0xb5,0x2a,0xf7,0xc9,0xf2,0xd3,0xfb,0x07,0x7c,0xd7,0x75,0x30,0x2a,0xcd,0x80,0xa8,0x2a,0x6a,0xb9,0x47,0xe2,0xa1,0xb0,0x76,0x6a,0x0f,0x9f,0x4a,0x56,0x3e,0xde,0xb3,0x89,0x12,0x25,0x63,0x1a,0x9d,0xea,0x64,0x08,0xc5,0x78,0xa7
+.byte 0x53,0xce,0xf8,0xb2,0xe5,0x97,0x3a,0xeb,0xd1,0x92,0xe1,0x4d,0xe0,0xf5,0x93,0x39,0x73,0xad,0x67,0xc9,0x0e,0x6b,0x16,0x4a,0x00,0xaa,0xb4,0xe6,0xa6,0xa5,0x67,0x95,0x90,0x04,0x5e,0x4d,0xc3,0x7f,0x6b,0xa1,0x50,0xb0,0x3b,0x72,0x0d,0xb3,0xec,0x9a,0x18,0x92,0x65,0x0c,0x2d,0x0f,0x94,0xd6,0x0f,0x95,0xba,0x4b,0xe6,0xc3,0x07,0x22
+.byte 0x0d,0x40,0xd4,0x0d,0x97,0x44,0xba,0x54,0x8c,0xf8,0x97,0x52,0x1f,0xa7,0xb2,0xe8,0x1b,0x0a,0xd5,0xde,0xff,0x1b,0x33,0x60,0x6a,0x28,0x68,0x36,0xb9,0x5a,0x3e,0x43,0x84,0x9a,0xb1,0x3d,0x3d,0xdb,0x1b,0xa2,0xc5,0x0e,0x2d,0xb5,0x5a,0xa5,0x36,0xe7,0xbf,0x7e,0xc3,0x76,0xad,0x1e,0xb5,0x49,0xc2,0xd5,0xa2,0x69,0x97,0x45,0x43,0x3e
+.byte 0xeb,0xcd,0xdf,0x4f,0xab,0xb3,0xe8,0x49,0xaa,0x9c,0x9c,0x58,0x1e,0xc8,0x1c,0x79,0xe9,0x16,0x1d,0xfe,0x54,0xac,0x55,0x18,0x10,0x73,0x97,0xdc,0xbe,0x45,0x63,0xfb,0x48,0x41,0x88,0xb4,0x0b,0x3a,0x1d,0x65,0x40,0x1b,0x10,0x66,0xeb,0xbe,0xed,0xc7,0x6c,0xd5,0x0c,0x19,0x85,0x23,0xb1,0x38,0xb3,0x4b,0xcd,0xc7,0xc5,0x06,0x18,0x40
+.byte 0xbd,0xef,0x9f,0x2e,0x3a,0x71,0x33,0x05,0x30,0x71,0xca,0xe9,0x7a,0x2c,0xe7,0x83,0x4e,0x3d,0x4b,0xc8,0xc7,0xcb,0x74,0x9c,0xa2,0xc7,0xbb,0x8c,0x44,0x0d,0xd8,0xb3,0x01,0x7c,0xdf,0x79,0xee,0x47,0xcb,0x91,0x6f,0xc3,0xfd,0x0f,0xfb,0xf8,0x6b,0x9b,0x00,0xaf,0xf6,0x69,0x82,0xa5,0x58,0x54,0x22,0x7f,0x4b,0xee,0xa7,0x03,0xdb,0xb6
+.byte 0x5f,0x12,0xe1,0x04,0x43,0x17,0xec,0xd4,0xdd,0x39,0x28,0xfa,0xa3,0x09,0x5e,0x14,0xaf,0x6b,0xfe,0x0c,0x65,0x01,0x13,0x75,0x3d,0xe7,0x6d,0xd9,0xda,0x1d,0x13,0xc1,0x56,0x40,0x50,0x95,0x65,0x8f,0xad,0x51,0x3f,0x13,0x05,0x2f,0x83,0xcd,0xca,0x8b,0x75,0xa2,0x39,0x61,0xde,0xd7,0x36,0xf9,0x1d,0x43,0x5b,0xc4,0x9a,0xc9,0xfc,0xa8
+.byte 0xf4,0x76,0x90,0x91,0xe8,0x52,0x5b,0x84,0xe7,0xc9,0x8e,0x7d,0x84,0xba,0xb1,0x32,0x12,0xce,0x06,0x9e,0x98,0x83,0x1f,0x7f,0x31,0xd7,0xf0,0x8a,0xa2,0xca,0xae,0xb3,0x50,0x51,0x93,0xfb,0x2f,0x43,0x0a,0xee,0x06,0x85,0xec,0xb8,0xf1,0x73,0xb1,0x65,0x37,0x05,0x8e,0x68,0xf7,0x7a,0xff,0xe7,0x17,0x08,0x5e,0x19,0x75,0x3d,0xf9,0x5e
+.byte 0xd5,0x25,0xf6,0x3b,0x99,0xb9,0x96,0x42,0x7a,0x37,0x8f,0x0d,0xde,0x22,0x83,0x89,0xf0,0x77,0x1f,0x22,0x42,0xc7,0xb5,0x70,0xcb,0xfd,0xf0,0xa9,0x87,0x8e,0x1f,0x01,0x9a,0x26,0xa6,0x8c,0x41,0xb9,0x12,0xd6,0xf2,0x5b,0xe5,0xfd,0xdc,0x74,0xbd,0xa1,0xc8,0xf7,0x3b,0x8c,0xe1,0x1d,0x42,0xb4,0x07,0x24,0x18,0x84,0x94,0x8a,0xce,0x00
+.byte 0xbd,0xd7,0xb0,0xfd,0x8f,0x0a,0xd3,0x75,0xa4,0xe8,0xfc,0x09,0xa9,0xa3,0x57,0x68,0x79,0x0e,0xef,0x37,0x46,0xd5,0x3b,0x8c,0x0d,0x67,0xbc,0x2c,0x5d,0x3e,0xf7,0xcc,0x9c,0x9e,0x81,0x62,0xc8,0xec,0x38,0x20,0x07,0x66,0xe4,0x83,0x15,0x13,0x3b,0x47,0x23,0xd9,0x46,0xaf,0x65,0xe1,0x40,0x2d,0x14,0x84,0x72,0xc1,0xbf,0xbe,0x81,0xc4
+.byte 0xcb,0x04,0x16,0x5e,0x2f,0x60,0x3a,0x8e,0x1a,0xd3,0xa2,0x00,0x25,0x6c,0xb7,0xdb,0x0d,0x20,0x99,0xb8,0x45,0x54,0xbf,0xc4,0x52,0x52,0x92,0x7d,0xcd,0xa1,0x9a,0x12,0x5e,0x27,0xe9,0xcf,0x79,0x9d,0xa8,0x6c,0xcd,0x37,0x20,0x08,0x09,0xc6,0x94,0x53,0x00,0x04,0xf5,0x3b,0xea,0x00,0x1b,0xc3,0x02,0xff,0xbc,0x18,0x1f,0xb7,0xf7,0x26
+.byte 0xe8,0x8b,0xc4,0x5f,0xf7,0xbe,0x9b,0xb3,0xba,0xae,0xbd,0x9c,0x3f,0x95,0xf7,0xcd,0x2b,0x40,0xf4,0x1c,0x6f,0xd7,0x52,0xe1,0xa7,0xdc,0x79,0xa4,0x88,0xff,0xfc,0xcf,0xfb,0xbb,0xe6,0xef,0xb6,0x31,0xac,0x24,0xa7,0x40,0xea,0x76,0xa2,0x34,0x6c,0xb1,0xfb,0x96,0x6b,0xfa,0xdd,0x60,0x70,0x73,0xb8,0xfd,0x66,0x3d,0xf9,0x63,0xc9,0x04
+.byte 0x70,0x20,0x35,0xca,0x04,0xb8,0xb3,0x4f,0x24,0x64,0x54,0xc2,0xd9,0x4d,0x8b,0xad,0x07,0xad,0xc5,0xb9,0x84,0xac,0x7c,0x65,0x4b,0x98,0x1d,0x09,0x23,0x95,0x5c,0x85,0x26,0xe5,0x8e,0xec,0xeb,0xc3,0xd5,0x15,0x9c,0x37,0x4e,0xf3,0x3c,0x97,0x92,0x75,0x99,0x48,0x48,0x52,0x4b,0x7b,0x93,0x54,0xd7,0x4f,0x7f,0xe5,0x51,0xdc,0x74,0x85
+.byte 0x9a,0xae,0xbd,0xf8,0xe6,0xe8,0x3f,0x1b,0xee,0x8b,0xf4,0xd8,0x5c,0x6c,0x46,0x6e,0x1d,0xaf,0x67,0x27,0x9a,0x39,0x4e,0x6b,0x99,0xcc,0xc0,0x66,0x54,0xbf,0x60,0xf6,0x24,0x64,0xfd,0x16,0xbf,0x56,0xb2,0x07,0x87,0x46,0xa6,0xef,0x40,0x67,0x78,0x2f,0x78,0x49,0x81,0x25,0xbd,0xa1,0xcf,0x78,0x68,0x25,0x8e,0x93,0x0a,0x4b,0xe1,0x92
+.byte 0x33,0x9c,0x13,0x70,0xd4,0xdf,0x74,0x34,0x8f,0x21,0xb9,0x51,0xd7,0x74,0xa9,0x02,0x6e,0xdd,0xb2,0xb4,0x6e,0x2a,0x95,0xdb,0xe4,0xaf,0x17,0xf5,0x9b,0xa5,0xc1,0x72,0x36,0x35,0x02,0x37,0x1c,0x38,0xaa,0x81,0x76,0xc6,0x1c,0xc3,0x2c,0xc5,0x45,0xaf,0x03,0xea,0xe6,0x14,0x51,0x44,0x84,0x9e,0x32,0xfe,0x4b,0x47,0xe9,0xb4,0x12,0x96
+.byte 0x13,0x6f,0x4c,0xed,0xe4,0xb0,0x79,0x7b,0xe5,0xc0,0x37,0x87,0x78,0x28,0x42,0xf7,0xd4,0xde,0xfc,0xd2,0x23,0x11,0x09,0xa5,0x11,0xc3,0xc4,0xf5,0xe0,0x2b,0x47,0x01,0x63,0xf2,0x85,0x1f,0x45,0x28,0xae,0xd3,0x29,0x04,0x1a,0x4b,0x83,0xab,0xf2,0x35,0x3a,0x40,0x2c,0x8d,0xb3,0xc7,0x47,0x0d,0xd1,0x3c,0xd0,0x1c,0x6b,0x5d,0x9b,0x4e
+.byte 0xdf,0x36,0x8d,0xc6,0x54,0x9e,0x61,0x51,0xf1,0xd2,0xa4,0x39,0xad,0x4a,0x14,0xa1,0x0b,0xd3,0xae,0x91,0x1a,0x29,0xeb,0xc5,0x75,0x88,0x13,0x1e,0x96,0xdd,0x6f,0x86,0x92,0xaa,0x37,0x16,0x95,0x86,0xbc,0xb1,0x35,0xbf,0x5f,0x75,0x40,0x46,0xe1,0x6f,0x2f,0x33,0x2d,0x13,0x35,0xef,0xca,0x09,0x04,0xe4,0x42,0xef,0x69,0x66,0xda,0xa6
+.byte 0x01,0xda,0x09,0xfd,0xb1,0x40,0x8d,0xaa,0xdd,0x08,0x0d,0xf5,0xf1,0xd6,0xc6,0x11,0x3b,0xbd,0xd3,0x04,0x70,0x76,0xaf,0xec,0x9b,0xcc,0x6a,0x1d,0xeb,0x95,0x4a,0x01,0x0a,0x03,0x62,0x00,0x32,0xb3,0xe0,0xd1,0x36,0xb6,0xeb,0xde,0x4b,0x5f,0x35,0x79,0x07,0x4a,0x0d,0xa1,0x8c,0xde,0x6b,0xd2,0xca,0x71,0x64,0x73,0xf7,0x9c,0x1d,0x95
+.byte 0x5c,0xdc,0xb9,0x4f,0x00,0x2e,0x86,0x3d,0x81,0x7b,0x05,0xa5,0x9e,0x03,0xa3,0x62,0xcf,0x22,0x78,0x0b,0xfe,0x09,0x3e,0x62,0x93,0x19,0x6e,0x47,0x7d,0x92,0x4a,0x0b,0xae,0xcb,0x37,0x4d,0x5a,0x3a,0x7a,0x68,0xde,0xb2,0x7e,0xd7,0xda,0x5c,0x45,0xd2,0x0f,0x1d,0x03,0xbc,0xed,0xd8,0xe5,0x2e,0x26,0x10,0x82,0x46,0x5a,0xe0,0x13,0x32
+.byte 0xf8,0xb9,0x18,0x8c,0xbd,0xb4,0xb3,0x8c,0x2f,0xb0,0x5d,0x0b,0xf3,0x8f,0x5a,0xda,0x8b,0xda,0x39,0xfe,0xe6,0x66,0x95,0x3f,0xfe,0x49,0x89,0xbf,0x43,0x36,0x77,0xc7,0x6d,0xea,0x92,0x5c,0x71,0xa6,0x29,0x50,0xb0,0x2f,0xed,0x89,0x9f,0x2c,0xd6,0x6b,0xfa,0xbe,0x62,0x9f,0x62,0xc7,0xe3,0x2e,0xd4,0xf2,0x2c,0x9c,0x98,0x37,0x38,0x5e
+.byte 0x81,0x6c,0x9e,0xcc,0xff,0x0f,0xfa,0xfa,0xe8,0xdd,0x2e,0x2d,0xb5,0x92,0x44,0x5e,0x2f,0xe1,0xd0,0x6c,0xc3,0xb9,0x11,0x95,0x70,0x4b,0x01,0xa0,0xc1,0x5e,0xe8,0x1d,0x40,0x16,0x9b,0x6e,0x29,0x1b,0x13,0xb9,0xda,0x39,0xbd,0x40,0x42,0xe2,0x06,0x35,0x57,0x2f,0xa8,0xf5,0xa7,0x00,0x60,0x07,0x26,0x21,0x6b,0xe6,0x23,0xa2,0x2a,0x70
+.byte 0xeb,0x85,0xcb,0xa9,0x73,0x31,0x62,0xf7,0xb0,0x90,0xd7,0x26,0xc1,0xd3,0xd7,0xcc,0x15,0x72,0x86,0xa6,0x0f,0x4a,0x24,0x14,0x5d,0xcd,0xbe,0xad,0x7d,0xf0,0x05,0x39,0x0c,0x10,0xbe,0x11,0x9a,0x36,0x9f,0x60,0x41,0xc6,0x7c,0xab,0x54,0x8a,0xac,0xc4,0xea,0xbd,0x43,0xeb,0x19,0x5a,0x8d,0x05,0xd1,0x83,0x58,0x92,0xb8,0xc6,0x75,0x56
+.byte 0x2c,0x58,0xb8,0x2d,0xe1,0x42,0xb4,0x0b,0xc9,0x97,0x79,0xb8,0x62,0xd0,0x15,0xd1,0x5d,0x0d,0x57,0x83,0xe4,0xba,0x73,0xa2,0x27,0xb8,0x56,0x64,0x28,0xaf,0xd2,0x58,0xe3,0xe6,0x12,0x01,0x6e,0x6a,0xfb,0x81,0x57,0xcd,0x32,0xc2,0x42,0x2a,0xe2,0x51,0x4a,0x4c,0xf8,0x69,0x0e,0xc0,0xe6,0x9f,0xf4,0x46,0x4b,0x60,0xcc,0x41,0x03,0xa4
+.byte 0x14,0xf0,0x15,0xb5,0xe5,0x39,0xfd,0x69,0xee,0xce,0x23,0x3a,0x50,0x66,0xdb,0xf4,0xe4,0x31,0x23,0xe9,0x06,0x93,0xdd,0x38,0xbc,0x2d,0xb9,0xf2,0x64,0x39,0x2f,0x1b,0xa9,0x71,0x0c,0x68,0xf7,0xb0,0x5b,0x74,0xe5,0x08,0xc6,0x5d,0xbe,0xb8,0xf7,0x40,0x0e,0xb4,0xe6,0x76,0x0c,0x14,0x8f,0x9d,0x25,0x95,0x6c,0x05,0x78,0x68,0x8a,0xa6
+.byte 0x80,0x24,0x8a,0x0b,0x6a,0xd7,0xfc,0xec,0x36,0xba,0x57,0xdd,0x49,0x82,0x3c,0x5f,0x9d,0xf4,0x57,0xac,0x16,0x99,0xed,0x73,0xa6,0xb0,0x2c,0x23,0xdb,0xf8,0x45,0x22,0xf4,0x82,0x16,0xc4,0x68,0x2f,0xe7,0x8c,0x85,0x6e,0x3c,0x43,0xdd,0x3d,0xea,0x90,0xeb,0xf4,0xef,0xf1,0x36,0x48,0x15,0x29,0x07,0x96,0x51,0xb5,0x78,0xa1,0xa3,0x59
+.byte 0x18,0x4d,0x11,0x5d,0x5e,0x67,0x69,0x28,0x29,0xcb,0xeb,0xbc,0x8f,0x17,0x12,0x57,0xaf,0xda,0xb5,0x86,0xef,0x59,0xdf,0xb1,0x6b,0x6a,0x33,0x66,0x67,0xd1,0x42,0xee,0xec,0x65,0xf2,0xeb,0x97,0x17,0x4e,0x01,0x3f,0x4d,0xb4,0x06,0x8e,0xf9,0xa8,0x79,0xb6,0xf1,0x67,0x8b,0xff,0x0b,0x5f,0x93,0x70,0x76,0x54,0xae,0x7b,0x0d,0x4a,0xbc
+.byte 0xf7,0xdc,0x11,0x64,0xb3,0x6a,0xd1,0x69,0x45,0x1b,0x57,0xfc,0xb5,0xfe,0x86,0xb2,0xd6,0xde,0x82,0x23,0x86,0x6b,0x21,0x78,0x8b,0x2e,0x96,0xf8,0x04,0x8b,0xba,0x15,0xae,0x33,0x91,0x27,0x88,0xe3,0xc1,0xe7,0xf8,0xc3,0xa6,0xb6,0x73,0xec,0x84,0x95,0x22,0x45,0x58,0xb1,0x50,0x99,0xde,0x8a,0x37,0x41,0x9f,0xb8,0x27,0xd6,0xd8,0xaa
+.byte 0x0f,0x0e,0xac,0xe4,0xd0,0x38,0xcf,0x2f,0x03,0x6f,0x3d,0x8a,0xd7,0x51,0xd6,0xf3,0x17,0x76,0xb5,0x0f,0xc5,0xf8,0xa7,0x0a,0x91,0xaa,0x8d,0xbc,0x15,0xd6,0x46,0xb9,0xdc,0x18,0x47,0x9c,0xd9,0x13,0xa5,0xb1,0xb5,0x45,0x2f,0x03,0x32,0x5c,0x8b,0xac,0x42,0x5b,0xd9,0x1a,0x41,0x1e,0x27,0xf9,0x92,0x72,0xc1,0xc7,0xc1,0x50,0x25,0x22
+.byte 0x7a,0x00,0x41,0x1f,0x2d,0x28,0xaf,0x41,0x96,0x8e,0x97,0x3b,0x36,0x80,0x16,0xe6,0x51,0x8f,0x07,0x13,0xd9,0x81,0x79,0x94,0x92,0xaa,0xb9,0xb6,0x39,0xf2,0x4d,0x24,0x6b,0x77,0x25,0x7e,0x47,0x6c,0xc7,0x62,0x3d,0x96,0x21,0xac,0x1a,0xf0,0x5f,0x5d,0x5a,0x7e,0x17,0xdd,0x47,0xd5,0x19,0x0a,0x85,0x3e,0xd5,0x6b,0x52,0x12,0xe2,0xbc
+.byte 0x43,0x79,0x28,0x1d,0x72,0xcc,0xa6,0x6c,0xea,0x9b,0xe9,0x04,0x34,0x2c,0x41,0x3a,0x64,0xe8,0xcb,0x12,0xfa,0xd5,0x45,0xad,0xe8,0x3e,0xa2,0x5c,0xb8,0x83,0x52,0xdb,0x0c,0x98,0x24,0x76,0xd2,0x00,0x62,0xff,0xac,0xd7,0x11,0xee,0xcf,0xfb,0xdd,0x65,0xd2,0x75,0xb0,0x25,0x4e,0x76,0x3f,0xa2,0x1a,0xae,0xee,0xc1,0x59,0x1b,0x0c,0x42
+.byte 0x70,0x42,0x06,0x00,0x64,0x31,0xe0,0xce,0x3a,0x91,0x5e,0x9d,0x56,0x83,0xab,0xa7,0x73,0xc2,0x15,0x29,0xba,0xf9,0x1d,0xc8,0x4b,0xc6,0x3a,0x9e,0xab,0xd7,0xfd,0x17,0x8d,0x80,0xf0,0xa1,0x8a,0x5a,0x7a,0x80,0xd8,0x1f,0xa9,0x5b,0xec,0x68,0x99,0x3a,0x66,0xcc,0x5a,0xdf,0x5f,0xe9,0xd5,0x6a,0xf2,0x2c,0x7e,0xf8,0xa7,0xdf,0x0c,0x59
+.byte 0xbd,0x85,0xf0,0xc9,0x91,0x44,0x9c,0x86,0x24,0x60,0xfb,0xe9,0xff,0x3c,0xa7,0xa7,0x6d,0x4b,0x17,0xb3,0x24,0x99,0x14,0xbc,0x64,0xd0,0x41,0xaa,0xcd,0x26,0xd3,0xa3,0x51,0xeb,0x25,0x1d,0xb2,0x7d,0xf1,0xf3,0xf3,0xf0,0x3a,0xe0,0xb5,0xa9,0x24,0xc3,0x78,0x4a,0xef,0x9b,0x34,0x93,0xf8,0x0c,0x71,0x10,0x5b,0xf0,0xe7,0x08,0x4d,0x5f
+.byte 0x74,0xbf,0x18,0x8b,0x48,0x8d,0xd7,0x23,0x81,0xed,0xa2,0x29,0xa9,0xdb,0x91,0xf6,0x61,0x7c,0xca,0x1e,0xe0,0xa7,0x21,0x9d,0xfc,0x04,0x3a,0x87,0xbb,0xf9,0xa4,0x3b,0xbb,0xc4,0x89,0xa1,0x7f,0xdc,0x83,0xfa,0x5e,0x0f,0xcf,0xdf,0xf6,0x41,0xd3,0xa3,0x76,0x76,0x44,0x3e,0x01,0xee,0xce,0xf6,0xc3,0xb9,0x49,0x43,0x6e,0xee,0x09,0x4c
+.byte 0x87,0xe6,0xa3,0xf5,0xa0,0x8d,0x99,0xb3,0x3b,0xd6,0xeb,0x27,0xf9,0x34,0x68,0xc8,0x04,0x80,0xb2,0x4d,0xb6,0xde,0x98,0x81,0xe0,0xec,0xc9,0x06,0xde,0x86,0xee,0xf0,0x87,0xb8,0x67,0x0e,0xce,0xf8,0xc5,0xb1,0xd2,0xe1,0xe3,0x53,0x1d,0xbe,0x6c,0xdd,0x5e,0x83,0x02,0xf5,0xc8,0xda,0xcf,0x3c,0xcb,0x88,0x2c,0xca,0x65,0x65,0x9e,0x71
+.byte 0x4e,0xf2,0x98,0x96,0xb2,0x54,0xb4,0x96,0xdc,0x84,0xb5,0x39,0x74,0x9b,0x61,0xcf,0x52,0xef,0xb3,0x0c,0x62,0xc9,0x92,0xe1,0xe5,0x6f,0x2f,0x0c,0x61,0x0d,0x6f,0xfd,0xd8,0x84,0x25,0xba,0x20,0x59,0x00,0xf5,0xa9,0xf1,0x77,0x6e,0x9a,0x3d,0x93,0x69,0xde,0xaf,0x9a,0xe6,0xe3,0xfd,0xb9,0xd3,0x04,0x82,0x18,0xa1,0x5b,0x9b,0xe0,0x29
+.byte 0x4c,0x64,0xf5,0x95,0x57,0x25,0xd3,0x04,0x8b,0x4a,0xe9,0x57,0x6f,0xd1,0x8c,0x40,0x73,0x49,0x32,0x93,0x3f,0x26,0xb4,0x6b,0xd3,0xd4,0x90,0xb7,0xe1,0xaf,0xa0,0x9a,0xc0,0x86,0xb7,0x5e,0xec,0x29,0xaa,0x03,0x4e,0x56,0xb5,0xcd,0x46,0x7d,0xe0,0x26,0x3d,0x5f,0xd3,0x55,0x86,0x68,0x4a,0xc5,0x42,0x5d,0x60,0x3a,0x39,0x6f,0x45,0xb9
+.byte 0x6a,0xea,0xf4,0x05,0xc8,0x24,0xf8,0xcd,0xe5,0xeb,0xca,0x3a,0xe7,0xb4,0x59,0x83,0x5a,0xa5,0x1d,0xe4,0x6a,0xaa,0x35,0x00,0x42,0x32,0xa5,0x6c,0x3e,0xc1,0xc2,0xc4,0x9d,0x2e,0x43,0x57,0x79,0x52,0xf6,0x1e,0x02,0xb8,0x9b,0xcd,0xf0,0x3d,0x57,0xa3,0x6f,0xf7,0x12,0x54,0x6c,0x63,0x0d,0xb2,0xba,0xff,0xa1,0xf6,0xf5,0xdf,0xa5,0xed
+.byte 0xda,0xdf,0x56,0x72,0x1e,0xc5,0x3f,0xad,0xd0,0xf9,0x38,0x94,0x51,0xe3,0xa4,0xb4,0xbf,0xd5,0x24,0x2a,0x90,0xfe,0xd4,0x34,0x6c,0xa8,0xc8,0x1c,0x9a,0xaf,0xac,0xff,0x5b,0x67,0x44,0x4c,0x4d,0xa7,0x59,0x2c,0x9f,0x67,0x07,0x25,0xe1,0x7f,0x4e,0x4a,0xaa,0x8f,0x5d,0xd1,0x26,0x0d,0x73,0x9b,0x69,0x5d,0xdf,0xb2,0xa5,0x89,0xbb,0x82
+.byte 0x0b,0x09,0xf3,0x11,0x76,0x5d,0x2d,0xad,0xc3,0xc1,0x15,0xbc,0xaf,0xa2,0xe6,0xd5,0xb0,0x6d,0x80,0xa6,0xda,0xfa,0x3b,0x9c,0xaf,0xff,0x98,0x40,0x83,0x3a,0xe1,0xb8,0x98,0x0e,0x97,0x00,0x89,0xfb,0x37,0xcb,0x81,0x36,0x34,0x33,0xbb,0x5c,0xd0,0x51,0x37,0xd6,0xb5,0x6c,0x3a,0x61,0x0a,0x27,0x23,0x96,0xa9,0x79,0x8d,0xf0,0xbe,0x31
+.byte 0xba,0xdc,0x89,0x4e,0x88,0x98,0xe4,0x10,0x15,0x8a,0xe1,0xae,0xe8,0x6d,0xa4,0x61,0x56,0x14,0x84,0x59,0x64,0xc2,0xaa,0xd8,0xfd,0x19,0xfc,0x17,0xf1,0xfc,0x6d,0x17,0xcb,0xea,0x7a,0x47,0x00,0x75,0x17,0xf3,0x62,0xfe,0x3a,0xbc,0x28,0x1a,0x0e,0x88,0x48,0x63,0x4a,0xcb,0x20,0x46,0xa4,0x75,0xf8,0xf1,0x7a,0xd6,0x92,0x7f,0x92,0xfa
+.byte 0x91,0x95,0x2f,0xbc,0x5b,0x42,0xf1,0x55,0xaf,0x91,0xa2,0x3b,0x29,0x5c,0xc8,0x5e,0x97,0x91,0xa2,0x2e,0xd2,0xa8,0x1c,0xf6,0x16,0xc5,0x15,0xf2,0x42,0xb3,0x41,0x59,0x52,0x8d,0x94,0x52,0xc4,0xc6,0x2c,0xdd,0x6f,0x01,0xea,0x62,0x42,0x83,0x7e,0x2e,0xf8,0xb8,0xc1,0xf3,0x71,0xd1,0x11,0x14,0x7a,0x3d,0xcd,0xec,0xe0,0x79,0x8b,0xbd
+.byte 0x28,0x12,0x60,0xf0,0x66,0xf1,0x1c,0x1c,0x19,0x07,0x8c,0x26,0xff,0xcc,0x72,0x9a,0xbd,0x12,0xe6,0x2b,0x2b,0xb1,0x32,0x04,0x98,0x92,0xd9,0x24,0x97,0x59,0x46,0xc6,0x11,0xe1,0x31,0x14,0x46,0x27,0x96,0xb1,0x06,0x81,0xd5,0xe8,0xff,0x45,0x3d,0x3c,0x04,0x9a,0xd8,0x0b,0x1f,0x41,0x03,0xba,0x1b,0x3e,0x4e,0xd5,0x7d,0x48,0x00,0x68
+.byte 0xb3,0xe8,0xe0,0xc8,0x3c,0xcf,0xdc,0xbe,0x29,0x90,0x64,0x51,0x18,0xdc,0xcd,0x87,0xcb,0xa8,0x3d,0xf8,0xb4,0x73,0x11,0xdc,0x7a,0xcb,0xa4,0x81,0x9e,0x3a,0x72,0xde,0x18,0x36,0x86,0x15,0x91,0xbc,0xeb,0x7f,0xe2,0xfb,0x6b,0xf1,0x5a,0x3d,0x05,0x50,0xeb,0xcf,0xd2,0xcc,0xf2,0x62,0xb1,0x32,0x46,0x14,0x95,0x4e,0xdf,0x73,0x64,0x61
+.byte 0x5f,0x3d,0xbf,0x52,0x3e,0xa7,0x55,0x01,0x9a,0xd8,0x01,0xef,0xf7,0x60,0x6f,0x83,0x43,0x6b,0x4c,0xa2,0xc8,0x04,0x34,0x70,0x70,0xa1,0x99,0xc9,0xa7,0x54,0x1e,0x87,0x99,0xb3,0xec,0xfe,0xe9,0x2d,0x39,0xef,0x6f,0x4d,0x8c,0xf2,0x4b,0xd2,0x12,0x5d,0xb6,0xa7,0x0b,0x04,0x3b,0x69,0xdd,0x9a,0x18,0x2d,0xd9,0x22,0x00,0x38,0x15,0x9a
+.byte 0x6e,0x6c,0x0c,0x84,0x32,0x32,0xb2,0xf9,0x61,0xef,0x74,0x35,0xec,0xcc,0xd7,0xbc,0x9d,0xe9,0xcd,0xe3,0xa0,0xa5,0x15,0x0a,0xfe,0x1f,0x37,0x35,0x2b,0x7c,0x42,0x50,0x81,0x67,0x52,0xb7,0xa7,0x9e,0x8f,0xda,0x64,0xc0,0xc0,0xc3,0x93,0xc7,0x9d,0x41,0xb8,0x4b,0x69,0x80,0x13,0x88,0x8a,0x07,0xf9,0x47,0xad,0xc9,0x4f,0x3d,0xc7,0xba
+.byte 0xd2,0xf2,0x7a,0xa0,0x38,0xbe,0xe1,0xfa,0x83,0xda,0x79,0x29,0x7f,0x4c,0xfa,0x0e,0x9b,0x59,0x1e,0x89,0x76,0x05,0x60,0x84,0x13,0x63,0x11,0x14,0x20,0xa9,0x2b,0xd0,0xc3,0x58,0xcc,0x73,0x3e,0x2c,0xa8,0xa7,0xa5,0xd0,0x2f,0x03,0xfc,0xa9,0x5d,0xdd,0xcd,0x40,0x91,0x90,0x1f,0xda,0x0a,0x73,0x58,0xd8,0x84,0x05,0x45,0x01,0x84,0x52
+.byte 0x8b,0x9b,0x17,0x98,0xa8,0xc4,0xc3,0xb5,0x94,0xd5,0x32,0x86,0xe9,0x10,0xe5,0xa5,0x99,0x8d,0x57,0x3e,0x32,0x25,0xfa,0xb4,0x5c,0x3a,0x5f,0xa6,0x2d,0x7d,0x4e,0xd3,0x7b,0xee,0x41,0x23,0x5e,0xc2,0xc9,0x91,0xf4,0x21,0xe0,0x4f,0x0d,0x87,0x30,0x53,0xf1,0x0e,0x63,0xe8,0x5b,0x3d,0xee,0x4a,0xc8,0x78,0x38,0xa2,0xa4,0xe8,0x72,0x41
+.byte 0xf1,0x37,0x30,0xe3,0x3d,0x93,0xc6,0x4b,0x10,0x0d,0xf6,0x20,0x15,0x0a,0x77,0x41,0xd5,0x7d,0xcb,0xf9,0xda,0x3b,0x17,0xa6,0xf1,0xe4,0x56,0xd4,0x65,0x7b,0x33,0xe4,0xef,0x34,0xfb,0x8c,0x9f,0x87,0x86,0xfc,0xce,0x90,0x60,0x77,0x57,0xc0,0xe4,0x37,0x2c,0xdf,0x41,0x95,0x85,0x89,0x4e,0x77,0x3f,0xa0,0xc7,0x55,0x4c,0x3f,0xa8,0x10
+.byte 0xd2,0x87,0x7e,0xd2,0x97,0xa1,0x6c,0xe7,0xec,0xaa,0xf6,0x93,0x13,0x2e,0x10,0xed,0x5b,0x7a,0xed,0x53,0xb4,0x55,0xaa,0xb4,0x67,0x78,0x07,0x5f,0xc2,0xd2,0xf1,0x7b,0x98,0xf0,0x82,0xf6,0x7c,0xb2,0xd4,0xa8,0xc2,0x53,0x39,0x21,0x7f,0xa0,0x76,0x37,0x1a,0x69,0xb3,0x49,0xd4,0xc3,0xd1,0xcb,0x31,0x76,0xec,0xaf,0x75,0x66,0x31,0x65
+.byte 0xeb,0x44,0x63,0xa0,0x13,0xf5,0x9e,0x67,0x40,0x41,0x76,0xce,0xd3,0xd6,0x91,0xb1,0x3a,0x07,0xff,0x38,0x1e,0xaf,0x55,0x57,0x55,0xd1,0x94,0x63,0xd3,0x81,0x16,0x59,0x68,0x01,0xe8,0x6d,0x7d,0x7a,0xa1,0x39,0xb9,0xa2,0xba,0x79,0x9d,0x69,0x00,0x13,0x59,0x2f,0x3d,0xef,0x10,0xe7,0x3c,0x02,0x7d,0xa3,0xa8,0xee,0x31,0x1a,0xad,0xa6
+.byte 0xdb,0x1b,0xe3,0x4a,0xdd,0x60,0xfb,0x4e,0xa6,0x49,0xbb,0xea,0x34,0x5d,0x21,0xac,0x83,0xa4,0xb5,0x23,0x8e,0x69,0xb3,0x25,0x14,0x8d,0xc2,0x89,0x8d,0xcf,0x38,0x46,0x18,0xb6,0x0c,0xce,0x45,0x22,0xeb,0xb5,0xb2,0xed,0xe5,0x0f,0x35,0x8f,0xdd,0xa1,0x15,0xd6,0x50,0x5b,0xe1,0x04,0xa7,0x32,0xc0,0xc9,0x03,0x56,0xc2,0x33,0xe8,0x16
+.byte 0x1c,0xd4,0x7a,0xfd,0x6b,0x4d,0x04,0xc0,0x9e,0xf8,0x32,0x9f,0x52,0x24,0xac,0xc5,0xb0,0xa1,0x63,0x77,0xc9,0x14,0xaf,0x46,0x60,0x67,0x52,0x81,0xbb,0x3f,0xf5,0x7f,0xad,0xef,0x7c,0x3a,0x71,0xc1,0x1e,0xea,0x4a,0xe0,0xd7,0xdd,0x31,0xf2,0x4b,0xdf,0x53,0x8a,0xc9,0x59,0x7a,0xb2,0x6f,0x7e,0xc0,0x00,0xa4,0x0d,0x09,0x9c,0xf7,0x22
+.byte 0x22,0xa9,0x37,0xde,0x3b,0xe1,0x74,0x85,0xcf,0xc5,0xb7,0x7b,0x0a,0xfd,0x6b,0xfa,0x98,0x49,0xa9,0x7f,0x52,0x23,0x0e,0xc0,0x4a,0xb3,0x81,0xa6,0x96,0x46,0x24,0xe7,0x01,0xd1,0xf2,0xac,0x31,0xb2,0x5e,0x61,0xe3,0xab,0xf8,0x1b,0x28,0xca,0xa2,0x78,0x3c,0xdf,0x8a,0xc1,0x17,0x46,0x9d,0xbd,0x69,0x31,0x41,0x8b,0xc1,0xc8,0xaa,0x68
+.byte 0xd5,0x35,0x65,0x49,0xfe,0xc6,0xa4,0x99,0xcc,0x62,0x4b,0x81,0x1c,0x21,0xa4,0xd8,0xe3,0xb3,0xe9,0x7c,0xf8,0x33,0x2f,0x21,0xa5,0x88,0xf2,0x8e,0x7d,0xee,0x00,0x00,0x62,0xcf,0x07,0x37,0x00,0x68,0x6c,0xb5,0x2d,0xc6,0x1b,0xcc,0x86,0x71,0xf0,0x4f,0x68,0xaf,0x0c,0x9a,0x25,0x69,0x71,0x2d,0xb5,0x87,0x90,0x02,0xd3,0xfc,0xbb,0x63
+.byte 0xa9,0xf1,0x13,0x4f,0xda,0x71,0x69,0x5c,0x0b,0xfd,0x3f,0x6c,0x2f,0x0b,0x4f,0x07,0x72,0x2d,0x2f,0x77,0xcb,0xa4,0xe4,0xbd,0x30,0xc7,0xe4,0xd9,0xf9,0x5d,0x2f,0x65,0xe4,0x41,0x5c,0xbc,0x03,0xa2,0x01,0xf9,0xfa,0x06,0x14,0x52,0x08,0x44,0x67,0x75,0x4e,0xbd,0x66,0x4a,0x26,0x3a,0x49,0xc4,0xba,0x02,0xb3,0x8e,0xa2,0x42,0xe7,0x92
+.byte 0x03,0x6d,0x61,0x10,0x73,0xd0,0x6f,0xe1,0x6e,0x67,0xff,0xb0,0x29,0x62,0x70,0x3c,0xeb,0x80,0xed,0x11,0x06,0xd6,0x18,0x60,0xe1,0x3d,0x21,0xa9,0xe9,0xd2,0x92,0x00,0x9e,0x13,0xf2,0x5d,0x38,0x71,0xdf,0xf3,0x5f,0x8a,0x90,0x45,0xf0,0x47,0x1f,0x0b,0x2d,0x12,0xf7,0x10,0x07,0x6a,0x52,0xe8,0xe2,0x26,0x9b,0x4b,0x7a,0x5f,0x97,0xb6
+.byte 0xf1,0x6d,0x47,0x3a,0x1e,0xc8,0x1d,0x78,0x5b,0x0a,0xb8,0x03,0xb1,0xe1,0xe7,0xc8,0xf0,0xe7,0x00,0xac,0xfc,0xd7,0x4a,0xde,0xaa,0xcd,0x0f,0xaf,0xf7,0x56,0x8e,0xed,0xfb,0xbe,0x7e,0xfe,0x62,0x75,0x7a,0x07,0x96,0xff,0xc3,0x21,0x35,0x71,0xb9,0x73,0x41,0xc2,0xb0,0xa8,0x6a,0x65,0x48,0xc4,0x50,0x31,0xe2,0xba,0xf4,0xe9,0x6c,0x03
+.byte 0x26,0x2c,0x77,0xfe,0x1a,0xd5,0x96,0xf6,0x6d,0xe4,0x14,0xfc,0xe2,0x1d,0x20,0x0c,0x14,0xa2,0x39,0x63,0xe5,0x16,0xef,0x6a,0xeb,0xe1,0x69,0xb8,0x67,0xa0,0x91,0xc1,0x8f,0xed,0xff,0xdf,0x26,0x1f,0xc3,0xb7,0x5d,0xe9,0xd2,0x72,0xe2,0x54,0x27,0x46,0x4f,0x33,0x25,0x59,0xaf,0xfa,0x87,0x4b,0x5a,0xda,0x7d,0x15,0x71,0x5d,0xb4,0x8d
+.byte 0x95,0xb6,0x09,0x5b,0x8b,0xeb,0xe6,0xba,0xc8,0x2f,0x8f,0x9e,0xa8,0xab,0x6a,0xa6,0x26,0xb6,0xf5,0x80,0xd0,0x7d,0xe7,0x4c,0x18,0x5a,0x72,0x8f,0x3e,0x90,0xe5,0xa1,0x16,0x33,0x66,0xc3,0x7b,0xf6,0xb6,0xdd,0x15,0x94,0x6d,0xca,0x8b,0xd7,0xa5,0x05,0xfb,0x5f,0x4e,0x94,0x6a,0xcc,0x54,0xed,0xeb,0xc0,0xb1,0xe1,0xc9,0x7f,0xc4,0x90
+.byte 0x2f,0x50,0x34,0x81,0x3c,0x83,0x47,0x3c,0x5a,0xb2,0x33,0x63,0xb6,0xa7,0xfb,0x59,0x70,0x87,0xea,0x7f,0x30,0x22,0xb4,0x54,0x48,0xfb,0x40,0xd2,0x7b,0xc9,0x49,0x80,0x18,0x27,0xc2,0x75,0x09,0x06,0x0a,0x83,0x1e,0x7a,0xf1,0x97,0xa1,0xc2,0x34,0x3f,0x6d,0xd6,0x2d,0xfe,0x5d,0x8b,0xfd,0x64,0x5d,0x6f,0x7f,0xbf,0x4e,0x01,0xb7,0x46
+.byte 0xfb,0xf7,0xd5,0x6f,0x5f,0x74,0xc8,0xca,0x9a,0x2e,0x74,0x08,0xe9,0x3d,0x8b,0xfd,0x97,0x38,0x72,0x67,0xbb,0x8a,0x34,0xee,0xf5,0x3a,0x2b,0x5e,0x64,0x64,0x06,0x7c,0x60,0x0f,0x7a,0x88,0x45,0x1b,0x69,0x90,0xb8,0xb0,0x4d,0x71,0x80,0x77,0xa8,0xaa,0x9f,0xd3,0xc6,0xfb,0xb8,0x12,0x1e,0x0c,0xf4,0x94,0x67,0x44,0xdc,0xb1,0x95,0x0e
+.byte 0x51,0xd1,0x06,0x69,0x92,0xbf,0xe6,0x67,0xe3,0xcd,0x0b,0x87,0x03,0x12,0x2e,0xa7,0x23,0x72,0x13,0xe9,0x89,0xcf,0x15,0x43,0xc0,0xa7,0x68,0xbd,0xce,0xec,0x28,0xb6,0x85,0x36,0xbe,0x52,0x5d,0x57,0xfa,0x7d,0x72,0xd1,0x4b,0x88,0xc9,0x64,0xbc,0x7a,0x18,0xe5,0x0e,0xab,0x19,0x81,0xee,0x11,0xbe,0xe0,0x68,0x44,0x81,0x49,0x3f,0xd8
+.byte 0x12,0xd1,0x8b,0xc1,0xe0,0x51,0xf7,0xc3,0x64,0xa7,0xc5,0x61,0x9b,0x32,0x6d,0xf0,0x6c,0xa6,0xaf,0xf9,0x4a,0xdf,0x94,0xaf,0xc8,0xf2,0x86,0xb1,0x4e,0x2e,0xa9,0xb4,0x35,0x82,0x15,0x8a,0x58,0xf3,0x03,0x2f,0x78,0x07,0x8f,0xb9,0x16,0x7c,0x42,0xfa,0x36,0xaa,0xa5,0x66,0x62,0x44,0xca,0xa6,0x55,0x95,0x27,0xdb,0x48,0xea,0x0a,0x1d
+.byte 0x5a,0xae,0x5c,0xad,0x99,0xfe,0x00,0xf1,0xb9,0x94,0xda,0x09,0x48,0x52,0x9d,0xfc,0xb4,0xb2,0x80,0x19,0x16,0xf8,0xcd,0x68,0x10,0xec,0x1c,0x16,0x3f,0xbb,0x42,0xb4,0x10,0xe3,0xdb,0xaa,0xe4,0x3f,0x2e,0x8e,0xb5,0xce,0xba,0x8f,0xf2,0xb5,0x76,0x98,0x15,0xa7,0x77,0x4b,0x1c,0x30,0xb7,0x6f,0xc9,0xa9,0xa4,0x64,0x59,0xab,0x3a,0x43
+.byte 0x74,0x33,0xab,0xe1,0x3e,0x5e,0x79,0x1c,0xa5,0xb4,0x87,0xe1,0xcb,0xea,0x0e,0x02,0x4b,0x01,0x84,0xbc,0xdc,0x75,0xf4,0x2c,0x2b,0x8d,0xc8,0x5f,0xb5,0xba,0x6b,0xb2,0x4a,0x7c,0xe7,0xaa,0x61,0xa5,0x0c,0xf8,0x02,0x73,0xec,0x11,0x13,0x6b,0x31,0x07,0xaa,0x79,0x78,0x86,0x01,0x77,0x5e,0xa3,0x09,0xd1,0xec,0xaf,0x7d,0xb7,0x65,0xa9
+.byte 0xd8,0x99,0xd2,0xd7,0x6d,0x32,0x97,0x0f,0x0e,0x51,0x0d,0x69,0x81,0x7a,0x94,0x48,0x31,0xe1,0xff,0x26,0x4d,0x30,0x49,0x93,0xfb,0x6e,0xdb,0xea,0xaf,0xcb,0xb4,0xa9,0xc9,0x9f,0xeb,0xca,0x52,0x36,0x26,0xac,0x47,0xda,0x02,0x3d,0xd0,0x93,0x8b,0x61,0x78,0x26,0x54,0x32,0xe8,0x14,0xac,0xf3,0xd2,0x46,0x04,0x12,0x89,0x9f,0xf6,0x11
+.byte 0xf5,0x64,0x83,0x66,0x00,0x50,0x55,0x05,0xb5,0xf6,0x58,0x9f,0xbf,0x4b,0x95,0xf1,0x7f,0x0b,0xb4,0xf7,0x63,0xea,0x6f,0xf7,0xb0,0x20,0x53,0xfe,0x95,0xbc,0xc4,0xe2,0xff,0x75,0xbd,0xab,0x73,0x68,0x44,0x18,0xf7,0x6b,0x04,0x46,0xde,0x6c,0x65,0xb2,0x22,0x4e,0x25,0x8e,0xba,0x7c,0x3a,0x6f,0x80,0x99,0xb4,0xe7,0xf9,0x97,0x68,0x40
+.byte 0xa9,0x96,0xfc,0x6b,0xcf,0x08,0x75,0xe4,0xda,0x6f,0xaf,0x71,0x4f,0x31,0x62,0x31,0x18,0xbf,0xb9,0xa0,0xcc,0x9e,0xa7,0xa2,0x27,0x2a,0xb8,0x6b,0xc0,0x93,0xf5,0x1f,0x41,0x25,0xa7,0x4d,0x9f,0xb4,0x12,0x5c,0x27,0x38,0x5d,0x80,0x88,0xa3,0xb8,0xb2,0xc3,0xd2,0xfb,0x1d,0xba,0x7b,0xac,0x51,0x0b,0x71,0x58,0x3f,0xe5,0xfa,0x36,0xb8
+.byte 0xc7,0x90,0x46,0xd0,0x5a,0x94,0xf0,0x7d,0x6e,0x6c,0x4c,0xb1,0xfa,0xdb,0x97,0x1e,0x19,0xf2,0x1f,0x4e,0x05,0x25,0x0e,0xbd,0x47,0x94,0x2a,0xd3,0x1a,0xbe,0x4a,0x04,0xaa,0x57,0x02,0xc9,0x42,0xc1,0x74,0xcd,0xe1,0x78,0x8b,0xff,0xc1,0xc6,0x17,0x4e,0x71,0xc4,0x2c,0x00,0x23,0x56,0x57,0x1f,0x47,0xd8,0x93,0x80,0xc1,0xc5,0x7b,0xd9
+.byte 0x25,0x30,0xac,0x72,0x37,0x00,0xd2,0xbc,0xc7,0x33,0x73,0xf9,0x14,0x86,0x7c,0xb0,0x28,0x14,0x5d,0xbf,0xbd,0x98,0x1c,0x00,0x05,0x19,0x2b,0x0a,0x55,0xad,0xb4,0x06,0x28,0x58,0x03,0xa1,0xe6,0x27,0xa3,0x32,0x5f,0x41,0xd5,0x6a,0x0b,0xbc,0x0f,0xaa,0xf5,0xc1,0xa7,0x09,0x2f,0x86,0xda,0x56,0xb0,0x04,0x49,0xd4,0x20,0xc6,0xa2,0x6c
+.byte 0x27,0x56,0x4e,0xcd,0x22,0x46,0xac,0x0f,0xd3,0x99,0x69,0x83,0xc4,0xae,0x9f,0x88,0xed,0x9c,0xba,0xfb,0xf3,0x66,0xc7,0x3d,0x65,0x55,0xd0,0xe3,0x04,0x03,0x6a,0x02,0x5c,0xbf,0x9f,0x23,0x34,0x79,0xe1,0xbe,0x7d,0xad,0xb4,0xc7,0x9e,0x4d,0x80,0x73,0x6d,0xe5,0x37,0x03,0xac,0xa3,0xf4,0x93,0xad,0x1e,0xf3,0xcd,0xb8,0xe2,0xeb,0x30
+.byte 0xc7,0x50,0xfe,0x0a,0x63,0x5e,0x0f,0xc9,0xd0,0x06,0x58,0xc1,0x6e,0x65,0x54,0x54,0x5d,0xaf,0xf1,0xe8,0x3e,0x95,0xe3,0x70,0x40,0x8e,0xb8,0x4d,0x76,0xda,0xa8,0xe8,0x9e,0x88,0xd8,0xaf,0x67,0x83,0x3b,0x77,0x65,0x58,0x00,0xbb,0xf7,0xe9,0x52,0xf0,0xba,0x0d,0x0a,0x59,0x28,0xe4,0xa7,0xfb,0x06,0xe5,0x34,0xbe,0xcf,0x10,0x7c,0x73
+.byte 0xa8,0xf3,0xa2,0x93,0x96,0x9e,0x4f,0x9b,0x3c,0xd1,0x9f,0x64,0x5b,0x8c,0xc1,0x89,0x66,0x67,0x13,0x52,0xb2,0xaa,0x6b,0x8e,0xea,0x97,0x27,0x20,0x2e,0x64,0xec,0xf0,0x72,0xc9,0x54,0x8a,0xed,0x78,0x3a,0xd7,0x4f,0xc2,0xba,0xc3,0xb8,0x64,0x7f,0xe4,0x5f,0x3d,0xf7,0xe5,0xd9,0xf1,0x8d,0xb1,0xd2,0xf6,0xcc,0x34,0xd8,0x7d,0x16,0xca
+.byte 0x47,0xaf,0x85,0xe5,0x4a,0x57,0xb9,0x5a,0x9e,0xff,0xb8,0x83,0xec,0x7c,0xb8,0x07,0xf5,0xd3,0x31,0x31,0x2b,0xf0,0x40,0x46,0xc3,0x63,0x27,0xe4,0xb0,0x3b,0x84,0x0d,0x50,0x05,0x80,0x0c,0xfa,0x8b,0x0e,0x33,0x6b,0x10,0xd4,0xf5,0x4f,0x8b,0x2d,0x9e,0xc5,0x01,0x92,0x52,0x62,0x1a,0x89,0x1e,0xca,0x48,0xc3,0xd6,0xfa,0xd2,0x94,0x7c
+.byte 0x77,0x6e,0xa7,0xeb,0xd7,0x4f,0xe8,0xc8,0xc2,0x71,0xb2,0x9e,0x86,0x30,0x18,0xfd,0x4c,0x56,0x4c,0xd0,0xa4,0x84,0x37,0x02,0x02,0x6a,0x8d,0x57,0x6b,0xc2,0x06,0xd1,0x8a,0xdb,0xa0,0xcc,0x31,0xf9,0xcf,0xbf,0xf2,0x29,0x7c,0x26,0xac,0x1f,0x03,0x20,0x26,0x76,0x03,0x6f,0xa5,0xb5,0x33,0xfb,0x02,0xe8,0xf6,0xe9,0x5e,0xb1,0x36,0x7c
+.byte 0x96,0x56,0xb1,0x98,0x2d,0x9c,0x38,0x9b,0xd4,0x56,0x28,0xcc,0xdb,0x08,0xd3,0x42,0x00,0x35,0x24,0xd9,0x74,0xa2,0x0d,0x55,0x21,0x06,0xb7,0xf9,0x6a,0xa0,0x81,0xc1,0x2d,0xb6,0x67,0x91,0x92,0x24,0x36,0xfd,0x2e,0xd8,0xc0,0xcb,0xc8,0x87,0x1a,0x41,0x11,0x70,0xbf,0xd2,0xe7,0x82,0x10,0x74,0xdf,0x65,0x46,0x19,0x6b,0xb4,0x89,0xeb
+.byte 0x9e,0xcf,0x79,0x35,0xba,0x25,0x75,0x32,0x64,0x6a,0xfb,0xaf,0xe5,0xed,0x85,0x98,0x34,0x75,0x31,0x40,0xbb,0xd8,0xe3,0xf5,0xa7,0xa2,0x9a,0x9e,0xcd,0xc4,0xf8,0xd8,0x15,0x6c,0x64,0x0c,0x6c,0x16,0x60,0xe9,0x40,0xf4,0x7a,0x14,0x37,0x7b,0x45,0x9b,0x0e,0x29,0x7a,0x1a,0x88,0x10,0xb9,0x2b,0xee,0x13,0xbd,0x8a,0xde,0x7a,0xe9,0x30
+.byte 0xe8,0x39,0x77,0x74,0xf5,0x2f,0xe3,0x10,0x19,0x89,0x28,0x21,0x3a,0x68,0x38,0xb4,0x4d,0x20,0x8d,0x7d,0xec,0x3f,0xf7,0x61,0xbf,0x53,0x32,0x3b,0xb8,0x6a,0xc9,0x58,0xeb,0xd4,0x33,0x0e,0xee,0xc7,0xb9,0x5e,0x3d,0x17,0x7e,0x36,0xa2,0xa6,0x94,0xb1,0x56,0xb6,0x8e,0x94,0x05,0x50,0x69,0x52,0x4f,0x31,0xe5,0x97,0x18,0xde,0x8f,0xb7
+.byte 0xff,0x2e,0x6f,0x1b,0x6a,0xda,0xfd,0xa1,0xd1,0x9a,0x4e,0x6a,0x1b,0x46,0x71,0x52,0x76,0x66,0xf9,0x70,0x8d,0x7d,0x97,0xb0,0xc3,0x8d,0xbc,0x35,0x26,0xe8,0x0b,0x80,0xc7,0x58,0x19,0x22,0x70,0x33,0x06,0xeb,0xcf,0x26,0x22,0xe0,0x97,0x91,0xbf,0xd6,0x94,0x05,0xe1,0x84,0xe2,0x31,0x66,0x57,0xc7,0x1e,0x36,0x30,0x50,0xaf,0x72,0xb3
+.byte 0x31,0xad,0x84,0xcc,0xb5,0x76,0x03,0xe1,0x56,0x97,0x87,0x36,0xf5,0xaa,0x97,0x99,0x38,0xa5,0xf5,0xb7,0x42,0x86,0x3b,0x2f,0x8a,0xb9,0x8e,0x6a,0x0b,0xe0,0xca,0xbc,0x4c,0x6c,0xc1,0x3f,0xbe,0x45,0xef,0xd2,0x57,0xcd,0x29,0xfb,0xfb,0xa5,0x79,0xf2,0xb1,0xbb,0x4b,0x55,0x26,0x2f,0x5c,0x84,0x5e,0x6a,0xc6,0xa9,0xd5,0x23,0xe4,0xd1
+.byte 0xe5,0xf0,0xbc,0x50,0x6a,0x2a,0xaf,0xa2,0x7c,0xcc,0x36,0x95,0xf9,0x5c,0x04,0x6d,0x04,0x31,0xbe,0x1d,0xb2,0x50,0x97,0x8f,0xdf,0x8a,0xed,0x4e,0x4e,0x0a,0x0b,0xfc,0xfc,0x1d,0xa9,0x6a,0x76,0x6a,0x33,0xd7,0x0a,0xcf,0xd5,0xdd,0xc6,0x62,0xe5,0x59,0x02,0xba,0x9c,0x43,0x32,0x8a,0x0e,0x47,0x91,0x00,0x07,0x47,0x93,0xc4,0xad,0x29
+.byte 0x33,0x57,0x15,0x45,0x44,0xb9,0xf3,0xc4,0xe6,0xd2,0xb9,0x3a,0x44,0x16,0x32,0x8d,0x57,0x78,0xac,0xf5,0xdb,0xa2,0x93,0x97,0x64,0x08,0x9b,0x66,0x4b,0xa0,0x64,0xab,0xa0,0xd6,0x0e,0x2c,0xa1,0x25,0x16,0x5c,0x6f,0x82,0xff,0x8e,0x89,0xfb,0xca,0x03,0xa6,0xf8,0xa1,0xf6,0x87,0x02,0x5c,0x90,0xcb,0x33,0xa0,0xc0,0x90,0xc2,0x1f,0xdd
+.byte 0x5c,0x50,0x93,0xf2,0x8b,0x87,0xa1,0x73,0xda,0x5f,0xa3,0x20,0xd4,0xe7,0x45,0xd7,0xea,0x4b,0x5d,0xd6,0x80,0xfc,0x2d,0xdc,0x45,0x6a,0xf6,0xaf,0xd4,0x7a,0x91,0x64,0x15,0x17,0xbf,0xc7,0x58,0x54,0x7c,0x08,0x42,0x4f,0x8d,0xab,0x9b,0xd0,0x1d,0x57,0x71,0x50,0xa7,0xe3,0xb4,0xf2,0x14,0x0c,0xd7,0x2f,0x7c,0x8b,0x17,0x61,0x98,0xfa
+.byte 0x19,0x34,0xb9,0x65,0xc5,0x5c,0xfe,0xa3,0x80,0x6f,0x99,0xec,0xfa,0x06,0x22,0x71,0xa9,0x10,0x2a,0xcf,0x12,0xb3,0x17,0xe5,0x59,0x3a,0xaa,0xcb,0x55,0x5f,0x45,0x9d,0xe9,0x29,0x56,0x34,0x11,0x62,0x6e,0x0a,0x95,0x12,0x5d,0xd4,0xa2,0x28,0x05,0xf1,0x0f,0x2d,0xa0,0x1e,0xe1,0x2b,0x42,0x6c,0xf0,0xe6,0x47,0xe0,0xb2,0xbd,0x89,0x20
+.byte 0x5e,0x24,0x05,0xec,0xf1,0x33,0xfc,0xa9,0x2f,0xef,0x3a,0x1f,0xfe,0x39,0xfe,0x01,0x09,0x0a,0x2a,0xe0,0x96,0x1e,0xde,0xad,0x96,0xaa,0x48,0xeb,0x8a,0xe6,0x54,0xbb,0x5d,0x7a,0xbe,0x4a,0xbf,0x96,0xf6,0x15,0x7a,0x70,0x6f,0xee,0xe7,0xf5,0x53,0xaf,0xe1,0xbb,0xaf,0x58,0x51,0xd4,0xa0,0xc6,0x44,0x03,0x47,0x33,0xce,0x58,0x62,0xd3
+.byte 0x93,0x21,0xa5,0xa5,0xb4,0xef,0x1d,0x93,0xcc,0x8c,0xf7,0x14,0xe3,0xec,0x40,0x52,0x47,0xe6,0xbc,0xe6,0x85,0x69,0xd0,0x15,0xad,0x24,0x21,0x4f,0x26,0x01,0x60,0x0f,0x0f,0xcb,0x7e,0x14,0x01,0xe1,0x90,0x11,0x06,0x17,0x38,0x2d,0xd8,0x26,0xe2,0x7c,0xd6,0xef,0xe0,0x59,0xf0,0x8c,0x2a,0xbd,0xba,0xe5,0x8b,0x07,0x56,0xd3,0x35,0xb3
+.byte 0x64,0x83,0x9e,0xb9,0xb9,0xeb,0x88,0x03,0xff,0x14,0xf3,0x8b,0x14,0xd3,0xa4,0xac,0x08,0xd9,0x75,0xf6,0x2c,0x9d,0x7f,0xc8,0x9d,0x11,0x3b,0xd1,0x71,0x14,0x4b,0x2a,0x6d,0x20,0x83,0x32,0x35,0x7e,0x1f,0x20,0xa6,0x69,0xbf,0xcf,0x22,0xd9,0xa2,0x57,0x4b,0x66,0xb1,0x9f,0x5a,0xa8,0xaa,0xb8,0x11,0x1d,0x45,0x28,0xac,0x86,0x09,0x37
+.byte 0xe9,0x1f,0xef,0xb4,0xe0,0x6f,0x75,0xad,0xe5,0xd8,0x25,0x06,0x19,0xb4,0xa8,0x07,0x78,0x79,0x43,0x63,0x40,0x26,0xbd,0x28,0x50,0x2d,0x29,0x26,0xf9,0xfc,0x5c,0x71,0x8f,0xfd,0x62,0x12,0x7c,0xd0,0x67,0xb3,0x65,0xef,0x31,0xc0,0x99,0xc1,0x54,0xfc,0x32,0x6e,0x25,0x56,0x77,0x6e,0xc1,0x6b,0x11,0x50,0x7c,0xa1,0x0b,0x97,0x8a,0xfe
+.byte 0x0f,0x5b,0x16,0x93,0x83,0xe0,0xd8,0xb7,0xbf,0xa8,0x90,0x6d,0xd6,0x8b,0x4b,0xd9,0x17,0xbb,0xe8,0xd9,0xbb,0x5f,0x39,0x4a,0x33,0x7c,0xb3,0x12,0x99,0x1e,0xfc,0xb2,0x05,0x91,0x67,0xdf,0x8d,0x0b,0x55,0xfb,0xd1,0x8d,0x0c,0x9b,0x80,0x81,0xee,0x8c,0x05,0xe2,0x16,0x30,0xad,0x1f,0x88,0x04,0x75,0xc1,0xe5,0xec,0x32,0xf8,0xa0,0x5b
+.byte 0x21,0xf6,0xd8,0x13,0x26,0xe4,0xa1,0x32,0xa8,0x93,0x91,0x5d,0x33,0x45,0x83,0x72,0x52,0x59,0x23,0x84,0xf6,0x7b,0xe2,0x90,0x20,0xc6,0x40,0x33,0xa9,0x94,0xcd,0xb9,0xab,0xe4,0x44,0x0b,0x06,0xbb,0x4c,0x2c,0x2a,0x5e,0x4d,0x57,0xb7,0xe0,0xb8,0x86,0x74,0xab,0xea,0x37,0x1c,0xa0,0xa6,0x21,0x33,0xc7,0xf5,0x24,0x7d,0x14,0xc8,0x8b
+.byte 0x9d,0x8f,0x31,0x23,0x29,0x9d,0x11,0x42,0x07,0xe8,0x2c,0xec,0x7d,0x70,0x8d,0xb5,0xa4,0xca,0x33,0x30,0x03,0x75,0x17,0xa1,0x10,0xe7,0x6b,0x87,0xf9,0x0b,0xef,0x43,0xef,0xf8,0x24,0xc2,0xf1,0x7a,0x1a,0x70,0x7e,0x2f,0xd4,0xeb,0x97,0x40,0xa6,0xe6,0x2d,0xc1,0xd8,0x3b,0xee,0xa4,0xda,0xd3,0x50,0x41,0x18,0xbf,0xad,0x66,0x02,0x85
+.byte 0x60,0x14,0xcf,0xce,0x50,0x88,0x5e,0xb6,0x73,0x11,0xbb,0x6a,0xca,0xb1,0x46,0x8e,0xbb,0x58,0x2c,0x63,0x61,0x20,0xec,0xc9,0x98,0x0c,0xdb,0x5c,0xe5,0x47,0xb5,0x89,0xe9,0x14,0xc8,0xbc,0x35,0xf2,0xa7,0x2d,0x84,0xcc,0x61,0xc8,0xb6,0x9d,0xeb,0xcb,0x8b,0x73,0x90,0x6d,0x06,0xc9,0x42,0xcf,0xd2,0x15,0x80,0x2d,0x39,0xeb,0x71,0x83
+.byte 0x27,0x0d,0x85,0xf9,0xa3,0xce,0xef,0x29,0x3b,0x10,0xb7,0xe9,0xd0,0x86,0x6e,0x88,0x1e,0x3b,0xdd,0xaf,0x52,0xde,0xa2,0xa4,0x13,0x3c,0x1f,0xcb,0x84,0x74,0x12,0x04,0x91,0x40,0xb8,0x1b,0x15,0xfd,0xdb,0xe8,0x74,0xcc,0x4d,0x41,0xb5,0x5a,0x92,0xd3,0x71,0xf7,0x57,0xa5,0xf7,0x18,0x5a,0x57,0x36,0xde,0x8f,0xb2,0x81,0x59,0xc8,0x5c
+.byte 0x22,0xcf,0xdc,0x7d,0xff,0x83,0xf2,0xad,0x8c,0x7b,0xd5,0x04,0xc4,0xb9,0x79,0x4a,0x12,0xa7,0xb1,0x7e,0x57,0xa5,0x6b,0x56,0x8a,0x11,0x96,0x57,0xde,0x35,0xdd,0xef,0x9b,0x03,0x41,0xde,0x61,0x5b,0x73,0x8c,0x6a,0x0c,0x6f,0xae,0x45,0x4b,0x56,0x4d,0xbe,0x8a,0x3f,0xdb,0x79,0x58,0x88,0xad,0xcb,0xfa,0x66,0x06,0x0e,0x74,0x21,0x1d
+.byte 0xe1,0x94,0xd7,0x06,0xea,0x60,0xe2,0x7d,0x70,0xcf,0xa9,0x4f,0xe6,0x9b,0xba,0x19,0x71,0x69,0x94,0x66,0x5a,0xb8,0x49,0x0c,0xd1,0x9a,0xc4,0x5f,0xa7,0xf4,0x9e,0x3d,0x9e,0xc2,0xd8,0x0e,0xd2,0x6d,0xc6,0xc8,0x99,0xc3,0x5e,0x3b,0xb9,0xd8,0x48,0xc0,0x38,0x48,0x95,0x89,0xff,0x7e,0x1d,0x80,0x53,0xac,0x7b,0xd7,0xfc,0x6f,0x5d,0x25
+.byte 0x2f,0xcf,0x15,0xdb,0x1a,0x64,0xc1,0x16,0x91,0x65,0x84,0x99,0x0a,0xc1,0xbf,0x4d,0x11,0xa5,0x55,0x55,0x35,0x93,0x6f,0x47,0xf1,0x75,0xb8,0xb6,0x11,0x9d,0x6e,0x3b,0xd1,0x11,0x20,0xa2,0xa2,0x5c,0x33,0x85,0x09,0xb8,0x13,0xc9,0xdd,0xf2,0xd4,0x32,0x37,0xf2,0xef,0x47,0xfa,0x25,0x1a,0xcc,0xdf,0xf4,0xe4,0x2c,0x2c,0x7f,0x23,0xb6
+.byte 0xa8,0xd4,0x6a,0xd4,0xb4,0x06,0x2e,0xb0,0xaa,0xa1,0x18,0x8a,0x5c,0xc6,0xb2,0x4c,0x71,0x92,0x4a,0xdc,0x81,0x20,0x51,0x8d,0x3f,0x71,0x7d,0x8c,0x25,0x79,0x07,0x14,0xa9,0x7a,0x8b,0xda,0x00,0xfc,0x51,0xdb,0xa0,0x50,0x2b,0x15,0x39,0xf6,0xad,0xdc,0x9e,0x22,0x93,0x2f,0x43,0xd8,0x5c,0xa2,0x5e,0xfa,0x70,0x8c,0xe0,0x6b,0x0e,0x93
+.byte 0x6c,0x89,0xfe,0x22,0x4c,0xec,0xb0,0x7e,0xc1,0x06,0x69,0xf7,0x2f,0x3e,0xe5,0xa4,0x45,0x53,0xab,0x9c,0xf5,0x40,0x05,0x53,0x64,0xc6,0xa7,0xf9,0xc4,0xd6,0x89,0xd9,0x47,0x72,0x8e,0x42,0xf9,0x64,0x12,0xeb,0xd9,0x25,0xdc,0x4c,0xc6,0xea,0x9c,0x4b,0x93,0xb4,0xa2,0xa6,0xae,0x95,0xc1,0x84,0x75,0xc9,0x22,0xe3,0x22,0x81,0x31,0xd1
+.byte 0xfd,0x2e,0x91,0x4a,0xc3,0x00,0xa6,0x57,0xbb,0x89,0x9f,0x2d,0xc3,0x2e,0x1f,0xa2,0x47,0xc4,0xa3,0xcd,0x2b,0xc2,0x29,0xaf,0x89,0xce,0x2e,0x87,0x8e,0xd8,0xfc,0xee,0xab,0x8a,0xbd,0x2f,0xee,0xcf,0x94,0xe0,0x74,0x70,0x86,0x00,0x42,0x11,0x8b,0x6c,0x81,0xd4,0x82,0xf2,0x29,0x3e,0x9c,0x68,0x71,0xaa,0x20,0x0a,0x51,0x5d,0x80,0x4c
+.byte 0xca,0x04,0x23,0x23,0xe2,0x69,0xb3,0xf5,0x65,0x98,0x19,0xee,0xa9,0x4d,0xd8,0xe0,0x06,0x4b,0x17,0xed,0xfa,0xf2,0xe3,0xd3,0x69,0x48,0xe4,0x4e,0xc0,0x5a,0x16,0x90,0xdb,0xb6,0x32,0x6e,0x6b,0xd7,0x7a,0xb6,0xd4,0x82,0xe4,0xcc,0x31,0x31,0x5c,0x18,0x84,0xef,0x75,0x9f,0xda,0xf6,0x62,0x2d,0x96,0x4d,0xa1,0x3c,0xb5,0x4a,0xbb,0xbf
+.byte 0x9d,0xb3,0x33,0x00,0xc1,0x73,0xc5,0xb2,0xeb,0x85,0x74,0xb0,0x68,0xed,0x16,0x66,0x71,0xc9,0x7e,0x6f,0x74,0xa6,0xe7,0xed,0xf0,0xfa,0xab,0x41,0xdd,0x10,0xf9,0xff,0x4c,0xb6,0x4f,0x15,0xe3,0x77,0x31,0x17,0x5c,0x5a,0xef,0xb2,0xa9,0x44,0xbe,0x97,0xa9,0x75,0x5a,0xb7,0xe0,0x16,0x17,0x37,0x1b,0x71,0x03,0xb9,0xaa,0x7b,0x7b,0x52
+.byte 0x46,0x58,0x6b,0x9b,0x87,0x27,0xa6,0x8a,0x0e,0x84,0x03,0x45,0x95,0x04,0xf1,0x7e,0xb6,0xf6,0x79,0xd5,0x66,0x6d,0x50,0x8c,0x5a,0x67,0xe0,0xdd,0x69,0xd8,0x92,0x75,0x15,0xcb,0xa5,0x05,0xfe,0x7a,0xc1,0xd6,0x11,0x57,0x10,0xa3,0xc3,0xb6,0xe9,0xe3,0x97,0xa5,0x46,0xc9,0xe9,0x9b,0x68,0xb6,0x55,0x0b,0xf2,0x17,0x9d,0x0e,0x7f,0xd9
+.byte 0x26,0x0c,0x01,0xff,0x95,0xe1,0x05,0xb7,0xbf,0x0d,0x77,0x12,0x96,0x03,0x71,0x01,0xc9,0x98,0xb4,0x44,0x94,0xc0,0xad,0x3d,0xfc,0x6f,0xe5,0x0c,0xa4,0x65,0xd7,0xe7,0x76,0x7c,0xb8,0xa0,0x0a,0xcd,0xe8,0x01,0x26,0x8e,0x94,0xec,0x94,0x65,0x86,0xee,0x4d,0x3b,0xc5,0xb5,0x2e,0x51,0xb7,0xa9,0x68,0xcd,0x14,0x90,0xd8,0x36,0xfb,0x52
+.byte 0x04,0x52,0xb4,0xca,0x9b,0xbf,0xc6,0x94,0x28,0xc5,0x7e,0x27,0x73,0xae,0x6d,0xba,0xe7,0x56,0xce,0x2e,0x00,0xeb,0x36,0x19,0xd7,0x4f,0x20,0x5e,0xfd,0x0f,0xd4,0x4c,0x02,0xaf,0xdb,0x74,0xef,0xf0,0x73,0x1e,0x2a,0x1a,0xe7,0x3a,0xe0,0xa5,0x89,0xcf,0x1a,0x66,0xbd,0x72,0x65,0xb4,0xf4,0x86,0x33,0x44,0xee,0x35,0xf6,0x09,0xbe,0x13
+.byte 0x96,0x84,0x04,0x95,0x3f,0x35,0xbb,0x01,0x2c,0x78,0x25,0xe8,0x1e,0x46,0xdb,0xd9,0xb1,0xe8,0xfb,0x2b,0xa8,0x59,0x72,0x5f,0x91,0xd3,0x7c,0x21,0x95,0xa9,0x50,0xa2,0x45,0x6f,0x48,0x0c,0xf2,0x51,0x10,0x3c,0xcd,0xea,0xeb,0x5d,0xc7,0xf9,0x0e,0xae,0x1a,0x02,0x05,0x15,0x12,0x10,0xc0,0x35,0x12,0x97,0xcd,0x5b,0x61,0x4f,0xd1,0xd3
+.byte 0x5b,0xec,0x2b,0xa0,0x20,0x03,0x2b,0xf3,0xe6,0x71,0x23,0xca,0x1d,0x48,0x64,0x3f,0x7e,0x52,0x8b,0xf9,0x96,0x33,0x31,0xbc,0xbd,0x73,0x2f,0xa6,0x80,0xb8,0x0b,0x3a,0xd7,0xf8,0x05,0xf0,0x06,0xc7,0xa5,0xce,0x6a,0x6a,0x62,0xae,0x06,0x93,0xa4,0x5f,0x0b,0x5d,0x4d,0xb8,0xa4,0xfa,0x2e,0xfc,0xb6,0x58,0x8c,0x2a,0x46,0xa4,0x55,0x1f
+.byte 0x9b,0x9b,0x13,0xdd,0x17,0x2a,0x3d,0x04,0x51,0xb6,0xbe,0x9c,0xca,0xf3,0x23,0xb6,0x7b,0x7a,0x92,0xb7,0x2f,0xf9,0x69,0x9a,0xee,0xb3,0xa1,0x60,0x56,0xcf,0x9d,0xab,0xfe,0x86,0x7a,0x41,0x94,0x15,0xbe,0xa3,0xa5,0x85,0x09,0xfb,0x7b,0x89,0xbd,0xc3,0x09,0x10,0xa6,0xfc,0x41,0x8e,0x57,0x27,0xdc,0x58,0xf4,0x01,0x7c,0x31,0x5e,0xca
+.byte 0xaf,0x31,0x2f,0x98,0x8b,0xbe,0x19,0x16,0xa1,0x81,0x7e,0xb3,0xa9,0xc5,0x15,0xd2,0xad,0x51,0xa1,0x73,0x56,0xd3,0x6a,0x15,0x35,0xe3,0xb1,0xdb,0x83,0x4c,0xe2,0x85,0x8c,0x03,0x12,0xc4,0x64,0x69,0xc0,0x23,0x16,0x7b,0x68,0x46,0x44,0x22,0x84,0xa6,0xb5,0xe4,0x90,0x91,0xc1,0xdd,0x25,0x7c,0x54,0x0e,0xce,0x5b,0x11,0xe4,0x50,0x1c
+.byte 0x3c,0x0d,0xc7,0xc1,0x0c,0x10,0x2d,0x8b,0xb7,0xde,0xe2,0x4f,0x7e,0x22,0x53,0xfc,0x07,0x55,0x19,0x14,0x3b,0x33,0xf5,0xf3,0xd8,0x7b,0x5e,0x40,0xa2,0x81,0x6d,0x40,0x0d,0x20,0x36,0x4b,0xa1,0x34,0x34,0xac,0x43,0x59,0xb5,0xb1,0x90,0x8b,0x48,0xcf,0x15,0x57,0x17,0x0e,0xd0,0xbf,0x28,0xcd,0xa4,0x77,0x4d,0xae,0x09,0x4c,0x67,0x51
+.byte 0x18,0xaa,0xb4,0xc9,0x35,0x41,0x0b,0x34,0x4d,0xb3,0xef,0x3f,0x46,0x97,0x6e,0xae,0x75,0xd7,0x6a,0x2b,0x22,0x9c,0xef,0x8e,0xaf,0x72,0xb0,0x14,0x90,0xbd,0x11,0x90,0xde,0x9a,0x02,0x8c,0x20,0xf5,0xc7,0x33,0x4d,0x94,0x88,0x9a,0x6c,0x18,0xb4,0xc0,0xa9,0x94,0x07,0x9a,0x4b,0x10,0x8f,0xe8,0x25,0xcd,0x9b,0xf5,0xfa,0x91,0x8a,0xc0
+.byte 0x93,0x61,0x1c,0x00,0xd1,0x34,0x9a,0x29,0xa3,0x35,0x38,0xe4,0xa7,0x9f,0xb6,0x88,0x0f,0xad,0x88,0x96,0xa0,0x73,0xe7,0x10,0xea,0x36,0xe8,0x88,0x6c,0x7f,0x03,0xbc,0xfe,0xe0,0xb2,0x4b,0x24,0x98,0xf6,0x73,0x6f,0xab,0x00,0x1e,0x26,0x83,0x0d,0x86,0x5b,0xa6,0x51,0x8f,0x5f,0xa9,0x8f,0xf4,0xa0,0x51,0xff,0xe0,0x64,0x09,0x95,0xfb
+.byte 0x56,0x53,0x18,0x61,0xea,0xc5,0x33,0xe8,0x6f,0x8a,0x07,0x97,0x1a,0x6c,0xb5,0xf8,0x73,0xae,0xe4,0x4e,0x6d,0xb2,0x83,0x20,0xfa,0xfd,0x79,0xa6,0x6c,0xaa,0x9b,0x7b,0x2c,0xfe,0x63,0x73,0xbc,0x87,0xd4,0x56,0xd1,0xb1,0xf1,0x0f,0x72,0x2c,0x2f,0xf0,0xf0,0x53,0xe2,0x6c,0x19,0x0d,0x9c,0xad,0xc8,0x0a,0x62,0x72,0xcb,0xc3,0x12,0x90
+.byte 0x4c,0x26,0xe3,0xa0,0x07,0x35,0xee,0xaf,0x81,0x35,0x07,0xa9,0x31,0xa0,0x59,0xc8,0x40,0xa5,0x45,0xb6,0x6d,0x3e,0xa2,0x5f,0x6a,0x79,0x74,0x65,0xa1,0xe3,0x1c,0xca,0xae,0xcc,0xa6,0xb6,0x0a,0x12,0x99,0x8e,0xc3,0xef,0x43,0xcf,0x42,0x92,0xa4,0x12,0xa3,0x8b,0x97,0x7d,0x6f,0xe0,0x35,0xed,0xac,0x69,0xae,0x8c,0xe1,0x32,0x11,0xa4
+.byte 0xe0,0x76,0x7f,0x75,0x92,0xda,0xfe,0x94,0x33,0xeb,0xe1,0xa4,0x3c,0x95,0x7c,0xc6,0xbc,0x3d,0xf2,0x39,0xa1,0x29,0x39,0x24,0x09,0xd4,0x52,0x68,0xfb,0x80,0xd0,0xd4,0x57,0xc6,0x4c,0xa5,0xa6,0x90,0xa6,0x61,0x15,0x2f,0xd3,0x35,0x36,0xf5,0x16,0xb3,0x65,0x0a,0xc4,0xcb,0x7f,0x73,0xe4,0xba,0x9a,0xd8,0x8b,0xc3,0x01,0xa0,0x08,0x57
+.byte 0x9e,0x26,0x54,0xbc,0x55,0xd1,0x5f,0xaa,0xb5,0x0d,0x42,0x75,0x04,0x76,0x8c,0xef,0xcf,0x64,0x3a,0x2e,0x4c,0x78,0xe5,0x37,0x8d,0x55,0xec,0xc1,0x7b,0xce,0x5f,0x5f,0x43,0x8b,0xdd,0x46,0x43,0xf5,0xa8,0x41,0xa6,0x82,0x1b,0x12,0xcb,0xcb,0x6d,0xa1,0x6c,0xb6,0x79,0x46,0x12,0x89,0x12,0x61,0xd6,0x4f,0xf9,0x43,0x2d,0x27,0xa9,0x61
+.byte 0x2e,0x2a,0x29,0x1b,0x6d,0xad,0x32,0x0b,0x6c,0x7c,0xf4,0xb8,0x98,0x91,0xbb,0x78,0xda,0x85,0xe8,0xfb,0x4e,0x11,0xc4,0x2a,0x07,0x54,0xa0,0x67,0x73,0x1b,0xa4,0x60,0x15,0x5c,0x83,0xbf,0x3f,0xd9,0x61,0x30,0x02,0xbb,0xa6,0x67,0xcd,0x0c,0xd1,0xb4,0x11,0x7e,0xca,0xf4,0x1e,0xed,0x83,0x34,0x66,0x54,0x23,0x39,0x36,0x8c,0xa0,0xc6
+.byte 0xef,0xad,0xa1,0x95,0x04,0x20,0x46,0x42,0xa8,0x99,0xd2,0x98,0xc6,0x0a,0x92,0x11,0xd1,0x84,0x4a,0xbf,0x25,0xe5,0xcf,0x78,0x98,0x81,0x80,0xaa,0x31,0x0a,0xa4,0xfb,0xef,0x35,0xfa,0xa4,0xac,0x5f,0x01,0x6b,0xb7,0x8e,0x86,0xc1,0x46,0x97,0x88,0xe2,0xaa,0x3b,0x1f,0xb5,0xf8,0xa9,0x90,0xf0,0x45,0x6d,0xdd,0xa3,0xdd,0xd8,0xef,0x36
+.byte 0x6f,0x87,0x55,0xf6,0x96,0xcd,0x88,0x43,0x03,0x97,0x82,0xea,0x5a,0x1c,0xa1,0x1a,0x7b,0x1b,0xa7,0xfc,0xaa,0x86,0xb4,0x71,0xde,0x0d,0x0a,0x52,0x98,0xd2,0x65,0x5d,0xa4,0xea,0x91,0xc9,0xe4,0x8b,0xd0,0xdb,0x85,0xe3,0x86,0x85,0x50,0xe1,0x41,0x1f,0x48,0x97,0x64,0xec,0x34,0xe4,0x54,0x42,0xf4,0x01,0xed,0x6f,0x4d,0xe3,0x1f,0x86
+.byte 0x14,0xbc,0x01,0x9c,0x7f,0x02,0x0c,0x65,0x94,0xd2,0x90,0x2c,0x1b,0xab,0x41,0x88,0xad,0x58,0xb5,0x71,0xd3,0xd6,0xe1,0x3f,0xf3,0x3c,0xb6,0xab,0x22,0x08,0x17,0xc7,0xf5,0x7e,0x34,0x56,0xae,0x1d,0x1e,0x7e,0xdb,0x24,0xe2,0xc2,0x38,0xf3,0x4d,0x46,0xe4,0x45,0xcb,0xb7,0x2f,0x0f,0x96,0x72,0x7e,0x31,0x89,0x17,0x9c,0xed,0x85,0xb9
+.byte 0xc8,0x8f,0x65,0x93,0xfb,0xb8,0x9e,0x41,0xa2,0xc1,0xcf,0xdb,0xe2,0x4c,0x26,0x4a,0xc7,0x2a,0x72,0xf6,0x28,0xbc,0x18,0x22,0xde,0xa1,0xfa,0x46,0xbe,0x95,0xc8,0xe2,0x19,0xbb,0x20,0x7b,0xd5,0xf8,0x34,0x15,0xaa,0xec,0xe2,0x9e,0xa9,0x3d,0xa1,0xd9,0xaa,0xc9,0x18,0x39,0x07,0x5c,0x81,0x61,0xe7,0x00,0xc5,0x57,0x3e,0xca,0x4d,0x89
+.byte 0x33,0x02,0xa6,0xc8,0x15,0xb7,0x24,0xdd,0x5c,0x55,0x56,0x11,0x5c,0x17,0x1b,0xda,0xc6,0xd5,0x46,0x6e,0x9f,0x70,0xe7,0x1e,0x41,0xee,0x91,0x1a,0xa0,0xad,0x35,0x64,0xdf,0x4a,0x18,0x03,0xa7,0xa8,0x88,0x8f,0x65,0xbc,0x76,0x34,0x08,0xab,0x50,0xc6,0xd3,0x08,0x7c,0xc1,0x4f,0x77,0xcd,0x1a,0xc6,0xed,0x35,0xea,0x4e,0x8a,0x6a,0x38
+.byte 0xa3,0xa3,0xd8,0xa9,0xa2,0x68,0xa7,0xd8,0xe0,0xc8,0x3f,0xfe,0xe7,0x73,0xc6,0x6b,0xd8,0x0c,0xd5,0x8f,0x81,0xe7,0x37,0x08,0x93,0x28,0x73,0xef,0xc4,0x91,0x52,0xa5,0x30,0xff,0x47,0x95,0x02,0x0d,0x8c,0xfd,0xc9,0x28,0x60,0xa9,0xad,0x30,0x00,0xcc,0x3a,0x00,0xbb,0x25,0xab,0xd0,0xf8,0x25,0x46,0x20,0xc0,0x67,0x9b,0xd6,0x10,0xa6
+.byte 0x84,0x6f,0x66,0x60,0x66,0x75,0xb6,0xfb,0x39,0x3a,0x9f,0x7d,0x32,0x7f,0x12,0x6f,0x8c,0xed,0x79,0x40,0x47,0xa3,0x27,0x17,0xa8,0xa4,0x02,0x93,0xb9,0x32,0x03,0x34,0x06,0x76,0x71,0x40,0x90,0x2b,0xe7,0xd0,0x3f,0x59,0xa7,0xfb,0x3a,0x7b,0xc8,0xa5,0x86,0x21,0x0d,0xf6,0xc6,0x49,0x07,0x56,0xe9,0xfc,0xac,0x61,0x30,0xa5,0x7e,0x90
+.byte 0x10,0xc8,0xdb,0x15,0x2b,0x75,0x27,0x77,0x51,0x42,0xcf,0x50,0xe8,0x6c,0x0b,0xb7,0x17,0x1a,0x89,0x7d,0xfe,0xd2,0x75,0xfa,0xb7,0xe5,0x68,0x10,0x1c,0x27,0x85,0x8b,0x52,0x7d,0x87,0x57,0x50,0x77,0x25,0x9d,0xcc,0x08,0x6a,0xad,0x63,0xf8,0x8e,0xe0,0x21,0x62,0x56,0x48,0x29,0xed,0x81,0x1d,0x6b,0x60,0x55,0x78,0x6a,0xce,0xd6,0x79
+.byte 0xe1,0x66,0x18,0x9f,0x71,0xf7,0x0c,0xec,0x35,0x53,0xef,0x39,0xfe,0x57,0x71,0xc0,0x49,0x4b,0x55,0xe8,0x3d,0x9b,0xe3,0x9a,0xbb,0xf8,0x61,0x31,0xa1,0x94,0x94,0x8a,0xb1,0xd2,0x0f,0x01,0xe0,0xd4,0x26,0xa0,0x59,0x70,0xd0,0x5e,0xb8,0x6f,0x63,0x7b,0x71,0x49,0xe1,0x98,0xfb,0xdb,0x22,0x26,0x18,0x16,0x31,0x08,0x90,0x32,0xd5,0x7a
+.byte 0xc0,0xd8,0xeb,0xae,0x93,0x3d,0x46,0xeb,0x0e,0xdd,0x08,0xa2,0xde,0x4e,0xc1,0x88,0x26,0xc2,0xf8,0xc6,0x5e,0x8a,0x9b,0x0d,0x9f,0x2b,0xcf,0x4e,0x13,0x43,0x4a,0x65,0xf6,0x47,0x1a,0x0a,0xae,0xf9,0x9f,0x7c,0xc5,0x18,0x65,0x09,0xcb,0x85,0x7d,0x33,0x36,0x43,0x19,0x99,0x20,0xa2,0x64,0xb2,0xf5,0x20,0xd2,0x74,0xc6,0x2c,0x29,0x46
+.byte 0xde,0xa7,0x4a,0x7f,0x3b,0x05,0x3e,0x11,0xb6,0xc1,0x98,0xfb,0xf5,0x9d,0x93,0x95,0x76,0x11,0x80,0x41,0x44,0xd3,0x2f,0xf4,0xfd,0x92,0x1e,0xd7,0xa7,0x5f,0x02,0x4a,0xbc,0xb7,0x96,0x33,0xc0,0x0d,0x2d,0x97,0xb8,0xd4,0x67,0x7a,0x4c,0x74,0x93,0xa7,0x8d,0x68,0x78,0xed,0xc8,0xc9,0x02,0x6e,0xae,0x10,0x97,0x7c,0x56,0x11,0x2a,0x29
+.byte 0x87,0x5c,0x21,0xec,0x75,0x9c,0x17,0x17,0x8d,0x45,0x08,0x31,0x36,0x64,0xc0,0xf7,0x95,0xb6,0x72,0xcf,0xac,0xd8,0x52,0x02,0x6f,0x3b,0x14,0x34,0x30,0xcc,0x39,0x7c,0xe4,0x1f,0x38,0x23,0xcf,0x1f,0xb7,0x7e,0x92,0x66,0xf7,0xda,0x9f,0x27,0xbb,0x83,0x45,0x71,0x67,0x63,0x6c,0x85,0x64,0x34,0xa8,0x93,0x5a,0x13,0x0c,0xff,0x8b,0x3a
+.byte 0x2a,0x10,0x1d,0xb6,0x43,0xef,0x57,0xf3,0xf0,0x29,0x2e,0x59,0x72,0x2e,0xc3,0xb6,0xd3,0xd0,0xdd,0x17,0x19,0x82,0x49,0x05,0xd4,0xfc,0xd6,0x2e,0x5d,0xd7,0x0c,0xb6,0x18,0xd5,0x08,0xbb,0xe5,0x3b,0x2e,0x85,0x62,0xc0,0x1e,0xa3,0xb8,0x92,0x21,0x06,0xfa,0xf1,0x2d,0xab,0x62,0x67,0x62,0xee,0x13,0x7f,0x07,0xb6,0x24,0x64,0x94,0x4f
+.byte 0x69,0xb9,0x7a,0xdc,0x23,0x5e,0x19,0x96,0xc5,0x4d,0xcb,0xee,0x2d,0x4a,0x7d,0x1d,0xd2,0x72,0x18,0x8f,0x43,0x8f,0x76,0xbf,0x30,0xd8,0xf1,0xfe,0x9c,0xe7,0x63,0x38,0xff,0x1a,0x3f,0x40,0xbd,0x73,0x66,0xf7,0xa9,0xd9,0x17,0x4a,0x8a,0x79,0x04,0x0e,0x20,0xe1,0x39,0x49,0xd9,0x30,0x9c,0x52,0xf9,0x14,0x8f,0xdc,0x9d,0x52,0xd5,0x34
+.byte 0xaa,0x58,0xfe,0x5d,0x68,0xcb,0xab,0x3b,0x3c,0x9e,0x25,0xde,0x6d,0xdd,0x58,0x0d,0x1b,0x99,0xa9,0xcc,0x26,0x4e,0xc0,0x3c,0x8b,0x1e,0xaa,0x52,0x3d,0x4d,0xb8,0x27,0xc1,0xd1,0xa2,0xaa,0x78,0xb9,0xee,0x5f,0x26,0x46,0x5f,0x41,0x0d,0xe1,0x70,0x7d,0xcd,0x3f,0x4a,0xca,0xb2,0xca,0x2f,0x36,0x1f,0x68,0xe6,0x66,0x8a,0xf6,0xe3,0x94
+.byte 0xe5,0xab,0x90,0xeb,0x2f,0xe8,0xb2,0x6c,0xa9,0x69,0xd2,0xe0,0x5f,0x4a,0x65,0xa8,0x6b,0xc1,0xfb,0x03,0x51,0x17,0x3b,0xf8,0xe0,0x67,0xc3,0x5a,0xe8,0x18,0xdf,0xc1,0xf8,0x7f,0x44,0x68,0x4a,0x01,0xbe,0xf8,0xa5,0x7a,0xb9,0x3b,0x0f,0x05,0x8e,0x4b,0x28,0x14,0x61,0x2f,0x2e,0xc7,0xf2,0x96,0xc7,0x60,0x99,0xc4,0xbf,0xe8,0x37,0x98
+.byte 0x00,0x34,0xf7,0x5a,0xd7,0x6f,0x90,0xc4,0x19,0xb5,0x07,0xd1,0x76,0x6e,0x65,0xcc,0xf6,0x51,0x88,0x5c,0x81,0x91,0xa8,0x4d,0xb7,0x33,0x53,0xb6,0x93,0x42,0x52,0x82,0xfa,0x2b,0xca,0xa0,0xbd,0xf3,0x09,0x2b,0x0f,0x09,0x02,0xdd,0x29,0x5f,0xa6,0x49,0x7b,0x97,0xe8,0x96,0xbf,0x6f,0x76,0xb7,0xa2,0x76,0x58,0xda,0x1d,0xb2,0xdb,0x6d
+.byte 0x9d,0x3b,0x32,0x6e,0x9c,0xea,0x45,0xfd,0x33,0xeb,0x41,0x91,0x91,0x52,0x2b,0x68,0xa3,0xf3,0xc6,0x92,0x43,0x13,0x49,0x8a,0x10,0xb1,0x2f,0x9a,0x0f,0xe1,0x94,0x21,0x18,0x76,0x87,0xaf,0x50,0xe4,0x71,0x5d,0x0a,0xba,0x75,0xaa,0x17,0xf5,0x37,0xf2,0x84,0x9b,0x29,0xdf,0x44,0x60,0xd0,0xac,0xcf,0x25,0x87,0x66,0x64,0x1f,0x0d,0xba
+.byte 0xb3,0xdb,0x14,0xb6,0x1f,0x00,0x70,0x98,0x83,0x1d,0x9e,0xbd,0xf9,0x17,0xf4,0x57,0xae,0xa8,0xae,0x7b,0xa7,0xde,0x1f,0x31,0xc6,0x29,0xb2,0xf7,0xef,0x36,0x31,0xe7,0x50,0x33,0x69,0x4e,0x8c,0xb5,0xe4,0xdd,0x74,0x87,0xc8,0xf5,0x22,0x1b,0x4b,0xec,0xc4,0xe1,0x5a,0x7d,0x5a,0xe8,0xb9,0x2f,0xf4,0xd1,0x83,0xa2,0xb7,0x97,0xe0,0x1e
+.byte 0xf7,0x3a,0x74,0xef,0x5f,0xb3,0x30,0xce,0xfa,0x23,0xd5,0x98,0x56,0x19,0x24,0xb5,0xc7,0x60,0x8b,0x03,0x8e,0xe7,0xdf,0x2c,0x36,0x4c,0x3b,0x3b,0x84,0x45,0x97,0x40,0x29,0x30,0x98,0xc3,0xc0,0xa2,0xf0,0xdf,0x69,0x47,0x95,0x26,0xdb,0x6c,0xcc,0xff,0x2d,0x32,0xaa,0xa7,0xb8,0x6b,0x24,0xec,0xff,0x94,0x4d,0x36,0xdd,0x7b,0x4d,0xc5
+.byte 0x8d,0xe2,0x3c,0x14,0x5a,0x37,0x75,0x1f,0xd6,0x98,0x7d,0xd3,0xdc,0xb0,0x24,0x69,0xe7,0x65,0x60,0x2a,0xe7,0x00,0x5b,0x68,0x99,0xa0,0x9e,0x10,0xf0,0x5c,0xa8,0x39,0x85,0x59,0xde,0xe4,0x46,0xf3,0xde,0xda,0xc0,0xb1,0xd2,0xf1,0xd2,0x05,0xd5,0xd4,0x2c,0x2e,0x7e,0x44,0x5c,0x52,0x80,0x85,0xbb,0x54,0x97,0xb6,0xad,0x6d,0x57,0x49
+.byte 0xed,0x67,0xaf,0x27,0xb4,0x5b,0xce,0x0f,0x3c,0x58,0xa2,0x24,0x22,0xa2,0xcb,0xfc,0x4e,0x8e,0xc2,0x3c,0x32,0xc6,0x07,0xc4,0xc6,0xc0,0x50,0xc3,0xe3,0x1b,0x96,0x76,0x62,0xf9,0xea,0x5e,0xdc,0xc5,0x96,0xe8,0xaa,0x20,0x26,0xac,0x44,0xfb,0xf2,0x16,0x72,0x72,0x4c,0x5c,0xee,0x51,0x07,0xb0,0x74,0xf6,0xde,0xd7,0x5d,0x73,0xf4,0xe9
+.byte 0x0d,0x29,0x06,0x5f,0xca,0xe2,0xbb,0xa4,0x3e,0xdc,0xf7,0x74,0x99,0x53,0x7a,0x52,0x60,0x46,0xaa,0xf0,0x34,0x97,0x0c,0x81,0x5b,0xd8,0x95,0x52,0x76,0x55,0xcb,0xc4,0x6d,0x50,0x26,0x3f,0x7e,0xc2,0x93,0x6e,0x14,0x0c,0xd7,0x49,0x5f,0x52,0x8f,0x34,0x49,0xb4,0xe7,0x12,0xfe,0xae,0xd1,0xfa,0xfc,0xc5,0x80,0x38,0x26,0x9c,0xf1,0x81
+.byte 0x01,0x58,0x15,0x99,0x29,0x8d,0x1b,0x2d,0x74,0xca,0xf1,0xf4,0xfa,0xcd,0xae,0xfa,0xa9,0x1d,0xbb,0xf1,0x55,0x2e,0x69,0x46,0x6e,0xe4,0x91,0xa3,0x48,0xb5,0xaa,0xb3,0x85,0xab,0x14,0xd2,0x84,0x8c,0xb1,0xb6,0x0c,0xa5,0x4a,0x90,0xed,0x6e,0xdf,0x1e,0x15,0x36,0x7b,0xa3,0x59,0xd6,0x8d,0x7d,0x7b,0x12,0x7c,0x9a,0x40,0x8a,0x28,0xde
+.byte 0xb5,0xbc,0xc4,0x52,0x96,0xfb,0x62,0x1f,0xc9,0xe0,0xc9,0x1d,0xc7,0xc4,0xcb,0x8a,0x96,0x21,0x42,0x7c,0x0a,0xdd,0x42,0x74,0xcf,0xc4,0x57,0x8f,0x28,0x0a,0x7c,0x4f,0x49,0x5a,0xc6,0x21,0xb2,0xd4,0xd0,0x61,0xa5,0x35,0xbd,0x4a,0x0c,0x16,0x68,0x1f,0xe3,0xff,0x3f,0x72,0xf0,0x1d,0x50,0x26,0x48,0x91,0x27,0x1b,0x2b,0x0d,0x8b,0xf2
+.byte 0xa0,0xc0,0xa0,0x5d,0xdb,0xcf,0x71,0x41,0x83,0x00,0xb9,0x3c,0xe0,0x4a,0x96,0x43,0xf8,0x64,0x0f,0x42,0xc5,0x75,0xec,0x26,0x62,0x99,0x13,0xeb,0xf9,0xa6,0x86,0xe4,0xc9,0xaf,0x3c,0x2c,0xc9,0x4f,0x89,0xf4,0xc0,0x46,0x99,0xb8,0xd1,0x9e,0x7b,0xb7,0x41,0x0a,0x5f,0x40,0x98,0x65,0x29,0xdd,0x60,0x6b,0x27,0xbf,0x66,0x08,0x32,0xc2
+.byte 0xcf,0xea,0x91,0x44,0x45,0x49,0x1c,0xb4,0x16,0x7f,0x11,0x1a,0x8c,0xb4,0x59,0x54,0xc6,0xcf,0x40,0xd2,0xe9,0xc1,0x54,0x9c,0xe2,0x6e,0xd5,0xfe,0xfb,0x4a,0xa3,0x98,0x63,0xef,0x86,0xe0,0x63,0x30,0x32,0x5a,0xbd,0xd4,0x7c,0xe8,0xbe,0xf1,0xed,0xa2,0x19,0x98,0xc8,0x34,0x65,0x4c,0xef,0x1a,0xb3,0xbc,0x87,0xbe,0x6b,0x75,0x2c,0xe5
+.byte 0x54,0xcc,0xe5,0x69,0xb2,0xc8,0xdb,0x57,0xf8,0xa7,0x82,0x07,0xf7,0x20,0x95,0x7f,0x6d,0x7b,0x33,0x66,0x67,0xa1,0x38,0x0e,0x9c,0x3b,0x22,0xab,0xc1,0xd3,0xed,0x87,0x32,0xfb,0x4a,0x5d,0xad,0x3a,0xe1,0x90,0xa6,0xe3,0x4d,0x6b,0x00,0xe4,0x5c,0x66,0x59,0x90,0x63,0x24,0x5b,0xe1,0x3b,0x69,0xb6,0xc9,0x05,0x83,0x3a,0x7b,0xf4,0xa5
+.byte 0xc8,0x47,0xf9,0x8e,0xab,0x92,0xbd,0xd3,0x41,0xc7,0x61,0xf4,0xce,0x30,0xdb,0xae,0x27,0x69,0x0f,0xcc,0x69,0x50,0xe8,0x18,0xf2,0x39,0x04,0x5a,0x29,0x12,0x61,0x46,0x5c,0x1b,0x2e,0x15,0x9c,0xfa,0x73,0x50,0xe3,0x51,0xda,0x4d,0x88,0x25,0xb2,0xff,0x55,0x27,0xce,0x86,0xca,0xe6,0x2a,0xb8,0x0c,0xa7,0xd0,0x06,0xbf,0x70,0xb5,0x6b
+.byte 0x80,0x44,0x65,0x5d,0x23,0xfa,0x0d,0x74,0x5c,0xfc,0xc7,0x86,0x5e,0x23,0x8a,0xf1,0xff,0x80,0xf0,0x19,0xaa,0x98,0xae,0x56,0xcf,0x12,0x74,0x6c,0x70,0xb2,0x39,0xbe,0x66,0x71,0xee,0xe3,0x43,0x3b,0xfa,0x79,0xa9,0x7e,0x69,0x6a,0x19,0x42,0xd5,0x0e,0x1e,0x92,0xfe,0x8a,0x0f,0xca,0x74,0xf2,0x68,0x71,0xf5,0xcb,0x05,0x94,0xc1,0x06
+.byte 0x1b,0xae,0x55,0xe9,0x16,0x03,0xa9,0x97,0xad,0x49,0xaf,0x88,0x8c,0x26,0x33,0x4d,0x46,0x75,0xb3,0x9c,0xee,0x70,0xe1,0x57,0x43,0xeb,0x59,0xff,0x77,0x89,0x8a,0x77,0x3f,0x7e,0xe6,0xbe,0xa2,0x05,0xb1,0xe3,0x41,0x5e,0xc7,0xd4,0x14,0xda,0xc0,0x84,0xd0,0x05,0x50,0xdd,0x62,0xdb,0x4c,0x3b,0x16,0xb0,0xe0,0xf5,0x2b,0xf1,0x83,0xea
+.byte 0x7b,0x89,0xbb,0xde,0x57,0xdb,0xc0,0xb9,0x7d,0xdf,0x53,0x0f,0x6c,0xc5,0x5a,0x0b,0x36,0xeb,0xa3,0xc3,0xe6,0xc5,0x80,0x98,0xf3,0x87,0x29,0x97,0xc9,0x2e,0xd6,0x3b,0x43,0x2a,0x36,0x3b,0xba,0x43,0x85,0xf5,0x0d,0x18,0x2e,0x78,0x43,0xae,0xa4,0x24,0x6d,0xdc,0xab,0x05,0x94,0x09,0x94,0x27,0x17,0xef,0xbc,0x7e,0x52,0xa4,0x80,0xda
+.byte 0x28,0xf5,0xc3,0x20,0x99,0xbb,0x5d,0xb6,0x7e,0x0e,0x59,0x3b,0x5e,0x1d,0x1b,0x4f,0xd1,0x91,0xe4,0xe4,0xc7,0x35,0xc7,0x2e,0xc1,0xba,0x60,0x05,0xa4,0xd5,0xca,0x5f,0x09,0xbf,0x79,0x06,0xcb,0xa7,0x32,0x7c,0xf4,0xdc,0xa8,0xb3,0x8b,0x26,0x59,0x6d,0xcb,0x74,0x37,0x56,0x51,0x96,0x0b,0x44,0xf1,0x95,0x16,0xe3,0x9b,0x9b,0x3b,0xb3
+.byte 0xea,0x6a,0x1b,0x76,0x99,0x69,0xd6,0x5b,0x10,0x5a,0x91,0x23,0xb5,0xc3,0xf9,0x6a,0xba,0xc4,0xe6,0x18,0x28,0x50,0x9d,0x09,0x14,0xbe,0xed,0x73,0xd2,0x51,0xff,0xf8,0x14,0x2b,0x8b,0xdd,0x2a,0x1a,0x8e,0x48,0xae,0xd8,0xdf,0xb9,0x5b,0xcb,0x8f,0xc2,0x8c,0xd6,0xb3,0xfb,0x40,0x2f,0xb0,0x6c,0x9a,0xea,0xd0,0x14,0x8c,0xc5,0xc7,0xc7
+.byte 0xf8,0xf5,0x4f,0xe2,0xd7,0x41,0xcd,0xb6,0x34,0x3e,0x81,0x19,0x09,0xa2,0x51,0xb4,0x60,0xfb,0xf2,0x6c,0xe6,0xae,0x68,0x47,0xb9,0x93,0x7b,0xc9,0xe7,0x00,0xc4,0xa7,0xf2,0xef,0x8b,0xd8,0xfc,0x9f,0xe5,0x6d,0x48,0xe2,0x6c,0x32,0x73,0x5c,0x30,0x7c,0x12,0x13,0xca,0xc3,0x31,0xc3,0xa2,0xb4,0xf7,0x23,0xc4,0xd0,0x47,0x39,0x93,0xc8
+.byte 0xa0,0x7b,0xb4,0x09,0x3f,0xe8,0x15,0x15,0x9c,0xa7,0xe6,0xa8,0xbe,0xba,0x60,0xf9,0x28,0x88,0x66,0x7b,0x62,0x32,0x17,0x18,0x68,0x87,0x53,0xf5,0xbc,0xf5,0x77,0x17,0xa1,0x3f,0x62,0xd1,0x10,0x0a,0x54,0x96,0x9c,0x31,0xc3,0xb7,0x1d,0xaf,0xc7,0xb3,0x27,0x9e,0x46,0xfe,0x7e,0x9b,0x88,0xf2,0x9e,0x6e,0x19,0x0f,0xb1,0x88,0xe4,0x08
+.byte 0x76,0x7c,0x77,0x46,0x09,0xa7,0x9e,0xf4,0xd9,0xbf,0x67,0xe8,0x9d,0x6a,0x75,0xa7,0xf5,0xee,0x29,0xba,0x84,0xa0,0x44,0x46,0x35,0x4c,0x22,0xef,0xb3,0xea,0xb0,0xf2,0xd6,0x78,0x20,0x97,0x28,0x5c,0x7e,0x90,0x06,0x80,0x19,0x63,0xa4,0x8a,0xef,0x0a,0xea,0x88,0xa9,0xa2,0xae,0x23,0x2e,0x40,0xce,0xc5,0xc2,0xbf,0xfe,0x5a,0x8f,0x14
+.byte 0xb8,0x66,0x1a,0x2d,0xdb,0x43,0x39,0xbd,0xe7,0x7b,0xbc,0x41,0x58,0x74,0x56,0xd1,0xe7,0xd0,0xba,0x24,0xd2,0x41,0xbf,0xd0,0x4e,0x97,0x38,0x8f,0x6b,0x6f,0xe2,0x7d,0x6d,0x32,0x94,0x43,0xa7,0x66,0xf7,0x90,0x21,0xe0,0xdd,0x19,0x48,0x72,0xc1,0xa5,0xbc,0x9c,0xe2,0xdd,0x2c,0x6e,0x50,0x45,0x2c,0xa0,0x95,0xcb,0x1d,0x2c,0x1d,0xa6
+.byte 0xbe,0x9c,0xd4,0x6c,0x07,0x2e,0x5e,0xc8,0xc1,0x05,0x61,0x7d,0x44,0x28,0xe6,0xad,0xf0,0x9d,0x2d,0x3d,0xce,0x90,0x7d,0x79,0x2e,0xf3,0x08,0xbe,0x7a,0xa9,0x58,0x04,0xa7,0x39,0x05,0xdd,0xb4,0x87,0x6c,0x7b,0xd5,0xb3,0x2d,0x6b,0x43,0xf4,0x37,0xd9,0x6f,0x5c,0xa2,0x23,0x92,0x53,0xb9,0xd7,0x1b,0x2d,0x5d,0xcd,0x6d,0x3f,0xef,0xc8
+.byte 0x66,0x91,0x10,0x1b,0xc5,0x24,0x50,0x87,0x70,0x93,0x03,0x3f,0x7b,0x40,0xc8,0x0c,0x9b,0xec,0x3d,0x82,0x27,0x96,0x2a,0xbe,0xca,0xaf,0x1b,0xbf,0xef,0x14,0x0c,0xdc,0xa6,0xc7,0x48,0x18,0xce,0x8e,0x43,0x58,0x97,0xb3,0x5e,0xd6,0xc9,0x70,0x65,0xd0,0x0e,0x17,0xac,0xa0,0x6b,0xc9,0x55,0x30,0x12,0x7c,0xbe,0xe5,0x46,0xfc,0xd8,0x3f
+.byte 0x0e,0xd7,0x96,0x16,0x32,0x8e,0xb7,0x2d,0x07,0xd1,0x26,0x98,0x70,0x4c,0xb1,0x6f,0x92,0x32,0x75,0x4f,0x57,0x6b,0x78,0xe0,0xc5,0x9b,0xf0,0x08,0x59,0x0b,0xfa,0x2d,0x79,0xbe,0xde,0x44,0x3d,0x65,0x77,0x27,0x3b,0xd9,0xea,0x55,0x79,0x22,0xe8,0xf7,0x62,0xb1,0xe3,0x32,0x4e,0x03,0x17,0x65,0xd3,0x5d,0xee,0xa0,0x9b,0xc2,0xbd,0x9f
+.byte 0xcd,0xdc,0xde,0xd7,0x6c,0x95,0x7a,0xf1,0x09,0x4c,0x14,0xb9,0x37,0x1d,0xd0,0xdd,0x4b,0x2e,0x93,0x0b,0xfa,0x08,0x40,0x01,0x36,0xdf,0x89,0x46,0xa6,0xbb,0x19,0xd9,0x4f,0xf9,0xe1,0x7b,0x03,0xc9,0xef,0x01,0x25,0xe9,0x6d,0x95,0x84,0x7f,0xf8,0x8e,0x02,0xfd,0x6f,0x30,0xed,0x1b,0x98,0xd0,0xb3,0xdd,0x92,0x65,0x46,0x49,0x61,0xde
+.byte 0x76,0xf5,0x4b,0x29,0x03,0x6f,0x79,0xee,0xbe,0x7a,0x07,0x6e,0xa8,0x29,0xb8,0x03,0xb4,0x6c,0x50,0x1f,0x4a,0xa2,0xaf,0xbd,0xde,0x18,0x72,0x90,0xa2,0x12,0xa9,0x59,0x7b,0xf6,0x96,0x2d,0xda,0x3d,0x90,0xba,0x7c,0x79,0x3e,0x6e,0xef,0x94,0x37,0xe2,0xef,0x6b,0x2a,0x74,0x6b,0x52,0xa0,0xc2,0x1e,0xa1,0x24,0x59,0x84,0xeb,0xdc,0xd0
+.byte 0x34,0x60,0xa8,0x81,0xaf,0xdd,0x57,0xc2,0xa6,0x02,0x7f,0xcf,0x9e,0x64,0x28,0x18,0x7c,0x95,0x98,0x90,0x7a,0x76,0x3f,0x78,0x16,0x2c,0xe0,0xa7,0xdf,0x0d,0x4d,0x5e,0xcc,0x0d,0x73,0x12,0x26,0xd7,0xe9,0x32,0x3e,0xa1,0xa9,0xde,0x29,0xb2,0x3b,0x6f,0x3b,0x6e,0x12,0x0c,0x10,0x34,0x86,0xf2,0xa0,0xd4,0x9c,0xf6,0x14,0x5a,0x41,0x06
+.byte 0x31,0xb1,0xe4,0x31,0x52,0xf4,0xcb,0xe3,0x39,0xcd,0x0b,0xc2,0xca,0x90,0xba,0xb3,0x21,0xbf,0x94,0x13,0x75,0x3b,0x0e,0x0a,0xc0,0x05,0x35,0xe6,0x28,0x74,0x63,0xc5,0x34,0x44,0xd8,0x9a,0x0e,0xec,0xb3,0x1b,0x30,0x58,0xfc,0xa0,0xc4,0xd1,0x26,0x50,0x6b,0x22,0x88,0xfc,0xad,0xa9,0xb4,0x3e,0x36,0xb6,0xb1,0x6d,0x62,0x7e,0x60,0x8f
+.byte 0xf5,0x17,0x65,0x1c,0xf6,0x51,0x4d,0x89,0x4a,0x7e,0x5d,0x23,0x3b,0x83,0x1f,0xa6,0xc8,0xd2,0x1a,0x90,0xd3,0x53,0xfc,0x48,0x64,0x94,0x6e,0x1c,0x72,0xef,0x5d,0xd4,0x23,0xa2,0x3a,0x93,0xe4,0x29,0x33,0x8a,0xbd,0xe5,0x17,0xc2,0xe9,0x18,0x6a,0x81,0x1e,0x5b,0x03,0x41,0x45,0x35,0x14,0xe7,0xc8,0x45,0x5c,0x37,0x69,0x77,0x62,0xf8
+.byte 0xd7,0xec,0x9d,0x62,0x2e,0xfa,0x43,0x3a,0xdc,0x8b,0x86,0x86,0x1b,0x31,0x71,0x0e,0x92,0x59,0xf7,0xef,0x96,0xfd,0x04,0x1e,0x1d,0x74,0x7d,0x08,0x06,0x21,0x54,0x39,0xd3,0x9f,0x30,0xa1,0x19,0x7f,0xc8,0x19,0x16,0xd1,0x21,0x2a,0xf3,0x21,0xce,0x19,0x1a,0xde,0x70,0x1b,0x87,0x05,0x9e,0xe8,0xf3,0xfd,0x1d,0xaa,0x61,0x6c,0xfb,0xdf
+.byte 0x50,0x9a,0xa0,0x32,0x4e,0xe4,0x68,0xda,0x0e,0x2f,0x2a,0x70,0xe1,0x51,0x66,0xb4,0x2d,0x5b,0xb6,0x32,0x3f,0xcb,0xc0,0xaf,0x01,0x03,0xcd,0xd6,0xb8,0x4e,0x3d,0x24,0x17,0xe2,0x30,0x3b,0xa4,0x08,0x0e,0x6a,0xcf,0xbe,0xc2,0x5c,0x79,0x5d,0x25,0xe2,0xae,0xa7,0x7f,0x42,0xff,0xa9,0xa5,0x05,0xbf,0xf4,0x92,0x30,0xaa,0x1d,0x96,0x7a
+.byte 0x49,0xbc,0x1c,0xaa,0x5c,0x8d,0xe8,0xf3,0xd3,0x1a,0x67,0x7f,0x47,0x09,0x90,0x35,0x82,0x4e,0xcc,0x2e,0x50,0xfe,0x2c,0xb9,0x29,0x39,0xff,0x49,0x8f,0x7e,0x89,0x8d,0x4a,0x15,0xd1,0xd6,0x83,0xdb,0x25,0xac,0xc1,0x81,0x23,0x70,0x3f,0xb9,0xce,0x7f,0x03,0x46,0xa8,0x39,0xab,0xff,0x71,0xc9,0x7b,0x3c,0xb3,0x5e,0x9f,0xfe,0x8a,0x0a
+.byte 0x39,0xad,0x6a,0xc1,0x8e,0x5a,0xa8,0x71,0xb7,0x01,0x25,0x28,0x15,0xd9,0x0a,0xae,0xc1,0xf9,0x23,0x1c,0xc1,0xe8,0x86,0x1d,0xb8,0x71,0x6e,0xa2,0xa4,0x67,0x22,0x4d,0x0e,0xd2,0xaa,0x70,0x26,0x23,0xfc,0x15,0xed,0x67,0x11,0x87,0x69,0x6f,0xc6,0x4c,0xe1,0x4b,0x04,0x86,0xe9,0x56,0x40,0xea,0x07,0xb1,0x6f,0xe9,0x8f,0xdd,0x2f,0xce
+.byte 0x8d,0xca,0x0a,0x58,0x01,0x44,0x2c,0x74,0xd0,0x14,0x07,0x9a,0xb7,0x5a,0xc1,0xea,0xa9,0xdd,0xa4,0x94,0x84,0xc2,0x11,0xa5,0xe2,0x00,0xd8,0xfc,0x77,0xb9,0x5e,0xe6,0x72,0xef,0xc5,0x38,0xe0,0x90,0x11,0x16,0xfd,0xa7,0x77,0xbd,0x4c,0x1d,0xeb,0x32,0x54,0xdb,0x2a,0x43,0xa1,0x87,0xbb,0x2e,0x79,0x22,0x4d,0xb3,0xdf,0x1a,0xee,0x75
+.byte 0xb0,0xdd,0xf2,0x09,0x05,0xf4,0x6a,0x3c,0x86,0xc6,0xe7,0x60,0x2a,0xee,0xb6,0x55,0xae,0xdc,0xce,0xf8,0xe4,0xd7,0xdf,0x72,0x42,0x91,0x6d,0xc4,0xd8,0x60,0xf1,0xe8,0x06,0x71,0x38,0xa3,0x03,0x3e,0x1b,0x14,0x47,0x74,0x93,0xb5,0x61,0x28,0xde,0x23,0x8f,0xbe,0x88,0x5e,0xdf,0x87,0x47,0xd4,0x5f,0x91,0x40,0xeb,0x02,0xda,0x27,0x3b
+.byte 0x65,0x9f,0xd8,0xf1,0x78,0x7f,0xba,0x9b,0x35,0xb3,0x10,0xaf,0x7f,0x51,0x37,0xa5,0x63,0x64,0x1f,0xf1,0xc3,0x1b,0x9e,0xe4,0xdd,0x93,0x8c,0x3a,0x98,0x20,0x9a,0x75,0x22,0x7b,0x48,0x0a,0x9d,0x55,0xed,0x07,0x1a,0x79,0x3b,0x98,0xe3,0x16,0x9b,0x16,0x2c,0xb2,0x03,0xc1,0xf5,0x6c,0xac,0x00,0x6a,0xb6,0xc1,0xc2,0x49,0x4d,0x9d,0xf5
+.byte 0x0e,0x7b,0x60,0x09,0xcc,0xa7,0x35,0xbb,0x70,0x34,0x18,0x49,0x2c,0xf1,0x41,0x4f,0xce,0x68,0x03,0x60,0x14,0xa7,0x2e,0x59,0x0f,0xa2,0xc4,0x2f,0x33,0xf0,0xb6,0xa4,0x31,0x75,0xdc,0xb4,0x88,0xe4,0xe3,0x0e,0x4b,0x3f,0x58,0xd0,0xa4,0xea,0x9a,0xef,0x47,0xb7,0xf7,0x20,0x71,0x52,0xd3,0x8a,0x1c,0xd9,0x2d,0x88,0x05,0x03,0x8a,0x1c
+.byte 0x3d,0x69,0xf0,0x39,0xf0,0x25,0xad,0x95,0xd4,0x47,0x3c,0xbb,0xfa,0x48,0xd7,0x8e,0xf5,0xdc,0x33,0x43,0x0a,0xbb,0xf0,0xd3,0xb1,0xc3,0x94,0x81,0xcd,0x22,0x79,0xdc,0xd0,0x92,0x8b,0xd3,0xc3,0xac,0x73,0x72,0x83,0xaa,0xa2,0x52,0x13,0x27,0x0e,0xc5,0x8c,0xa5,0x69,0x21,0x6e,0x9c,0x9d,0x9b,0xeb,0x7a,0x19,0xfe,0xb6,0xdb,0x4e,0xc1
+.byte 0xa6,0xec,0x42,0xb0,0x86,0x69,0x60,0xde,0x36,0x11,0x6a,0x86,0xd7,0xbf,0x15,0x48,0xa2,0x73,0x8f,0x68,0xde,0xd6,0xb2,0x6d,0xe0,0xc5,0x1f,0x1f,0xd5,0xc5,0xef,0xce,0xa1,0x90,0x5c,0xe6,0x6c,0x15,0x73,0xa7,0xcc,0x2d,0xe8,0xcf,0x4c,0xc8,0x17,0x3c,0xfa,0x5e,0xdb,0x4f,0x54,0xf3,0xa3,0xff,0x50,0x3e,0x42,0x60,0x0d,0xf3,0xf7,0xbb
+.byte 0xc6,0xf5,0xe7,0x63,0x50,0x49,0xc1,0x94,0x60,0x68,0xbd,0x62,0xc0,0x81,0x80,0x16,0xfd,0x65,0xfb,0x2e,0x23,0x67,0xb3,0xb6,0xf8,0x95,0xfa,0x00,0x3f,0x1d,0x10,0x16,0xd5,0xd9,0x66,0xf8,0x25,0xb4,0xce,0xf2,0x2e,0x4f,0xa2,0x21,0x14,0xbd,0x2c,0x63,0xec,0x44,0x57,0x07,0x87,0x3c,0x2f,0x22,0xcf,0x48,0xd3,0x20,0x51,0xfc,0x5d,0xd5
+.byte 0x9f,0x67,0x9c,0xaf,0xe3,0x89,0x36,0xc5,0xfa,0x7c,0xca,0x07,0xdc,0x56,0x2a,0x4e,0xa5,0x76,0xe6,0x09,0x99,0xfb,0xb7,0xba,0xaa,0x0b,0x9c,0xe2,0x0f,0x73,0xab,0x9b,0xbe,0x6f,0x50,0xe3,0xf7,0x28,0x32,0xf2,0xab,0x86,0xa3,0x89,0x3a,0xea,0xd7,0x52,0x52,0x6e,0xed,0x1b,0x94,0xf0,0x59,0x9d,0xbb,0x7a,0x88,0x6f,0xbf,0xaf,0x6a,0x87
+.byte 0x47,0x34,0x7f,0xf4,0x8b,0x0d,0x33,0x12,0x2b,0x67,0x6b,0xc9,0x1d,0x18,0x23,0x2e,0x54,0xee,0x07,0x28,0xbd,0x9d,0xa1,0xaf,0x85,0x7a,0x0f,0xe5,0x5d,0xf7,0x8b,0xca,0xd9,0x3d,0x8f,0x4f,0xcc,0xce,0xc3,0x6e,0x3a,0x40,0x08,0xd2,0x14,0xf0,0x28,0x9b,0xc0,0x4a,0x7a,0x3c,0xc2,0xed,0xe0,0x20,0x04,0xf5,0xf9,0xee,0xb8,0x35,0x94,0xbc
+.byte 0x53,0x46,0xf2,0x1a,0xab,0xe9,0xde,0xd8,0x27,0x67,0x0d,0x63,0x2a,0x7b,0x3a,0x38,0x91,0xbc,0x48,0x2c,0x38,0x09,0xa0,0xe3,0x66,0xe3,0xeb,0xb9,0x02,0x2d,0x80,0x87,0x81,0x4f,0x5c,0x1c,0xfd,0x2b,0x0f,0x99,0x37,0x3a,0xfa,0x0f,0x8e,0x8c,0x87,0x76,0x72,0xd3,0xcf,0xc8,0x1e,0x8a,0x3b,0x97,0xa0,0xe6,0x32,0x66,0x3c,0x55,0x2c,0xfb
+.byte 0xa9,0x41,0xfd,0xf9,0xd4,0x50,0xe0,0x5b,0x03,0xb7,0x1e,0x49,0xfa,0x59,0xeb,0x55,0xb1,0x21,0xd0,0x52,0xeb,0xe6,0x0f,0x21,0x81,0x4f,0x82,0x9a,0x8f,0x67,0x3d,0x0d,0x1d,0x11,0x1f,0x70,0x59,0x09,0x87,0x99,0xe5,0xf2,0x89,0xa6,0x56,0x8d,0x52,0x55,0xa8,0x91,0x5d,0x51,0x48,0xec,0x66,0x05,0xd6,0x18,0xd1,0x61,0x02,0x5a,0x80,0xcc
+.byte 0xee,0xf3,0x3b,0x8e,0x73,0x2a,0xb1,0x22,0xda,0x1d,0xca,0xb2,0xd6,0x7f,0xd7,0x7d,0xaf,0x23,0x8d,0xff,0x24,0x8e,0x5e,0x38,0x29,0x23,0x1f,0xbc,0xfd,0xe4,0x3d,0xcd,0x66,0xe3,0xe1,0x0f,0x85,0xe3,0xda,0x34,0xc6,0xba,0x60,0x5f,0xaf,0x32,0x79,0x34,0xc0,0x01,0x93,0xae,0x1e,0x72,0x7f,0xd2,0x32,0xa1,0xdc,0x0b,0xca,0xee,0x5a,0x7a
+.byte 0x09,0x98,0x2a,0x46,0x0a,0xe7,0xfd,0x0f,0x76,0xa0,0x3b,0x2b,0x3d,0xe5,0xcd,0x04,0xa2,0x5e,0x9b,0xba,0x4a,0xd5,0x0a,0xce,0x94,0x77,0xbb,0x24,0xa4,0x12,0xbc,0x24,0xb6,0x60,0x40,0x62,0xd2,0x70,0x0e,0x3f,0x62,0x72,0x2f,0xa1,0xc9,0x12,0x03,0x0f,0x39,0x57,0x77,0x7c,0x5c,0x31,0x13,0xcb,0x8c,0x2c,0x84,0xfd,0x7b,0x6f,0x60,0xbb
+.byte 0x1a,0x0b,0x65,0x8c,0xc1,0xe6,0x4b,0x60,0x8c,0xe7,0x3e,0x94,0x2a,0xcc,0x70,0x9f,0xd0,0xfd,0x00,0x0e,0x36,0xb2,0xf1,0x62,0x78,0x6a,0xc8,0x9b,0xbe,0x8b,0x54,0xa7,0xad,0xee,0x3e,0x8e,0x1c,0x23,0xbe,0xa2,0x73,0x43,0xbe,0x15,0x32,0x84,0xdd,0x22,0x75,0xd5,0x9a,0xfb,0x93,0x38,0x55,0x2f,0xa4,0x34,0x4c,0x33,0xc3,0xd7,0x7c,0x9f
+.byte 0x42,0x2f,0x9f,0xf6,0x27,0x90,0x15,0x6b,0x14,0x4f,0xbc,0x4b,0x07,0x42,0x24,0x98,0xa6,0xc4,0x4c,0x2f,0x22,0xd9,0x80,0x99,0x97,0x6b,0x7d,0xe8,0x2b,0x31,0x37,0xfe,0xd1,0x8b,0xbd,0xbf,0x08,0x4a,0x56,0x3d,0xff,0xb5,0x12,0x6d,0xc4,0xcf,0xbc,0x75,0xe9,0xe6,0x6f,0x1a,0x30,0x34,0x5b,0x2c,0x1d,0x8f,0x85,0xa0,0xe8,0xfd,0xfd,0xe2
+.byte 0xe7,0x13,0x73,0xcd,0x63,0x63,0x90,0xa5,0xa4,0x3f,0x91,0x65,0x77,0xd4,0xed,0x0c,0x1d,0x06,0x95,0x93,0x74,0x85,0xec,0x31,0xde,0xc9,0xb9,0x2e,0x7c,0x6d,0x2c,0x0d,0x15,0xb7,0x6b,0x0c,0xd2,0xe8,0xa8,0xcb,0x90,0x5c,0x11,0x53,0xc5,0x9d,0x54,0xf4,0x90,0xf7,0xc8,0x17,0x65,0xc0,0x3f,0xea,0xf6,0x28,0x8e,0xf0,0x1c,0x51,0xcc,0xfd
+.byte 0x99,0x67,0x3d,0xa5,0x82,0x1f,0xb3,0x75,0x08,0x27,0x85,0xa9,0x7b,0x54,0x91,0x6e,0x80,0x9a,0xdb,0x6c,0x17,0x4a,0x36,0x73,0x0e,0x61,0x2e,0x01,0xae,0x32,0xf8,0x54,0xdb,0xcf,0x24,0xa5,0x13,0xb1,0x7e,0x0b,0xf5,0xe7,0x0e,0x27,0x9a,0xef,0x01,0x0b,0x34,0x4f,0x91,0xc2,0x93,0xe0,0xe6,0x14,0x64,0xf8,0x7b,0x41,0x37,0x22,0x39,0xad
+.byte 0xf4,0xa9,0x3b,0xfb,0x7e,0x2b,0xd8,0x2b,0x0f,0x7e,0x40,0x55,0x5a,0x48,0x61,0x2f,0x95,0x5e,0x5c,0x25,0xe5,0x06,0x89,0x17,0x23,0xb6,0x1b,0x38,0x2e,0x7b,0x45,0xa5,0x11,0x0a,0x8d,0xd3,0x8d,0xb6,0x8d,0x47,0xc5,0x4f,0x8f,0x8b,0xe2,0x03,0x85,0xa1,0x5a,0xa2,0x8d,0xca,0x4d,0xef,0xc9,0xde,0x7d,0x06,0xa1,0x3f,0x21,0xb9,0x38,0x7b
+.byte 0x91,0xf7,0x5c,0x9f,0x97,0xe3,0xeb,0x5d,0xea,0x5e,0xc1,0xa5,0x30,0xb0,0x7f,0xe0,0x4c,0xef,0xe5,0xe3,0xa0,0x2d,0x23,0xb6,0x08,0x21,0xe6,0x67,0x35,0x82,0x07,0x59,0x02,0xd4,0x68,0xa5,0xf1,0x42,0x70,0xb4,0x5e,0x54,0xed,0x1e,0x99,0xb2,0x55,0xf1,0x69,0x2e,0x7c,0xaa,0x6c,0x5e,0xd4,0xfa,0x16,0xa7,0x1f,0xdb,0x46,0x70,0x65,0x26
+.byte 0x98,0xf1,0xb6,0x42,0xb3,0x48,0x99,0x7c,0x07,0xbe,0x2b,0xee,0xb4,0xc1,0xf0,0xb7,0x47,0xf8,0xcf,0xe4,0x8d,0x34,0xa6,0xe5,0x17,0x9a,0xb7,0x2c,0x2e,0x03,0x30,0xfd,0xfb,0x42,0xe7,0xa1,0xe0,0x34,0x49,0x64,0xd8,0x0c,0xd5,0xb8,0x77,0x9f,0x0e,0xe2,0x73,0x0d,0x20,0x0c,0x21,0x07,0xaf,0x0f,0x93,0x94,0xd6,0xdc,0xe3,0xac,0x8d,0x8e
+.byte 0xae,0x87,0xbd,0x2c,0x19,0x66,0xef,0x90,0x4a,0xd9,0xb0,0xf6,0xac,0x3a,0xe2,0xb5,0x2e,0xb4,0x63,0x91,0xf1,0x8b,0xac,0xce,0x51,0xc2,0xe0,0x02,0x7d,0xf8,0xab,0xe4,0xd6,0x85,0xd6,0xbb,0xd7,0x72,0xd0,0x5f,0x4e,0x90,0x09,0xcc,0x51,0xee,0x5b,0xad,0xb2,0xf6,0x16,0x37,0x09,0xa8,0xfc,0x74,0xa5,0x2e,0x26,0x27,0xff,0x53,0xd4,0x45
+.byte 0x82,0xb1,0xb6,0x16,0x65,0xc6,0xbb,0x54,0x0b,0x89,0xa1,0x0e,0x09,0x7c,0xc9,0xc9,0x48,0xa7,0x51,0x78,0x1d,0x3a,0x30,0xc5,0xe7,0x02,0x9e,0x91,0xd6,0x39,0xc8,0x35,0xf0,0x33,0xab,0xf6,0x0f,0xf9,0xce,0xef,0x26,0x46,0x48,0x56,0xbc,0x45,0x44,0xe2,0xd7,0xfc,0xdf,0xb2,0x95,0x20,0x07,0xeb,0x47,0x1c,0xde,0x88,0x5e,0x08,0xee,0xa1
+.byte 0x56,0x9a,0x5d,0x8f,0x35,0xc5,0xb3,0xd3,0x7d,0xe3,0x25,0x82,0xcc,0xcb,0xad,0xd8,0xef,0x83,0x76,0x08,0x55,0x9e,0xf4,0x00,0x1f,0x92,0x24,0x0e,0xf6,0x96,0x98,0x34,0x10,0x10,0x93,0x27,0x3b,0x96,0xbd,0x75,0x45,0x9d,0xad,0xc1,0x79,0xa7,0x09,0x68,0x0a,0xbc,0x14,0xe9,0x62,0xf6,0x5e,0x4e,0x6d,0xfb,0xf2,0x25,0x20,0x8b,0x53,0xa6
+.byte 0xc2,0x31,0x71,0xaa,0xfa,0xa2,0x1c,0xa1,0xb3,0xa2,0xd7,0x22,0x5a,0x72,0x61,0x5c,0x30,0x75,0xcc,0x82,0xb0,0xd0,0x07,0x8c,0x95,0x11,0x57,0xa4,0xe2,0x42,0xf3,0x3d,0x87,0x56,0x45,0x38,0xd6,0x1b,0x2b,0x26,0x11,0x99,0xce,0xcc,0x2e,0x96,0x1b,0xa1,0x06,0xa1,0xa9,0x65,0xe1,0x1f,0x53,0xb6,0x1e,0x5c,0x44,0x40,0xa2,0xf2,0x03,0xe7
+.byte 0x39,0x24,0x59,0x5f,0xdd,0x30,0xf0,0x78,0x9f,0x34,0xf1,0xd3,0x5d,0x9a,0xdd,0xf9,0x02,0x16,0x4b,0xfa,0x8d,0xab,0x2f,0x96,0xdb,0x67,0xf6,0x1e,0x7a,0xf8,0xd8,0xe6,0x71,0xdc,0x1a,0xbf,0x44,0xd2,0xbd,0xb3,0x6d,0x47,0x69,0xe0,0x14,0xef,0xe5,0x5e,0x0a,0xe9,0x1a,0x8b,0x3f,0x67,0x1e,0x1c,0x37,0x86,0x25,0x02,0x52,0x3f,0xf5,0xde
+.byte 0xe0,0xbe,0x1d,0x61,0x44,0x3d,0xd2,0xe9,0x26,0x3d,0x4b,0xa4,0xb1,0xb9,0x62,0xc5,0x70,0xfb,0x1d,0xaf,0xe6,0x19,0x97,0x0f,0x6e,0x6d,0x4e,0xdf,0x5f,0xc9,0xb2,0xb0,0xb9,0x4b,0x72,0xc7,0x60,0x5d,0xf8,0x7d,0x3b,0xd8,0x74,0x29,0xf2,0x56,0x25,0xd9,0xd9,0x12,0x3a,0x50,0x01,0x54,0xd3,0x0e,0x4c,0xbd,0xc9,0xf5,0x66,0xc4,0x4b,0xa2
+.byte 0x68,0x31,0xb1,0x9d,0x47,0xd8,0x28,0xce,0x6b,0xe4,0x5f,0x78,0x75,0x22,0x7d,0x44,0x08,0x71,0xfb,0xd8,0xa0,0x6e,0xd1,0xbd,0x64,0x4e,0x00,0x99,0xf7,0x85,0xad,0x31,0xde,0x5c,0x4c,0x7c,0xc3,0x89,0x49,0x9f,0xea,0x22,0x86,0xa0,0x48,0x48,0xcf,0x47,0xfb,0x68,0x04,0x4c,0x05,0x62,0x57,0x60,0x9b,0xa0,0x37,0x41,0x77,0xe4,0x7d,0x3e
+.byte 0x36,0xda,0xd5,0xfd,0x68,0x47,0x8c,0x68,0x61,0x4c,0xea,0x38,0x20,0xa5,0xe4,0x12,0x6e,0xd5,0x14,0x37,0x01,0xcf,0xbd,0xdd,0x55,0x97,0xb4,0x30,0xf0,0x65,0x15,0xee,0x1f,0xc8,0x5b,0x07,0x82,0xae,0x43,0xad,0x11,0xda,0x0e,0x61,0x23,0x0a,0x5f,0x52,0xf9,0x9d,0xc5,0x98,0x4e,0xaf,0x77,0x21,0xc8,0x9f,0x6d,0x25,0x94,0x4f,0x91,0x1a
+.byte 0xb4,0x2d,0xe3,0x15,0xe5,0xe6,0x25,0xb8,0x8e,0xd8,0x33,0xe3,0x05,0x01,0x7b,0x6b,0xa8,0x39,0x44,0x4b,0x58,0x3c,0x17,0x53,0x17,0x5c,0xbc,0xd5,0xcd,0xd4,0x29,0xe7,0x17,0x7a,0x69,0xa6,0x75,0x8e,0x0a,0x00,0x41,0xbe,0xb4,0x8d,0x79,0x1d,0xac,0x2a,0x0f,0x9b,0x7b,0x5a,0xe8,0x17,0xe2,0xb3,0x1d,0x03,0xde,0x5a,0x7c,0x31,0x18,0x8c
+.byte 0x1c,0xf9,0x19,0x7b,0x37,0x1f,0x53,0x77,0xce,0x1f,0xad,0xb6,0x0d,0x21,0xe1,0xb0,0xf9,0x42,0x52,0x99,0x02,0xa8,0x58,0xab,0x94,0xf8,0x9f,0x99,0x2d,0x1e,0x68,0x4f,0x5a,0x91,0x2b,0xdf,0xe8,0xe6,0x34,0xb6,0x80,0x9b,0xb1,0x0e,0x87,0xec,0x29,0x17,0x4d,0x98,0x2d,0x40,0xd0,0xf7,0xca,0x55,0x9d,0x56,0x19,0xd5,0x7c,0x4e,0x2e,0x75
+.byte 0x5d,0xe7,0x3e,0xed,0x47,0xdc,0xb1,0x04,0xe5,0x61,0x0f,0xe7,0xc4,0x16,0x71,0xf4,0xf8,0x8a,0xf1,0xfc,0xd5,0xdb,0xeb,0x0b,0x82,0x0f,0xfe,0x64,0xa2,0xb0,0x53,0xab,0xf5,0x01,0xc2,0x8f,0xa0,0x4d,0x5d,0x1b,0x54,0x32,0x48,0xca,0x8a,0x42,0x59,0x4a,0x85,0x68,0x75,0xd1,0x1b,0x03,0x11,0xfe,0x28,0xd7,0xd5,0x37,0x81,0x7a,0xfb,0x84
+.byte 0xfd,0xa8,0x98,0x54,0xf7,0x81,0xb0,0x2d,0x2d,0x5d,0x95,0x0a,0x5b,0x80,0x13,0x95,0xad,0x8f,0x88,0xaa,0x38,0x7e,0xbc,0x88,0xc2,0xf6,0xa6,0x1e,0x6d,0x78,0xc9,0x4f,0xa9,0xb3,0xaa,0x23,0x0c,0x62,0x19,0x6f,0x26,0x5d,0xca,0x36,0x23,0xf8,0xd1,0x76,0x80,0x32,0x59,0xa0,0x47,0x86,0xee,0xc9,0x0f,0x1d,0x37,0xd9,0xc9,0x4e,0x65,0x22
+.byte 0x17,0x95,0x88,0x85,0xb3,0x8a,0x5d,0xb9,0xe6,0x3b,0x6c,0x02,0x81,0x61,0xe0,0xab,0x19,0x6c,0x9a,0x29,0x33,0xf1,0x7b,0x0c,0x22,0x16,0x0c,0xd6,0xfa,0xc2,0x84,0xe5,0x74,0x9e,0x8e,0xf8,0xdb,0x44,0x68,0xa0,0x58,0x52,0x9f,0xad,0xe6,0x2b,0x23,0x70,0xf3,0x6e,0xdc,0xf1,0x2d,0xa5,0xc2,0x7f,0xef,0x5f,0x58,0xc2,0x96,0x66,0x67,0x4b
+.byte 0x7c,0xe0,0xd7,0x96,0xda,0xf7,0xd7,0x7a,0x7d,0xb4,0x4f,0x48,0xbd,0x87,0x6b,0xf4,0xbd,0xd1,0x45,0xdc,0xba,0x4f,0xd2,0x00,0x7f,0xde,0x3c,0x57,0xd7,0x3b,0x5b,0xa9,0xf3,0x17,0x76,0x47,0x0c,0xcf,0x48,0x07,0xa8,0xc3,0x30,0x60,0xc6,0x98,0x20,0x29,0xba,0x5f,0x76,0x6d,0x63,0x5f,0x87,0x7e,0x36,0xbc,0xa3,0xe4,0xd6,0x6a,0x55,0x73
+.byte 0x8b,0x8b,0x62,0x40,0xc5,0x7e,0xa3,0x33,0x04,0xce,0xe2,0x9d,0x9f,0x67,0x1c,0xf0,0xa1,0x78,0xd2,0x0b,0x58,0xc1,0x2e,0xec,0x78,0x0a,0xc9,0x0b,0x1d,0xfb,0xcc,0x72,0xd8,0xe4,0x15,0xcb,0x09,0x8b,0xd9,0x33,0xa9,0xb6,0x24,0x7e,0x59,0x48,0xbf,0xda,0xdb,0x5c,0x99,0xd1,0x92,0x1b,0xb6,0xf6,0x75,0x78,0x53,0x69,0x89,0x27,0x6b,0x3c
+.byte 0xfb,0xd2,0xa7,0xeb,0xc5,0xf7,0xea,0x8b,0x38,0x59,0x8e,0x02,0xc7,0x6e,0x96,0x8a,0x85,0x1c,0x91,0x1b,0x97,0x97,0x9e,0xa7,0x9d,0x10,0xa4,0x4a,0x6e,0xa8,0x51,0x05,0xbe,0x5f,0x9a,0x5b,0x94,0xf2,0x2c,0xa1,0x1e,0x33,0xc5,0xe8,0x92,0xb8,0xd2,0xfa,0x27,0x07,0x12,0xa1,0xdc,0x24,0x43,0x28,0x06,0xe5,0x43,0x57,0x8f,0x66,0x72,0x2f
+.byte 0x26,0xf7,0xea,0xa1,0xcf,0x57,0xd6,0xa6,0xf7,0x37,0x1d,0x6e,0xd9,0xde,0x1a,0x8c,0xf5,0x01,0x76,0xc3,0x56,0x40,0x57,0x3d,0x4a,0x14,0x04,0xf2,0xfc,0xba,0x3b,0x60,0xf1,0x88,0x1e,0x16,0x08,0x99,0x90,0xfe,0x27,0xaa,0x04,0x53,0xd8,0x7e,0x0c,0x58,0x6a,0xd9,0x5a,0xe4,0x11,0xd4,0xcc,0x48,0xbe,0x03,0x08,0xbc,0x61,0x47,0xdd,0xde
+.byte 0x5f,0x03,0xc7,0x8f,0x9c,0x08,0x93,0xe3,0xaa,0xee,0x9c,0xe3,0xc6,0x06,0x78,0xda,0x0a,0xdd,0xb0,0xc3,0xf3,0x0b,0xe5,0xa0,0x5f,0x1e,0x3e,0xb3,0x15,0x7f,0xf1,0xf4,0x38,0xb2,0xed,0xf2,0xa6,0x8b,0x1d,0x78,0xb6,0x03,0x19,0xcd,0x17,0xb4,0x18,0x17,0x49,0x61,0x17,0xbd,0xbe,0x4b,0x04,0x00,0xce,0x4b,0xcc,0x47,0x61,0x76,0x85,0xdc
+.byte 0x2b,0x85,0x48,0x82,0xf4,0x9b,0xb4,0x62,0x53,0xc7,0x06,0x50,0xf2,0x3e,0xba,0x6d,0xf2,0x19,0x0f,0x7f,0x84,0xce,0xa6,0x4d,0x96,0x97,0x94,0x12,0xb6,0xd0,0xd6,0xa4,0xc1,0xcc,0x14,0x54,0xf6,0x7a,0xf1,0x94,0x62,0xa1,0xc7,0x22,0x9b,0x0d,0x0e,0x69,0xcf,0x38,0x5c,0xda,0x9f,0xc0,0xfa,0x93,0x81,0x24,0xce,0x9f,0xf3,0xc2,0x66,0xad
+.byte 0x06,0x21,0xf2,0x48,0x6c,0x4a,0x0d,0xb8,0x41,0x86,0xaf,0xb7,0x6c,0x65,0xcb,0x83,0xd8,0x75,0x11,0x60,0xfa,0x06,0xe5,0xd2,0x11,0x87,0x29,0xb8,0x41,0xcb,0x17,0xb5,0xbd,0xbd,0xf9,0xd5,0xbc,0x89,0xb6,0x60,0x65,0x59,0xbb,0x38,0x9d,0x70,0xf9,0x81,0x6b,0xe6,0x12,0x80,0x08,0x73,0x9f,0xfb,0x2f,0x72,0x4e,0x18,0xff,0x65,0xab,0xa6
+.byte 0xaa,0x78,0xf1,0xa4,0xe9,0x1a,0x7d,0xa5,0xdd,0x91,0x77,0xa9,0xa3,0xf3,0xe3,0xe5,0x5a,0xa2,0x0d,0x3a,0x2a,0x4a,0x11,0x9a,0x8d,0xc3,0x00,0x6e,0xd4,0x4f,0xb9,0xe7,0x39,0x78,0x89,0x64,0xb2,0xc8,0xfd,0x1f,0xe6,0xa9,0x54,0x17,0x83,0x3f,0xeb,0x97,0x77,0xac,0xc8,0xba,0x0e,0x77,0x02,0xb0,0x29,0xbe,0x51,0x62,0xef,0xa5,0xd5,0xab
+.byte 0x79,0x98,0xab,0x7a,0x1e,0x13,0xe8,0x87,0x4f,0x61,0xa3,0x37,0xdf,0xe6,0xda,0xb9,0xf5,0x69,0xf7,0x7a,0xee,0xd6,0x5f,0x6a,0xb3,0x95,0x55,0x59,0xd1,0x6c,0x5b,0xd5,0xba,0x8b,0x74,0x85,0xbf,0x1e,0xe5,0xb3,0x24,0x28,0x4b,0xc8,0x4a,0xec,0xa1,0x1d,0xda,0x99,0x3f,0xdf,0xfc,0xe6,0x2e,0x1b,0xa4,0xba,0x1a,0x03,0x89,0xb7,0x93,0x4e
+.byte 0xaf,0x40,0xb0,0x7e,0x3f,0x34,0x0d,0x94,0x75,0x8c,0x8a,0xfb,0x88,0xcd,0xd3,0xc2,0x61,0x95,0x63,0x51,0xaa,0x78,0x1f,0x24,0x95,0x5a,0xb5,0x98,0x9a,0xd4,0xb8,0x34,0xe1,0x47,0x1c,0x68,0x0f,0x08,0xf1,0x69,0xe6,0xd4,0xaf,0x23,0xf6,0x32,0x71,0x51,0x01,0xa9,0xf2,0xa1,0x45,0x0b,0x75,0x82,0x09,0xe4,0x9c,0x2a,0x1d,0x0b,0xd6,0xd2
+.byte 0x26,0xe8,0x30,0x44,0xdf,0xa3,0x2b,0x97,0x11,0xc7,0xe7,0x47,0xfd,0xc7,0xbf,0x59,0xf3,0x28,0x32,0x46,0xc0,0xc4,0x7a,0x96,0x08,0x0d,0x2c,0xa1,0x82,0x6c,0x0a,0x33,0x82,0x55,0xd7,0xcf,0x3e,0x08,0xbb,0x22,0x15,0x96,0x12,0x66,0xd2,0xae,0x21,0x3a,0x54,0x6a,0xe0,0x33,0x0c,0xa4,0x96,0x4b,0x5d,0xf2,0x86,0xb9,0x70,0xe4,0x65,0x45
+.byte 0xe4,0x2f,0xa7,0xb4,0xc1,0xd5,0x9a,0x02,0xa1,0x5b,0x4e,0x58,0xca,0xf8,0x63,0xae,0x45,0x1c,0xf4,0xa7,0xc8,0xa5,0x84,0x23,0x87,0xcb,0x3e,0x88,0xca,0xe9,0xa9,0x49,0xc5,0xc6,0x63,0x37,0x99,0xe0,0x27,0x03,0x96,0x7b,0x73,0x8c,0x36,0xde,0x89,0x80,0x30,0x2c,0x00,0x94,0x0b,0xfb,0x1f,0x39,0xe0,0xed,0xb6,0x31,0x21,0x90,0xfe,0xa4
+.byte 0xee,0xa5,0xe5,0x7b,0x9a,0x11,0x41,0x51,0xab,0x89,0x54,0xe0,0x8d,0x5f,0x10,0x1b,0x76,0x27,0x77,0x3d,0xb0,0x58,0x86,0x7b,0xb7,0x45,0xfb,0xd0,0x81,0xa8,0xcd,0xc0,0xc8,0x5f,0xfb,0xfe,0x8c,0x0a,0x3d,0x5d,0x61,0x4b,0x9b,0x32,0x75,0x66,0xa9,0xac,0x32,0x35,0xe9,0x1a,0xdf,0x06,0x8d,0x13,0x5d,0x40,0xcb,0x7d,0x50,0x3e,0x54,0xab
+.byte 0x04,0xbc,0x83,0x32,0x8f,0xf5,0x93,0x1d,0x9b,0x5a,0xe1,0x19,0x70,0x4a,0xba,0xfc,0x4c,0x6a,0xf3,0xd6,0xd1,0xfd,0x48,0xd0,0x7c,0xa4,0xab,0x0b,0xb6,0x5f,0xe1,0x31,0xce,0x99,0x10,0x98,0xfc,0x6e,0x1c,0xaa,0x9c,0x34,0xa2,0x55,0xdc,0xe0,0x81,0x1b,0x9e,0xff,0x75,0x2e,0x25,0xe9,0x2c,0x20,0x83,0xf6,0x66,0xf9,0x63,0x31,0xfe,0xa7
+.byte 0xbf,0x4d,0xfd,0xff,0x0b,0x93,0x84,0xd4,0xb4,0x72,0x13,0x38,0x90,0x75,0xc9,0xff,0x61,0x4b,0xf9,0x55,0x62,0x58,0xf0,0x60,0xce,0x2d,0xec,0x94,0x06,0x0a,0xde,0x48,0xc0,0x46,0x89,0xfb,0x5c,0xf7,0x9f,0x37,0xad,0xd2,0xff,0xbe,0xfb,0x81,0x21,0xe0,0x20,0x43,0x88,0xad,0x40,0x47,0x7a,0xa9,0x30,0x88,0x10,0x16,0x41,0xf8,0x25,0xe0
+.byte 0x8f,0xc2,0xe3,0x9f,0x48,0xd3,0xfe,0x61,0x70,0xb9,0xa1,0x9e,0xaa,0xa6,0x73,0xcf,0xc3,0xd6,0xab,0x69,0x65,0x4a,0x3c,0xec,0x28,0x02,0x63,0x62,0xa1,0xb6,0xa3,0xd5,0x8c,0x9e,0x11,0x81,0x98,0x12,0x4f,0xec,0xb6,0xe5,0x3a,0x96,0xa1,0x11,0x13,0x77,0x5f,0x0f,0x19,0x40,0x14,0x28,0xcc,0xf1,0x3e,0x19,0x1d,0x78,0x31,0xac,0x5c,0xce
+.byte 0xd7,0x29,0xfa,0x02,0x3b,0x29,0xd8,0x3a,0x37,0xcb,0x94,0xb2,0x38,0xc7,0x7f,0x3a,0x46,0xd2,0xb7,0xfe,0xfb,0x54,0x7c,0x01,0xa2,0x9b,0x53,0x57,0x04,0x73,0x4e,0x06,0x90,0xe5,0x78,0x0a,0x45,0x67,0x12,0x83,0xd7,0x31,0x59,0xa4,0x76,0xaa,0x7c,0xde,0x72,0x92,0x11,0x94,0x4c,0x6a,0xe4,0x35,0x35,0x3a,0x2e,0xef,0x7c,0xc1,0x91,0x76
+.byte 0xd0,0xfe,0x84,0xd1,0xa1,0xf9,0x03,0xc3,0xba,0x09,0xbb,0x2c,0xe2,0xb5,0x06,0x7e,0x23,0xb7,0xe0,0xc1,0xd3,0xfd,0x55,0x01,0xf3,0xba,0xc5,0x1b,0xf8,0x02,0x60,0x92,0x0a,0x93,0x1c,0xc4,0x19,0x03,0x88,0xf5,0x45,0xe5,0x8f,0x7d,0xce,0x2c,0x87,0x2e,0xf6,0x55,0x8c,0xf9,0xb0,0xd2,0x72,0x2d,0x93,0x6d,0x28,0x6e,0x8e,0x3a,0xed,0x68
+.byte 0x02,0xda,0x80,0xd0,0x71,0x4a,0x8f,0x06,0x59,0x38,0x89,0x81,0xcb,0x1a,0x74,0x1e,0x62,0xa3,0xa5,0xb8,0x85,0xc3,0xd2,0x04,0x3d,0x3b,0x93,0x36,0x0c,0x12,0x55,0xfb,0x7b,0xc8,0xa3,0x25,0xa7,0x93,0xb0,0x3e,0x49,0x86,0xbf,0x76,0x8f,0xc4,0x4c,0xfe,0xce,0x4a,0xf6,0x2f,0x15,0x33,0x06,0x3a,0x35,0x49,0xe7,0x08,0xff,0x99,0xac,0xf6
+.byte 0x20,0x6d,0xab,0xb2,0x05,0xa9,0xe4,0x06,0x57,0x9c,0xf4,0x76,0x8c,0x82,0x64,0xd5,0x67,0xe0,0xad,0xe1,0x69,0xdc,0x9e,0x2c,0x59,0x92,0x3a,0xc8,0xc1,0x0a,0x61,0x89,0x45,0x9f,0x8b,0xf8,0x64,0x0a,0x5a,0x75,0x55,0x37,0x24,0xe1,0x42,0x43,0x7c,0x9c,0xcd,0x4e,0x9e,0x19,0xfb,0xd9,0x15,0x29,0x30,0x52,0x33,0xf3,0xc8,0x88,0xdb,0xaa
+.byte 0x07,0x27,0xfb,0x2b,0x0c,0xc0,0xa1,0x5f,0x51,0xf1,0x54,0xf8,0x90,0x0a,0x35,0x07,0x6e,0x9c,0x64,0xd8,0x4f,0x2d,0xb3,0x61,0xbc,0x18,0x1f,0x22,0x84,0x94,0x4b,0x85,0xfc,0x4a,0xf9,0xe5,0xfc,0xdd,0x7a,0x07,0xa2,0xbb,0xbe,0x7e,0x1f,0x4e,0xf9,0x29,0xb8,0xde,0x56,0xe9,0x04,0xc1,0xc2,0xb6,0xa8,0xc7,0xb6,0x83,0xf2,0x85,0x3d,0x35
+.byte 0xe3,0xeb,0x2f,0x2f,0x3c,0x1a,0x3a,0xf1,0x61,0x1f,0xe8,0xf0,0xce,0xa2,0x29,0xda,0x3f,0x38,0xf5,0x82,0x7a,0xb8,0x55,0xf1,0x1a,0x6e,0x5b,0x5c,0xd0,0xc8,0xc8,0x3a,0xe2,0xaf,0xb4,0x6f,0xba,0xe4,0x03,0x78,0x5f,0x47,0x4b,0xaf,0xfe,0x2a,0x7e,0x27,0xba,0x17,0xb4,0x92,0x27,0x70,0x13,0xd9,0xbb,0x6b,0x1c,0x9a,0x3e,0x29,0x85,0x9a
+.byte 0xb7,0x64,0x5b,0x6d,0x7b,0xec,0xb2,0x26,0x3a,0x4b,0xb7,0x17,0xaf,0xb5,0xa1,0xbc,0x4d,0x67,0x4c,0x86,0xd1,0x53,0x2e,0x5d,0x64,0xe8,0x55,0xd9,0xbb,0xae,0xc1,0x55,0x41,0x99,0x8e,0x4d,0xed,0x3d,0x9e,0xea,0xe3,0xf2,0x76,0x45,0x6d,0xaa,0xbb,0x89,0x0b,0xc0,0x13,0xfe,0x99,0x2c,0xb0,0xd2,0xa9,0xeb,0x58,0x57,0x4d,0x88,0x2e,0x04
+.byte 0x4f,0x7a,0x76,0xaa,0x3a,0xa6,0x08,0x93,0x42,0x74,0x2f,0x3a,0x35,0xb0,0x36,0xcc,0x77,0xec,0x54,0x41,0x2e,0x81,0xf6,0x9f,0xf3,0xe7,0x23,0xc0,0x3f,0xa4,0x52,0x83,0x38,0xe2,0x12,0xed,0xdb,0x23,0xa0,0x0b,0xbf,0x61,0x98,0x89,0xb0,0xa4,0x3d,0xa9,0x6a,0x73,0xa1,0x99,0xc9,0x9e,0x68,0x45,0x37,0x4b,0x6c,0x87,0xfb,0x93,0xf2,0xaa
+.byte 0xe8,0x1d,0x53,0x6c,0x4b,0xda,0xc5,0x6f,0xaa,0xde,0x99,0xd2,0xba,0x7c,0x27,0xc2,0x4e,0xd5,0x5b,0xc8,0x13,0x9e,0xa2,0x10,0x6a,0xbb,0x39,0xf9,0xa7,0x55,0x0a,0x65,0x88,0x3c,0x9b,0xff,0x83,0x4e,0xf7,0x9c,0x99,0x69,0xbd,0x64,0x0d,0xd1,0xc0,0xb0,0x43,0xd6,0x63,0x50,0x13,0x68,0x8d,0xd1,0x7e,0x56,0x93,0xb5,0x8e,0x8f,0x12,0xe5
+.byte 0x37,0x96,0x21,0x64,0xd5,0x0b,0xf6,0x27,0xf8,0xaa,0x34,0x8e,0xc4,0x2b,0x7b,0x6a,0x7c,0x89,0x4e,0x15,0x15,0x3d,0x17,0x93,0xd4,0x99,0xfe,0x97,0x95,0x20,0x85,0xcc,0xd4,0xcd,0x73,0x67,0x80,0x22,0x06,0xed,0x5e,0xce,0x90,0x59,0x01,0x31,0x24,0x17,0x37,0x4a,0x63,0x96,0xc2,0xf3,0xe0,0x21,0x0a,0x3b,0x9f,0x94,0xad,0xd6,0xa4,0xa9
+.byte 0xa2,0x54,0x0d,0x2a,0xb3,0x5c,0xfa,0xbe,0xeb,0x21,0xd6,0x13,0x22,0xa5,0x95,0x5e,0x25,0x72,0xf9,0x18,0x1f,0x50,0x64,0x04,0x5b,0xe8,0x0e,0x1f,0x6c,0xe1,0x4e,0xf5,0x7f,0xf0,0x13,0x4f,0xda,0x75,0xab,0x5a,0x98,0xd3,0x07,0x32,0x96,0x2a,0xc7,0x1e,0x0f,0x14,0xdb,0x96,0x5f,0xac,0xc1,0xef,0x5b,0x2d,0xd6,0x6d,0x13,0x01,0xd9,0x04
+.byte 0x9c,0xcd,0xe5,0x5e,0xbe,0x3a,0x47,0x14,0x09,0xbe,0x11,0xad,0x87,0x3f,0x0e,0xe1,0xcb,0x97,0xd0,0x6e,0x1f,0x49,0x07,0xd1,0x8c,0x2b,0xe0,0xf0,0xb2,0xaa,0x8b,0x70,0x18,0x7f,0x29,0xcc,0xc4,0x23,0x66,0x48,0xc4,0xb5,0x5e,0xf1,0x10,0xd7,0x1d,0x2a,0xba,0xe4,0x12,0x64,0x1d,0xf5,0x03,0x35,0x71,0x57,0x5d,0xf4,0xa4,0xb5,0x99,0x0b
+.byte 0x4c,0x80,0x65,0x07,0x2f,0xbc,0xf7,0x28,0x8b,0xc0,0x8f,0x84,0x63,0x7e,0xf5,0x01,0x23,0x8c,0xaf,0x71,0x35,0xd4,0xe1,0x70,0xc7,0xef,0x1f,0x66,0xa9,0x34,0x57,0xaa,0x9a,0xbb,0x80,0x43,0x15,0x96,0xc4,0x03,0xd9,0xae,0xbe,0x89,0x1c,0xa1,0x9f,0x65,0x61,0xe5,0x90,0x9f,0xa6,0xf4,0x3b,0xde,0xa1,0xd1,0xf1,0xf9,0x2d,0xd7,0xa7,0x7e
+.byte 0x3d,0x42,0x3d,0x1b,0x99,0xed,0x49,0x2e,0x92,0x6b,0x47,0x0e,0x0b,0x90,0x56,0xe0,0x1b,0x6b,0xfe,0x97,0xfe,0x9b,0xa2,0x50,0xcc,0xbf,0xea,0xae,0xe8,0xf0,0xc4,0xe5,0x81,0x20,0x4a,0xb0,0xf7,0xa5,0x23,0x24,0xf6,0x3f,0x9e,0x9c,0xcc,0xce,0xe4,0x95,0x49,0xea,0x66,0x4a,0x35,0x31,0xf3,0x03,0xc3,0x08,0xf9,0x5f,0x95,0x4c,0xbc,0x84
+.byte 0x13,0xbe,0x7f,0x35,0xbb,0xd7,0x35,0x3c,0xfb,0x05,0x43,0x95,0xbf,0x87,0xf2,0xc3,0x2d,0xef,0x13,0x1d,0x65,0x17,0x82,0x75,0x3d,0x67,0x51,0xcd,0x6e,0x42,0x5f,0x49,0x53,0x8b,0xaf,0x34,0x7d,0xa8,0xc1,0x45,0xcd,0x3d,0x29,0x00,0xa3,0xf3,0xbb,0x44,0x00,0x05,0x57,0xa5,0xeb,0xfd,0x98,0xa6,0xae,0xc6,0xc4,0x6c,0x6d,0x7d,0xf6,0x3e
+.byte 0x82,0x1d,0x12,0xe7,0xcd,0xd2,0xd5,0xfe,0x41,0xf8,0xa4,0xb3,0x6a,0x04,0x13,0x28,0x10,0x40,0x27,0xc9,0x43,0x74,0xcf,0xaf,0x9b,0x60,0x17,0x43,0x8f,0xd7,0xb7,0x56,0x72,0xf3,0x48,0x0a,0xe6,0x36,0xf2,0x3f,0x51,0xf9,0x6e,0xc8,0xa3,0x04,0x8c,0x01,0x86,0x6e,0x83,0x27,0xe2,0xba,0xf2,0x8f,0x8f,0xa1,0x39,0xe7,0x17,0xdd,0x06,0x10
+.byte 0x0c,0x7f,0xfa,0x22,0x5d,0x88,0x35,0xc6,0xcd,0x60,0xa2,0xf0,0xfd,0xc9,0xed,0x85,0xac,0x88,0xfd,0x7d,0xc0,0x77,0x1b,0x80,0x3d,0x21,0x1e,0x8e,0x4d,0xdb,0x20,0xe2,0x38,0xad,0xd4,0xb5,0x2b,0x2b,0x31,0xbc,0x7b,0x02,0xa2,0x25,0x50,0xc0,0x01,0x20,0x76,0x6f,0x98,0x0b,0x3d,0x46,0xed,0xbb,0x2b,0x39,0x74,0x30,0xce,0x3e,0x6d,0x91
+.byte 0xa1,0x89,0x83,0xde,0x69,0x93,0x1a,0x14,0xa1,0xb0,0xaa,0x80,0xb0,0x1c,0x02,0x3f,0x13,0x9a,0x15,0x7f,0xb4,0x02,0x8f,0x30,0x0b,0xee,0xd9,0x72,0xcb,0x74,0x95,0x4a,0x39,0xb3,0x4e,0x78,0x12,0xb1,0x77,0x89,0xc0,0xaf,0x17,0xfd,0xc1,0x68,0x65,0xd1,0x08,0xae,0x56,0x5c,0xe0,0xe7,0x6f,0xb3,0x1e,0x10,0xce,0xd8,0xdf,0xee,0x67,0xad
+.byte 0xd8,0x08,0xe0,0x79,0x36,0xe4,0x57,0x1c,0x45,0x22,0xa7,0x44,0xa8,0x12,0x37,0x92,0x85,0x9f,0x3a,0x48,0xd0,0xfd,0xb3,0x40,0x20,0x10,0xed,0x11,0xe0,0x9a,0xa6,0x09,0x5b,0xe9,0x21,0x95,0xe1,0x45,0x19,0x39,0xcc,0x85,0x5f,0xa5,0x6b,0x46,0x37,0xe1,0xa1,0x17,0x3f,0xb6,0xe9,0xb0,0x81,0x25,0xf6,0xd1,0xb8,0x22,0x5a,0x27,0x48,0x83
+.byte 0x01,0x36,0xd4,0xb8,0xc0,0x9f,0x37,0x52,0x22,0xd2,0x69,0x7b,0x3d,0xfb,0x31,0xc1,0xa3,0xb4,0xa1,0x1d,0x0e,0x24,0x9a,0xda,0x02,0x15,0x4b,0x46,0x24,0x0e,0xb1,0x79,0xc2,0x5b,0x01,0x60,0x4a,0x24,0x8a,0xbb,0x70,0xaa,0xf4,0x45,0xc1,0x0d,0x04,0x26,0x3f,0x74,0xbd,0xdd,0x33,0xaa,0xd6,0x62,0x56,0xb1,0xe7,0x2d,0x7b,0x66,0xa2,0x40
+.byte 0xb4,0xe4,0xbd,0x8e,0x35,0xba,0xf1,0x2f,0x59,0xa7,0x01,0x6d,0x5a,0xa7,0xa6,0x3b,0x82,0xa3,0xb4,0x54,0x51,0x33,0x6b,0xfb,0x78,0x4a,0x74,0x88,0x7f,0x55,0xea,0x08,0x8e,0x19,0x78,0xbc,0x80,0x19,0x2f,0x41,0x97,0x20,0xa0,0x9e,0xbf,0x44,0xae,0x2e,0x26,0x66,0xe3,0x25,0xa0,0x92,0xa9,0xbe,0x8c,0x0d,0x96,0xec,0x93,0x99,0xe2,0xe7
+.byte 0x81,0xd5,0x10,0x62,0x3a,0x97,0x38,0x51,0x36,0x11,0x00,0xe0,0xc1,0x3a,0xc5,0xd4,0xa5,0x19,0xf4,0x82,0x66,0x0c,0xf9,0xb3,0x04,0x3e,0x57,0xc3,0x43,0xab,0xc6,0x52,0x95,0x8f,0xd3,0xf1,0xde,0xd9,0x57,0x6d,0x32,0x4f,0xc7,0x8c,0x1b,0x7a,0x53,0x6a,0xcf,0x56,0xea,0x61,0xb4,0xe5,0x64,0x2d,0x02,0x26,0x5b,0xcf,0x1c,0xc7,0x37,0xc3
+.byte 0x41,0xd2,0x1b,0x6c,0x5b,0x47,0xb8,0x73,0x89,0xfe,0x0e,0x7a,0x35,0x05,0xfc,0xea,0x6a,0x34,0x74,0x69,0xf0,0x12,0x29,0xa9,0x33,0xce,0x93,0x15,0xa0,0x68,0xb3,0x46,0x43,0xdb,0x8d,0xfa,0xef,0x93,0x66,0x72,0x18,0xae,0xe4,0xab,0xf4,0x8a,0xd1,0xb5,0x42,0xbd,0x2d,0xda,0xcb,0xf6,0x44,0x25,0xb1,0x01,0x8a,0xff,0xd5,0x34,0x16,0xec
+.byte 0x7e,0x38,0x7b,0x50,0x41,0x61,0xf9,0xdf,0x4c,0x3e,0x02,0xd6,0xc3,0xce,0x19,0x9f,0x12,0x45,0x0c,0x99,0xb1,0xd9,0xeb,0xb9,0xe3,0xd5,0xb6,0x2b,0x25,0x8c,0x0b,0x04,0xf8,0x8d,0x41,0x41,0x3d,0x39,0x1b,0x7f,0x88,0xa7,0x8f,0x61,0x30,0xfe,0x67,0x75,0x35,0xd1,0x41,0x90,0xda,0x73,0x80,0xcf,0xc9,0xf6,0x44,0x00,0x67,0xcd,0xca,0xaf
+.byte 0x6d,0x84,0x39,0x9a,0xb2,0xbb,0xfc,0xac,0x9b,0xb2,0x95,0x2f,0xc9,0x06,0x3a,0xa4,0x7b,0x9a,0x25,0xc6,0xe5,0xdb,0x7a,0xc6,0x8b,0x84,0x6a,0xb7,0x1e,0x22,0xaa,0x10,0x96,0xd3,0x55,0x50,0xa2,0x02,0x04,0x69,0x92,0xd7,0x6b,0x1f,0x9b,0x45,0x07,0x71,0xda,0xdc,0x76,0xc5,0xb8,0x34,0xa2,0x32,0x33,0x16,0x2e,0xb0,0x2a,0x90,0x43,0x40
+.byte 0x92,0x77,0x74,0x4e,0xdc,0xb4,0xe2,0x7d,0xc1,0x57,0xaf,0xf4,0x2c,0x20,0x65,0x77,0x88,0xc9,0x6e,0x69,0x38,0xc8,0x19,0x95,0x32,0x54,0x59,0x7f,0x37,0xd7,0x3c,0x07,0x05,0x87,0x2b,0xf9,0x58,0x74,0xc7,0x61,0x13,0x3d,0xc2,0xd9,0xec,0x3b,0x36,0x9f,0x8e,0xae,0x52,0xdd,0x5c,0xaa,0x29,0x6b,0x31,0x34,0x48,0x61,0x34,0x62,0x56,0xce
+.byte 0x25,0xa8,0xc0,0x62,0xf5,0x35,0x58,0x4d,0x8e,0x61,0xd4,0xae,0x25,0x50,0xee,0x45,0xdd,0x14,0x7d,0x46,0x81,0x47,0xc3,0x3f,0x3f,0x81,0xdb,0x9a,0x59,0x56,0x4f,0x45,0xed,0x9c,0xe2,0xfc,0x96,0xff,0x5d,0x37,0x70,0xad,0xd2,0xeb,0xd9,0x2d,0x2a,0xaf,0xb9,0x16,0x4a,0x79,0x5d,0x76,0xb5,0x8f,0x74,0x19,0x6f,0x74,0x7d,0x4a,0xee,0x83
+.byte 0xa5,0x81,0xf3,0xd5,0xa0,0x43,0x5e,0x46,0xba,0xbe,0x49,0xa8,0xce,0x72,0x36,0x32,0xcd,0x8c,0x9b,0xa0,0xf9,0x5d,0xb7,0xb9,0xc7,0x8c,0xb2,0x59,0xb4,0x44,0xc1,0x90,0x53,0x92,0xd2,0xa8,0x4c,0xf9,0x35,0x40,0x32,0xd1,0xf0,0x2f,0xcb,0x6a,0x0b,0xe0,0xbe,0x34,0xc9,0x82,0x18,0x8d,0xfb,0xfc,0x50,0x8d,0x67,0xd5,0x86,0xd4,0xf1,0xb1
+.byte 0xaa,0x2f,0x9c,0xbc,0x52,0xbb,0x9f,0x17,0x1c,0x74,0x1d,0xdf,0x2d,0x1a,0x94,0x43,0x9b,0x80,0xb9,0x48,0xa3,0xaf,0x4b,0x30,0x0d,0xd9,0x3f,0x11,0x48,0x79,0x60,0xcc,0x25,0x6a,0xdb,0x8a,0xda,0xab,0xda,0x09,0x7c,0x9c,0x4a,0xaf,0xf9,0x0d,0xfb,0x7a,0x92,0x61,0xa5,0x17,0xf8,0x79,0x1b,0x00,0x52,0x56,0x5e,0x27,0x22,0x37,0xf4,0xbe
+.byte 0x52,0x36,0xd3,0xdc,0x9a,0x33,0xf5,0x44,0x0e,0x53,0x0b,0xf6,0x9b,0xb0,0xb6,0x11,0xe4,0xd5,0x45,0x2e,0xdc,0xdb,0x46,0x18,0x9a,0x90,0x8b,0xcc,0xfe,0xc6,0x94,0x4f,0x97,0xb9,0x42,0xb6,0xd3,0x8f,0x7c,0x20,0xd1,0xa8,0xe6,0x85,0xce,0x65,0xeb,0x95,0x38,0x11,0x5c,0x1a,0x9d,0x34,0x25,0xc2,0xf0,0x33,0xbb,0x2c,0xc9,0x8d,0x0a,0x7a
+.byte 0xb1,0x90,0x9f,0x24,0xed,0x35,0x3c,0x7e,0x71,0x82,0x12,0x3a,0x79,0x29,0xc8,0xa7,0x3e,0xa2,0x4e,0x50,0x03,0x94,0x7a,0x94,0xb7,0x2b,0x61,0x95,0x3d,0x5e,0x60,0x1c,0x68,0x51,0x82,0x73,0xe0,0x4a,0x2a,0x48,0x26,0xda,0xa3,0x53,0x8c,0x83,0xba,0x9f,0x95,0x37,0x5e,0x68,0x54,0x19,0x21,0xf8,0x31,0xaf,0x6b,0xfc,0x3a,0x3e,0xe3,0x3f
+.byte 0xdb,0x16,0xb5,0x7e,0x13,0xf8,0xfd,0x7f,0x36,0xd6,0x8e,0x33,0xaa,0xe9,0xa4,0xa7,0xfd,0xf0,0x32,0xa6,0xdf,0xfa,0x22,0x7d,0xff,0x2a,0xe6,0x0d,0x6f,0xe2,0x21,0x54,0x6c,0x1a,0x99,0x17,0x56,0xad,0xce,0x39,0x6b,0x1a,0xe8,0x27,0x13,0x12,0x9c,0x4b,0x84,0x69,0x73,0xde,0x44,0x14,0xb2,0x7c,0x44,0x54,0x91,0x4f,0xeb,0x83,0xec,0x04
+.byte 0x73,0x85,0xb1,0xa8,0x44,0x72,0xa7,0x77,0xaf,0x0c,0xe0,0x52,0x65,0x04,0xe7,0x2a,0xee,0x0c,0x20,0x83,0x32,0x34,0x17,0x00,0x61,0xf9,0xf5,0x42,0x03,0xa4,0xb8,0x02,0x6f,0xb2,0xd3,0x65,0x51,0x2a,0x8e,0xdf,0x28,0x78,0x8a,0x8a,0x00,0xfb,0x24,0xd6,0xd5,0x86,0xaa,0xfb,0x86,0x93,0x5d,0x11,0xa4,0xf3,0xfd,0x36,0x18,0xf3,0x61,0xea
+.byte 0x33,0xa8,0x0c,0xf0,0xb4,0x68,0xee,0xd3,0xe3,0x4f,0x22,0x24,0xde,0x1f,0x29,0x84,0x8b,0x5b,0x73,0x15,0xd6,0x62,0xa3,0x71,0x7d,0xf0,0x65,0x36,0xca,0x68,0x8a,0x6d,0x61,0x9c,0x0d,0x53,0xdd,0xf4,0x12,0xb3,0x5f,0xf0,0xb1,0x86,0xd6,0xe2,0xd6,0x80,0x4a,0x01,0x09,0x99,0x65,0xdb,0xae,0xe6,0xfc,0x68,0x5b,0xf9,0x10,0x99,0x8b,0x9f
+.byte 0x08,0x52,0x09,0xae,0x59,0x4d,0x6c,0xf9,0x91,0x2b,0x57,0xea,0xf0,0xa3,0xdb,0xb8,0x99,0x29,0x2f,0xab,0x95,0x01,0x7d,0xec,0xd8,0x77,0x73,0x75,0x4f,0x88,0x44,0x69,0x76,0xc9,0x3c,0xf0,0x2d,0x7b,0x0d,0xbe,0xd4,0x88,0x0d,0xbc,0xa0,0x52,0xf4,0x2a,0xd1,0x62,0x2a,0xa9,0xe2,0x41,0x2f,0x52,0xce,0x96,0x7d,0x65,0x9b,0x74,0x82,0xde
+.byte 0x43,0x4d,0xf8,0x8e,0x77,0x1c,0x18,0xf5,0x7e,0xab,0x94,0x3e,0xe7,0x90,0x2b,0xa1,0x16,0x00,0x7f,0x9c,0x9d,0x86,0xd1,0x74,0x7e,0xf7,0xbd,0x5a,0xa7,0x2f,0x0f,0xb0,0x5c,0xfc,0xfb,0x59,0x00,0xf3,0x84,0x09,0x77,0x66,0x17,0xf6,0x5d,0x0e,0xe2,0xe2,0xd4,0xb3,0x9e,0x79,0x88,0x66,0xa5,0x8e,0x30,0xae,0xca,0x7e,0x2b,0x32,0xa2,0x89
+.byte 0xe9,0x7e,0x59,0x21,0xd5,0x99,0xc7,0x10,0xa8,0x6f,0x95,0x8d,0x84,0xb4,0xcf,0x61,0xe7,0x5c,0x09,0xf3,0xbc,0xeb,0xf6,0x0c,0x84,0x1a,0x8d,0x13,0xf8,0x49,0x22,0xeb,0x09,0x55,0xef,0x56,0x12,0x21,0xcb,0x61,0x87,0xbf,0xef,0x43,0x5b,0x82,0xa8,0xc2,0xa2,0x5e,0xad,0x54,0x9a,0xcc,0x95,0xa2,0x01,0x05,0xb2,0xbb,0x26,0xa8,0xfd,0x6b
+.byte 0x66,0x95,0x9c,0x0b,0x7b,0x23,0x32,0xff,0xdd,0x6c,0x18,0x1e,0x77,0x01,0x3c,0x82,0xaa,0x97,0x28,0x0f,0x93,0xa5,0x6c,0x85,0xe5,0x94,0x40,0xe0,0xa3,0x01,0x57,0x56,0x43,0x40,0xdd,0xa9,0xaf,0x21,0x79,0x10,0x8b,0xff,0x4b,0x51,0xe4,0xa2,0xe5,0xd7,0x0c,0xe2,0x9e,0x1e,0x38,0xdb,0x64,0xe1,0xb1,0x5b,0xe5,0x40,0xab,0xf6,0x05,0xd2
+.byte 0xba,0x85,0x78,0x61,0x2d,0x2e,0x07,0x06,0x6d,0x86,0x59,0xaa,0xd9,0x2c,0xfb,0x83,0x34,0xd0,0x2d,0x1d,0xad,0x5f,0xe4,0xac,0x05,0x46,0x3a,0x7b,0xd9,0xef,0x9f,0x2b,0x0c,0x18,0x21,0xf1,0x24,0x8a,0xb4,0x6e,0xd2,0x98,0x75,0x08,0x96,0x0c,0x7b,0x41,0xb7,0xf7,0x1f,0xcd,0xa8,0x1f,0x44,0xb1,0xed,0xdc,0x0e,0xcb,0x94,0xa0,0xb8,0x62
+.byte 0x67,0xdc,0x24,0xde,0x9e,0xe9,0x89,0xcd,0x92,0x7c,0x91,0x15,0xff,0xbd,0xfd,0xee,0xf8,0x29,0xd7,0xf9,0xe8,0x51,0xe7,0xc8,0x21,0xc5,0x20,0xe4,0xb8,0xa6,0xdb,0xfb,0x09,0x65,0x1c,0x3b,0x9e,0x39,0x44,0xcf,0xf5,0xc2,0x7b,0xf3,0x14,0x7d,0x69,0xf2,0xd0,0x97,0x63,0xf1,0xa7,0x81,0x56,0xfb,0xdf,0x4d,0x83,0x55,0x4f,0xde,0x50,0x7d
+.byte 0xfe,0xb0,0xc0,0xc8,0x3b,0x3d,0x78,0x74,0x58,0x74,0x5e,0xfc,0xb7,0x0d,0x9a,0x26,0x3b,0x39,0xb6,0xf7,0xe0,0xe4,0x12,0x3c,0xd6,0x88,0x1c,0x9b,0x51,0x89,0xe7,0x53,0xcd,0x24,0x2e,0x34,0xa2,0xee,0xfa,0x5a,0x87,0xe5,0x7e,0xd5,0xf2,0x2f,0x15,0x99,0x57,0x5d,0x31,0x02,0xf8,0x08,0x38,0xea,0x8c,0x30,0x21,0xb0,0xff,0x94,0x51,0xcf
+.byte 0x23,0xb7,0x02,0x5d,0xa3,0x75,0x7f,0x9d,0x66,0x49,0xe5,0xbe,0xc7,0x06,0x5e,0x1d,0xc9,0xe2,0x82,0x8a,0xc4,0x17,0x83,0x7e,0x65,0x6d,0x85,0x26,0x66,0xc0,0xf4,0xa5,0x1c,0x6e,0xba,0x32,0xfa,0x41,0x7b,0x2b,0x64,0x98,0x58,0x8c,0xce,0x2f,0xf3,0x56,0xf0,0x67,0xef,0x73,0x79,0xc4,0xc2,0x07,0xd7,0x85,0x1d,0x75,0x38,0x1e,0x15,0x82
+.byte 0x9d,0xf3,0xdd,0x3a,0x72,0xa3,0x23,0x0e,0x4a,0x1a,0x3a,0x97,0xc8,0xf1,0xf1,0x58,0x5d,0x1f,0xae,0x6d,0xc8,0x03,0xe0,0x7b,0x0f,0xf5,0x6f,0x35,0x41,0x8d,0xd5,0x03,0x85,0xdd,0xeb,0x3d,0x73,0xb1,0x93,0x35,0xc0,0x0f,0xfb,0x42,0xd4,0xf1,0x6b,0x35,0xe2,0x96,0xc5,0xd9,0xf2,0x69,0xbb,0x70,0x5e,0xf0,0x0c,0xe6,0xb5,0x81,0x94,0xc9
+.byte 0x29,0xa1,0x34,0x89,0xd9,0x9c,0x49,0x01,0x37,0x56,0x16,0x30,0x47,0x6f,0xe4,0x7c,0x5b,0xdd,0xfb,0x80,0x7f,0x0c,0x38,0x53,0x3d,0x57,0xf7,0xc4,0x80,0xf9,0x12,0x3a,0x9f,0xf9,0xb0,0xb6,0x94,0x6d,0xde,0x41,0x4e,0x30,0xac,0x1f,0x25,0x34,0xa0,0x95,0xe8,0x00,0x86,0x32,0x40,0xbb,0xc1,0x49,0x2d,0x07,0x49,0xb8,0x5f,0xcd,0x1b,0xd3
+.byte 0x0e,0x0c,0x54,0x0f,0xe4,0x20,0xe5,0xa1,0xed,0x98,0x65,0x5a,0xe7,0xce,0x68,0x9c,0x4c,0x48,0x03,0x9c,0x5b,0x68,0x4b,0x75,0x71,0x11,0x40,0x69,0xca,0x9a,0x3a,0xb2,0x3d,0x35,0x2c,0x70,0x35,0x8b,0x80,0x53,0x86,0x30,0x7d,0x4c,0xe9,0xc0,0x30,0x60,0xd0,0x06,0xbe,0xc2,0xad,0x39,0xcc,0xb2,0xec,0x90,0xcc,0xbd,0x7c,0xb5,0x57,0x20
+.byte 0x34,0x2e,0xfc,0xce,0xff,0xe3,0xd9,0xac,0xb8,0x62,0x6b,0x45,0x22,0x34,0xdf,0x8e,0x4b,0xf1,0x80,0x28,0x8d,0x0f,0xd5,0x3b,0x61,0x3e,0x91,0xa1,0xb1,0x85,0x27,0x78,0x88,0xbc,0xc4,0xb1,0xa1,0xbe,0x4f,0xc3,0xfd,0x1f,0xb9,0x30,0x31,0x2f,0xc1,0x9d,0xa3,0xb6,0x29,0xa4,0x60,0x82,0x73,0x93,0x74,0xea,0x97,0x67,0xf2,0xa3,0x97,0x50
+.byte 0x2f,0x9f,0x7b,0x23,0x18,0xb6,0xb4,0xee,0x15,0xa0,0xa4,0x07,0x1a,0xe9,0xb6,0x63,0x7e,0x88,0x40,0x57,0x86,0x79,0x6b,0x75,0xbe,0x57,0x8f,0xfe,0x0d,0xdf,0x4c,0x7f,0x39,0x9a,0x97,0xa6,0x87,0xc5,0xfd,0x52,0x77,0x36,0xc9,0x66,0x63,0xcf,0xc7,0x34,0x3b,0xf4,0x7a,0x12,0x56,0xf0,0xbc,0x7a,0x1a,0xa2,0xa2,0x51,0xb8,0xc1,0x70,0x81
+.byte 0xcf,0x1d,0xb5,0xe2,0x82,0xbb,0xfc,0xa3,0x80,0x18,0xf8,0x4b,0x76,0x9c,0xdf,0x9d,0x6c,0xf1,0xd8,0x2a,0xab,0x0c,0x12,0x02,0x29,0x09,0xfd,0x28,0xfb,0x57,0x38,0x05,0x2c,0xc5,0x67,0xd1,0xaa,0xbc,0x98,0xe6,0x22,0x78,0x06,0x4f,0x69,0x6a,0x63,0x1a,0x13,0x0b,0xa5,0xd2,0x61,0xc7,0x45,0x5b,0x21,0xab,0xbf,0x7b,0x7f,0x8c,0x2c,0xba
+.byte 0x93,0x9f,0x41,0x67,0xc4,0x5f,0x53,0xac,0x90,0x05,0x86,0xb5,0x80,0x1f,0x5b,0x35,0x4f,0x92,0xf5,0xa8,0x5f,0xfb,0x56,0xdd,0x2d,0x9b,0xea,0xcb,0x0f,0x98,0x3c,0x4e,0xf1,0xa5,0x2c,0x37,0x70,0xe3,0x5c,0xaf,0x96,0x36,0xa8,0x2a,0xec,0xe0,0x2c,0x00,0xcd,0xaf,0x03,0x1d,0x05,0x2f,0x8c,0xe7,0xfe,0x4d,0xe9,0x97,0x6d,0xe1,0xf9,0x23
+.byte 0x60,0x08,0xea,0xfb,0x27,0xc8,0xf9,0xdf,0x49,0xfe,0xd9,0x48,0x35,0x6b,0x43,0xc5,0x19,0x90,0xb1,0xf1,0xee,0x84,0x7a,0x57,0xfa,0xa5,0xd6,0xd8,0xc9,0xf0,0x8a,0xe7,0x13,0x84,0xfc,0x28,0x54,0xae,0x99,0xfd,0x91,0xbe,0x91,0x27,0x98,0x28,0xdc,0xd7,0x2e,0xc1,0x21,0xcb,0x31,0xf8,0x47,0xe6,0x77,0x6d,0xee,0x7b,0x12,0xe4,0x9e,0x9d
+.byte 0x07,0x46,0xa9,0x15,0x0b,0x3c,0xbe,0xc7,0x2d,0xe5,0xd6,0x25,0x4c,0xea,0x61,0xdc,0x18,0xb2,0x9d,0xb0,0x9a,0xff,0xa3,0x5f,0x2b,0xab,0x52,0x7d,0x1b,0xc3,0xa3,0x41,0x8f,0x5a,0x29,0xbd,0xc4,0x56,0x54,0x43,0x2d,0x61,0x07,0xed,0xd1,0x81,0x45,0xdb,0x61,0x0f,0xda,0xea,0xa6,0x1e,0xf9,0x9c,0xc0,0x8c,0xc4,0x8e,0xc7,0xca,0x38,0xe2
+.byte 0x45,0xde,0xdc,0xc5,0xc6,0xb0,0x43,0x17,0x8b,0xb1,0x58,0xd1,0x10,0x8e,0xa5,0x17,0x37,0x85,0xca,0x61,0x67,0x5c,0xd0,0x72,0x22,0x6b,0xd3,0x3b,0x53,0xbc,0xfb,0xe1,0x1e,0xa4,0x1b,0xd3,0xc3,0x8a,0x50,0x03,0x39,0xf5,0x36,0xdf,0x51,0x2e,0x05,0x4a,0xa8,0xdb,0x91,0x87,0xae,0xfe,0x3f,0x5c,0x35,0x5e,0xf9,0x8f,0x43,0x9e,0x92,0x36
+.byte 0x91,0x27,0x90,0xe8,0x7c,0xcc,0xc4,0x9c,0x13,0xbb,0x61,0x40,0xec,0x4f,0x49,0xcf,0x04,0x38,0x77,0x3b,0xb5,0xf8,0x69,0x8d,0xbb,0xb2,0x30,0x32,0x42,0x4d,0x7d,0x6c,0x56,0xdc,0xf4,0x8f,0xfc,0xb8,0x53,0xc5,0x11,0x17,0x23,0x94,0xf9,0x6d,0x6f,0xee,0xee,0x31,0xbf,0xce,0x11,0x8b,0x9e,0xd7,0xa5,0x09,0x36,0x89,0x72,0x25,0x18,0x1f
+.byte 0x13,0xa7,0xdf,0xc5,0x91,0x7e,0xd6,0x2b,0xb8,0x08,0x9c,0x12,0x83,0x21,0x97,0x3d,0xad,0xac,0x1c,0x54,0xf3,0x65,0x04,0x2f,0x09,0xd1,0xd2,0xe5,0xce,0x24,0xb1,0xd9,0xe4,0x38,0x1f,0xb4,0xce,0xea,0x27,0x7f,0x5f,0x16,0x52,0xa4,0x2f,0x2f,0xaf,0x91,0xec,0x7a,0x21,0xf7,0xa1,0x38,0x78,0x78,0xc5,0xa9,0x94,0x63,0x87,0xf8,0x95,0x9e
+.byte 0xf9,0x82,0x98,0x6d,0x9d,0x48,0x80,0xaa,0x7a,0x36,0xf9,0x5f,0xfb,0x39,0x3d,0xae,0xbc,0xcd,0xfc,0x67,0x46,0x07,0x7e,0xdf,0xef,0xff,0x8d,0x67,0xe7,0xd9,0x60,0x90,0x7b,0x49,0x10,0x65,0x3a,0x60,0x87,0x7a,0xed,0x9a,0x44,0x48,0x81,0xcc,0xad,0xe4,0x6a,0x62,0xf8,0x02,0x6f,0x41,0x8a,0x8d,0x44,0x28,0x1a,0xb8,0x52,0x60,0x4b,0x3f
+.byte 0xfc,0xdd,0x33,0xad,0x14,0xb1,0x34,0x63,0x1f,0xdc,0xeb,0x9a,0x3f,0x99,0x82,0x28,0x36,0x6f,0x8e,0xd7,0x39,0x2e,0xc0,0x37,0xfb,0xad,0x57,0x6c,0x82,0x1a,0xc6,0xe4,0x4b,0xca,0x00,0x68,0x57,0x34,0xf0,0x57,0x6a,0xcb,0x50,0x5d,0x8d,0xfa,0xcd,0x89,0x41,0x91,0x23,0x98,0x1f,0x4f,0x18,0xb6,0xd2,0x9d,0xde,0x2f,0x5c,0xe6,0x08,0x76
+.byte 0x97,0xba,0x24,0x4e,0x84,0xd7,0xeb,0x80,0xde,0xec,0xee,0x51,0x5a,0x0e,0x5f,0xb7,0x37,0xda,0xa5,0x94,0x2b,0x6d,0x73,0xb7,0x6c,0x22,0x95,0x3a,0xaa,0x5c,0x6f,0x89,0x90,0xec,0xb3,0x31,0x00,0x37,0x28,0x18,0xbb,0x98,0x23,0xfc,0x3e,0x21,0x7c,0xaa,0x44,0x54,0x7b,0xe6,0xa0,0x17,0x58,0xef,0x11,0x3f,0x48,0xb8,0xa8,0x15,0x4a,0x92
+.byte 0xa9,0x39,0xe2,0xa6,0x38,0x03,0xa6,0xd3,0x79,0x8b,0x38,0x06,0xaf,0x4b,0xd4,0xab,0x0a,0x13,0xff,0x2d,0xfa,0xab,0x4b,0x64,0x9e,0xb0,0x3d,0xba,0x18,0x01,0xfd,0xc3,0x6a,0x6f,0x21,0x9c,0xf5,0x2f,0xab,0x2d,0x42,0x12,0xc9,0x72,0xde,0x83,0x42,0x6a,0xf0,0xd4,0x96,0x73,0xf1,0x93,0xa3,0x2d,0x9b,0xb4,0x94,0x51,0x0c,0x6e,0x8e,0xf0
+.byte 0x5e,0xbf,0x98,0xbf,0x08,0x0f,0xd8,0x6c,0x65,0x4e,0xb5,0x47,0xeb,0x7c,0x1b,0x73,0xe0,0xe6,0x2c,0x03,0xd2,0x2a,0x32,0xff,0xa7,0x03,0x6d,0x38,0x47,0x56,0x4b,0x25,0x0b,0x39,0x73,0x87,0x4b,0xa5,0x12,0x79,0x79,0xf3,0x88,0x37,0xe2,0x4f,0xb8,0xbf,0x70,0x0e,0xf7,0x8c,0xe6,0xa3,0xbc,0x35,0x10,0xcd,0x72,0x56,0xd6,0x83,0xc1,0x0b
+.byte 0x5b,0xf3,0xa8,0x74,0xc7,0xb9,0x84,0xc8,0x6c,0xff,0x66,0xad,0x95,0x6f,0xbc,0x82,0x84,0x2a,0x11,0x40,0xf9,0xa8,0x3f,0x05,0xf9,0xab,0x19,0x55,0xce,0x80,0x90,0x65,0x49,0x3d,0xe1,0x54,0x2c,0x1a,0xdb,0xf3,0xaa,0x2f,0xeb,0xf5,0x10,0x1f,0x8c,0x35,0x46,0x68,0xb1,0x4c,0x52,0xe7,0xe9,0x58,0x78,0x33,0xfd,0xc6,0x13,0x0e,0x69,0xae
+.byte 0xf4,0x1a,0x8a,0x77,0x8f,0xcc,0x98,0x74,0x88,0x20,0x84,0x5b,0x83,0x54,0xa9,0xee,0xc2,0x0f,0x8a,0x46,0xb1,0xc7,0xfb,0xfd,0xf2,0x2c,0xaf,0xfa,0x72,0x34,0x7a,0x79,0x50,0x10,0xc6,0x04,0xfd,0x0a,0x1e,0x4a,0xb5,0xf5,0xe7,0x4d,0x98,0x80,0x5d,0x0b,0x81,0x23,0xc3,0x6e,0xbf,0xc8,0xcd,0x35,0x96,0x5a,0x58,0xec,0xef,0x6a,0x8d,0x48
+.byte 0xda,0x48,0xbb,0x8f,0xcc,0x1f,0x86,0xff,0x7a,0x27,0xef,0xe6,0xb7,0xc7,0x2a,0x47,0x8d,0x6c,0x4a,0xc6,0x0a,0x32,0x67,0x1d,0x2f,0x83,0x3d,0x46,0x41,0x46,0x1c,0x75,0x7b,0x29,0x89,0xa2,0x65,0x9b,0x53,0x3d,0xd9,0x90,0x83,0xce,0xab,0x07,0xbb,0x46,0x61,0xb1,0x54,0xbd,0xc9,0x98,0xf7,0x96,0x76,0x03,0xdc,0x1f,0x1b,0xf2,0x5c,0x07
+.byte 0xdd,0x24,0x94,0x72,0x1e,0x94,0xb1,0x14,0x0b,0x40,0x77,0xde,0x3d,0x3f,0x1c,0xf0,0x8f,0xa4,0xcb,0x34,0xb5,0x2b,0x72,0x53,0x78,0xf3,0x3f,0x8e,0x47,0x30,0xb2,0x7e,0x73,0x3f,0x9a,0xef,0x19,0xb1,0xef,0x82,0x99,0xd4,0x17,0x60,0x94,0xf6,0x15,0x75,0x50,0x1f,0xb3,0xdd,0xae,0x1f,0xf8,0x63,0x9a,0x30,0x2c,0xf0,0xdd,0xbf,0x49,0x70
+.byte 0xd7,0x86,0x4a,0x5c,0x46,0x10,0x48,0x46,0x02,0x18,0xa4,0x39,0xb6,0x75,0x11,0x21,0xae,0x62,0x64,0xd8,0x85,0xc8,0xda,0xd2,0xd6,0x69,0xcc,0x37,0x57,0x49,0x73,0x1a,0x10,0x7b,0xd7,0x58,0xdd,0x0b,0xf3,0x16,0xe7,0x62,0x2c,0x32,0x92,0x0e,0x70,0x6f,0x77,0x74,0x0d,0xff,0xc2,0x8d,0x3b,0x3f,0x29,0x28,0x8f,0x88,0xb8,0x02,0x5b,0x3a
+.byte 0x8b,0x65,0x89,0x92,0x2f,0xc7,0x30,0x73,0xc3,0x20,0xbc,0xa4,0xe4,0x5e,0xea,0xf8,0x21,0xb6,0xc5,0x47,0x56,0x35,0x8f,0xf6,0xd5,0xdd,0x77,0x1d,0xdf,0xd0,0x27,0xa3,0x04,0xb9,0xd0,0xc4,0x28,0x16,0xa5,0xaf,0x47,0x55,0x85,0x93,0x38,0xf4,0xac,0x13,0x30,0x7d,0x77,0x1f,0x3d,0xd5,0xd7,0x22,0xbe,0xe2,0x4e,0x6d,0x4b,0x0e,0xbe,0x1d
+.byte 0x43,0x79,0x34,0x95,0x6f,0x38,0xa1,0xb3,0xa0,0xed,0xf6,0x17,0xf4,0x24,0x70,0x26,0x18,0x3e,0x1c,0xde,0xdc,0xa9,0x67,0x12,0xd3,0xc8,0xd7,0x70,0x13,0xa5,0xb3,0x25,0xe1,0x0a,0xe9,0xf6,0x4e,0x56,0x82,0x17,0xdc,0xbc,0x96,0x2f,0x59,0x03,0x9b,0xf4,0xc3,0x66,0xd2,0x90,0x95,0x1d,0xe0,0x99,0xfb,0xd8,0xa8,0x14,0xc7,0xa6,0x12,0x6b
+.byte 0x08,0x6a,0xc8,0x0f,0x34,0x2a,0xb6,0xc4,0x9a,0xcd,0x61,0xf7,0x61,0xa3,0x59,0x29,0x11,0x30,0x76,0xb5,0x97,0xbc,0x2f,0x87,0xd8,0x12,0xb3,0x1d,0x99,0x8d,0x5d,0x57,0x0c,0xda,0xb0,0x9f,0x51,0x1a,0xb5,0xc6,0x94,0xc3,0xe9,0x5a,0x72,0x0c,0x37,0x76,0xb6,0x3c,0x00,0x02,0x69,0xad,0x8e,0x66,0x8b,0x5c,0x13,0x48,0xb7,0x9e,0xc5,0x7e
+.byte 0xe0,0x35,0x07,0xd2,0x04,0x9c,0x35,0x95,0x8b,0x55,0x87,0x03,0x32,0x36,0xeb,0x11,0x88,0x54,0x8d,0x3e,0x88,0x46,0xc2,0xfe,0x24,0xa4,0x4b,0x92,0x19,0x44,0x6c,0xc9,0x69,0x32,0x22,0x95,0x5b,0xda,0x58,0xa4,0x00,0x33,0x83,0x2d,0xa4,0x17,0x2e,0x00,0x4d,0x9a,0x7d,0xef,0x04,0xa8,0x8b,0xf2,0x7c,0xb9,0xdb,0x54,0xcf,0x63,0x14,0x52
+.byte 0x5b,0x79,0xf6,0x89,0x5c,0xfa,0x8a,0x85,0x88,0x7f,0xca,0xed,0xfb,0x62,0xbc,0x1d,0x0d,0x90,0x51,0x27,0x45,0x74,0xa0,0x55,0xfc,0x60,0xea,0xef,0x6e,0x40,0xeb,0x0b,0x61,0x45,0x44,0xee,0xb6,0x20,0x4c,0xe1,0x08,0x62,0x29,0xdd,0xd0,0xa1,0xd5,0x7f,0x42,0xb9,0x0f,0x12,0xef,0xfb,0x13,0xa2,0xf1,0x85,0xaa,0x56,0x18,0x6c,0x70,0x7a
+.byte 0x4d,0x52,0x76,0xce,0xa9,0xed,0x0a,0xcc,0x55,0xf0,0x01,0x99,0x44,0xe9,0xc4,0x74,0x33,0x2a,0xce,0x53,0xf3,0x4f,0x8f,0x1c,0x67,0x39,0x2b,0x0e,0x46,0xe2,0x49,0x06,0x52,0xbf,0xc4,0x3f,0x93,0x84,0x46,0x0a,0x9b,0xcb,0x1d,0xa5,0x66,0x9c,0x3e,0x3d,0xd1,0x92,0xda,0xe2,0x11,0x5b,0x89,0x7a,0xc4,0x33,0xba,0xa9,0x19,0xfd,0x3c,0xe3
+.byte 0xf0,0xa0,0x9b,0x83,0x50,0xce,0xa9,0x62,0xe3,0x85,0xc6,0xc4,0xe5,0x22,0xbb,0x1a,0x8e,0x04,0xb5,0x4d,0xca,0x18,0x7d,0xb0,0x99,0x50,0x78,0x88,0x69,0x43,0xe0,0xfd,0x90,0xa6,0xbf,0xdc,0xe3,0x03,0xf2,0x5d,0xa1,0xa2,0x88,0xc7,0xab,0xa9,0xc2,0xda,0x3f,0xff,0x79,0xa6,0x07,0xfd,0xc4,0xb1,0xfb,0x47,0x3d,0x75,0x82,0x26,0x52,0x85
+.byte 0x3f,0xf9,0xc9,0x85,0x46,0x24,0xe9,0x0f,0x96,0x8c,0xbb,0x02,0x83,0x60,0x69,0x49,0x8c,0x38,0xd1,0x4e,0xd0,0x63,0x2c,0xb6,0x12,0xb2,0x8e,0x4b,0xd3,0xe3,0xdf,0x20,0x00,0x99,0xf1,0x06,0x93,0xbf,0x27,0x42,0x8b,0xe3,0x8d,0x4c,0x3b,0x05,0x62,0x64,0x21,0xb1,0xfe,0xce,0x08,0xd2,0x23,0x69,0x11,0x74,0x31,0x3a,0x90,0x10,0x07,0x1a
+.byte 0xd5,0xf5,0xc2,0x09,0x61,0x67,0x65,0x99,0x3a,0xf3,0x9e,0x4a,0xd8,0xa1,0xb2,0x50,0xf4,0x07,0xf0,0x7b,0x89,0x6d,0x4d,0x6a,0xd4,0x54,0xb9,0x3c,0xd5,0x4e,0x1c,0x12,0x0f,0x19,0x92,0x97,0x21,0x65,0x83,0x33,0x20,0x92,0x95,0xd4,0x0e,0x78,0xf4,0x92,0x16,0x36,0xd8,0x1b,0xd8,0xbf,0x41,0xe4,0xfb,0xb9,0x81,0x26,0x72,0x7e,0x1b,0x58
+.byte 0x05,0x45,0x97,0x66,0xf2,0x23,0x16,0xca,0x4e,0x95,0xc2,0x6c,0x60,0x84,0x5f,0x77,0x82,0x44,0x0e,0xf7,0x30,0xaa,0x51,0xa9,0x85,0x8b,0x03,0xfc,0x3d,0x6d,0x66,0x91,0x37,0xa5,0x1c,0xf8,0xcf,0x9d,0xd8,0xcd,0x8c,0xa1,0x29,0xbd,0xb5,0x4f,0x47,0xba,0xd1,0x55,0x3b,0x4e,0xc9,0xce,0x4c,0xcf,0x2e,0x19,0xa0,0x95,0xe6,0xcb,0x36,0x97
+.byte 0x3e,0x23,0xbe,0x09,0xfd,0x38,0x47,0x00,0x03,0xec,0x49,0xbb,0x49,0x1f,0x45,0x84,0x0f,0x1e,0x74,0xab,0xc9,0x07,0x00,0x04,0x70,0xe9,0xbd,0x61,0xb1,0x92,0xee,0x67,0x9a,0x5e,0x90,0xdc,0xe7,0x99,0x36,0xd0,0x58,0x15,0xe5,0x15,0xa2,0x1d,0x61,0x18,0x39,0x5f,0x6c,0xc7,0xbe,0xd0,0x23,0x1e,0x41,0xc8,0xaa,0x8e,0xbf,0xb8,0xdb,0x90
+.byte 0x8c,0x60,0x07,0x1e,0xe9,0x6c,0xe4,0xde,0xec,0x73,0x34,0x94,0x54,0xa4,0x6b,0x49,0xcf,0x87,0xb5,0x88,0x98,0xe6,0x2c,0xce,0xb7,0x76,0xa5,0x29,0xf1,0x29,0x50,0xc5,0x9e,0x13,0xe4,0x61,0x6a,0x54,0xb2,0x26,0xfa,0xfa,0x4a,0x41,0x3b,0x0a,0xf5,0x9a,0x60,0xbb,0xfc,0x1e,0x5d,0x21,0x7e,0x91,0x51,0xd6,0x5e,0x92,0xf9,0x21,0x80,0xa8
+.byte 0x35,0xc0,0xbb,0x7a,0xeb,0x75,0xb4,0xa3,0xd3,0x8d,0xaf,0x07,0x53,0x65,0x36,0x11,0xf9,0xb6,0x69,0x29,0x1e,0x5d,0x8f,0x57,0x5d,0xed,0x42,0xf9,0xd5,0xf6,0xc3,0x1e,0x29,0xc4,0x49,0x04,0xe4,0xfb,0xbf,0x9b,0x4a,0x7b,0xdd,0x57,0x51,0xfe,0xc4,0xd1,0xd9,0xe9,0x8f,0x94,0x78,0xbc,0x5c,0xeb,0xb6,0xbc,0x51,0xb0,0x82,0x87,0x47,0xb4
+.byte 0xf7,0xf9,0x02,0xd7,0xac,0x23,0xc0,0xe5,0x9a,0xc3,0x2f,0xd2,0xb8,0xb2,0x62,0xb9,0xdb,0x49,0x85,0x77,0x92,0xa6,0xe5,0x24,0x43,0x4d,0x0d,0x67,0x94,0x01,0x29,0xd6,0x2e,0xee,0xd9,0x2e,0x97,0x0e,0x20,0x7f,0x84,0x19,0x3c,0x3a,0x6f,0xa5,0xb0,0x8b,0x8f,0x8d,0x96,0xbb,0x76,0x61,0x97,0xc2,0x65,0x83,0xd8,0xda,0xab,0x42,0xfa,0xe5
+.byte 0x1e,0x42,0x93,0xa7,0x66,0x03,0x06,0x3b,0xbe,0xb8,0xae,0x71,0xee,0xdb,0x5d,0xdf,0x40,0x64,0x17,0x17,0x2e,0x03,0xca,0x37,0x2a,0x71,0x92,0x0a,0x01,0xa3,0x0f,0x0b,0x09,0xf2,0x0e,0x4b,0x4d,0x18,0xf3,0xc4,0xf2,0x51,0x7b,0x53,0x30,0xab,0x24,0xa2,0x47,0x38,0xc9,0x2c,0xdf,0x0d,0x32,0x3e,0x3f,0x57,0x2d,0xfc,0x44,0x19,0x64,0x8b
+.byte 0xe9,0x9a,0xc2,0xf2,0xf6,0x2d,0x30,0x0c,0x0f,0xc3,0xc3,0xfe,0xc2,0xd1,0xbc,0xe0,0xbf,0xaf,0xeb,0x40,0x64,0x28,0xe2,0xd9,0x3c,0x7e,0x24,0x94,0x8f,0xe8,0x54,0x8b,0x26,0x6b,0xe1,0x4e,0x44,0x5a,0x7d,0x7b,0x12,0x36,0x2c,0x12,0xad,0x26,0xbc,0xa7,0xa3,0x2b,0x25,0xb9,0xde,0xe6,0x64,0x2d,0xab,0x7f,0x15,0x22,0x51,0x26,0x1c,0x15
+.byte 0x5d,0x13,0x18,0x93,0xc1,0x19,0x65,0xca,0xf3,0x8b,0xe0,0xcf,0x8c,0x43,0xe9,0xfd,0xa1,0xbd,0xe9,0xde,0x78,0x26,0xcb,0x7c,0xdc,0x68,0x06,0x98,0xf6,0x90,0x44,0x40,0xf0,0x5e,0xe1,0x16,0xf5,0x5d,0x4d,0x9b,0x85,0xe6,0x26,0xbd,0xab,0xcc,0x46,0x62,0x18,0x51,0xd5,0x3c,0x9f,0x6e,0xfa,0xe7,0x94,0xfc,0xc2,0x1a,0x9d,0x63,0x2c,0xdc
+.byte 0xc3,0x89,0x67,0x94,0x37,0x58,0x0d,0x13,0xb8,0xdf,0x41,0x3d,0x70,0x78,0x1e,0x61,0x75,0x77,0xcc,0xbf,0x5f,0xa8,0xd3,0x89,0xcc,0xd3,0x40,0x4e,0x65,0xbd,0xce,0x3c,0xf0,0x5a,0x8f,0xe2,0xe1,0x24,0xaa,0xed,0x0f,0xd1,0x03,0x0d,0xf5,0x36,0x98,0xcd,0xa5,0x77,0x40,0x24,0x0a,0x82,0x68,0x79,0x82,0x38,0x68,0x6f,0x2b,0x0b,0xce,0x0f
+.byte 0xcd,0x0f,0xba,0xdb,0xb5,0x22,0x38,0xd2,0xb0,0x9f,0x0f,0x08,0x0d,0xd8,0x5e,0xa7,0xd0,0xa9,0x39,0x66,0x4c,0x46,0xce,0x2a,0xc3,0x67,0x8c,0x91,0xdc,0xf1,0xc0,0x3a,0x58,0x50,0x1f,0xb0,0xa4,0x4d,0xbf,0x99,0x57,0xcf,0xae,0xb2,0xaf,0x6a,0x42,0xd2,0x7f,0x85,0x8c,0x40,0xc6,0x9a,0x93,0x57,0x54,0xf5,0xb4,0x83,0x59,0xb5,0x19,0x52
+.byte 0x7c,0x8b,0x76,0xee,0x35,0x90,0xbf,0xbe,0x65,0x58,0x3b,0x25,0x52,0x18,0xd8,0x7f,0x1f,0xe6,0x70,0xce,0x56,0x1a,0x45,0xa0,0x81,0xee,0x95,0x6f,0x55,0x43,0xaa,0x6e,0x87,0xa9,0xab,0x7d,0xe9,0xa1,0xa3,0x63,0xe7,0x1b,0x6b,0xa6,0x2c,0xe5,0x4a,0xb2,0x1e,0x73,0x5e,0xb5,0xae,0x83,0xe6,0x54,0x0b,0xc5,0x6b,0xb6,0xc4,0x73,0x62,0x1a
+.byte 0xbf,0x1a,0x65,0xa2,0x5e,0x3a,0x45,0xd9,0xba,0x5b,0xef,0xf7,0x13,0x0c,0x7c,0x68,0xa1,0x98,0x71,0xb7,0x39,0x7c,0xbc,0x69,0xdb,0xd4,0xac,0x3f,0x82,0x63,0x9b,0x71,0x25,0x3a,0x06,0x73,0x60,0x71,0xc3,0x30,0xd3,0x96,0x02,0x4b,0x46,0xbd,0xd4,0x6e,0xc6,0x29,0xcc,0xd0,0xe1,0x0b,0x66,0x62,0xea,0x29,0xc7,0xcf,0x35,0x9e,0x2f,0x1f
+.byte 0xa0,0xfc,0x8c,0x4a,0x83,0x8e,0x3b,0xf5,0x7a,0x6f,0x52,0xaf,0x99,0x9c,0x86,0xab,0xe5,0x1b,0x82,0xb3,0x18,0x35,0x77,0x9b,0xa3,0x94,0xc8,0x39,0x30,0x3f,0xad,0xa9,0x0f,0x93,0xb8,0xc8,0xed,0x04,0xf2,0x0b,0x9a,0xb1,0xd1,0xc9,0x9e,0x40,0x4f,0x71,0x21,0x63,0x2a,0x05,0x26,0x53,0xa3,0x3f,0x43,0xe4,0xf8,0x7c,0x2f,0xa3,0x5a,0x6e
+.byte 0xc1,0x40,0xa8,0x4d,0xbc,0x03,0xae,0xe9,0x36,0xb6,0x37,0xdc,0x5f,0xef,0xb0,0x35,0x33,0xdf,0x33,0x71,0xaf,0x80,0xf2,0x69,0xd9,0xb5,0xfc,0xff,0xd2,0x5b,0x6a,0xeb,0xdc,0xe0,0x26,0x43,0x38,0x7b,0x24,0xb2,0x79,0x53,0x52,0x57,0xc4,0x1f,0x6d,0xc9,0x50,0xf2,0x63,0x9d,0xc1,0x22,0x5f,0x11,0x82,0x38,0xdb,0xd3,0xb4,0x1d,0x10,0x72
+.byte 0x9e,0x4d,0x03,0x30,0xba,0x5e,0xe9,0x8c,0x21,0x12,0xe6,0x3a,0xd6,0x4c,0x18,0xa4,0x27,0xc9,0xf5,0x50,0xbd,0xbe,0xf0,0x86,0xd8,0x00,0x56,0xf0,0x10,0x81,0xec,0xeb,0xfc,0x5b,0x29,0x88,0xff,0x73,0x60,0x6b,0xf5,0x8c,0x0b,0x30,0x04,0x53,0x85,0x61,0x0c,0xfc,0xff,0x8f,0x21,0xd2,0xa1,0xcb,0xf7,0x90,0x53,0x3b,0xf4,0xf0,0x2c,0x7d
+.byte 0xb6,0x84,0xe7,0x4c,0x88,0xea,0x4f,0xdf,0xff,0x0f,0x5d,0x0f,0xd3,0x2d,0x4f,0x7e,0xdc,0xd1,0x22,0x71,0x0d,0xae,0xa8,0xcf,0x05,0x7b,0xfc,0xfe,0x87,0x40,0xa5,0xe8,0xfd,0x3f,0xdb,0x2f,0x00,0x21,0xb9,0x70,0x02,0x2c,0x96,0x24,0xaf,0x35,0xe2,0x87,0xcb,0x50,0xcf,0x7e,0xfa,0xaf,0x39,0x82,0x0c,0xd5,0xa6,0x3f,0x9c,0x77,0x60,0x16
+.byte 0xbf,0x42,0xcc,0x97,0xd1,0x19,0x0d,0x8a,0x50,0x98,0x7d,0x19,0x7b,0x40,0x1c,0x22,0xde,0x50,0x90,0x32,0x9a,0x3d,0x07,0x35,0xc0,0x48,0x4c,0x0a,0xcd,0x91,0xab,0xf7,0xf3,0x06,0x77,0x80,0x96,0x7b,0x59,0x33,0xe6,0xbf,0x93,0xb8,0x59,0xd0,0x3a,0x1f,0xcc,0xe7,0x1d,0xd4,0xb5,0x58,0xee,0xe7,0x95,0xfa,0x75,0xdb,0x37,0x74,0xb0,0x7d
+.byte 0x4d,0xee,0xef,0x20,0x13,0xe5,0x82,0x07,0x8e,0xdd,0x57,0x75,0x33,0x56,0xc4,0x80,0xb0,0x06,0x9f,0x6b,0x72,0x31,0xcf,0xac,0x5f,0x96,0x13,0xeb,0xf4,0x34,0xb6,0x6b,0x55,0xef,0x55,0x26,0x4e,0xdb,0x6c,0x2f,0x64,0x29,0x91,0x3c,0x6d,0x29,0xd2,0x94,0xbd,0x2c,0x99,0xb9,0x97,0x76,0xee,0x7d,0xfd,0xb2,0x8d,0x14,0x4f,0x09,0x81,0xb3
+.byte 0x68,0x3e,0x79,0x28,0x56,0x50,0x3f,0x86,0x4c,0x95,0x6c,0xad,0xf6,0xc5,0x43,0x25,0xea,0xbc,0xe2,0xba,0x77,0x18,0xc6,0x82,0x65,0x73,0x38,0x90,0x9d,0xc9,0x57,0xcd,0xa2,0x7c,0xd3,0x26,0x59,0x44,0xd9,0x79,0xae,0xdd,0x6f,0xe9,0xdc,0x16,0x73,0xba,0x05,0x8a,0x40,0x9f,0xe7,0xcf,0x29,0xa4,0xdf,0x49,0x7f,0x1d,0x73,0xc7,0x8b,0x8d
+.byte 0xad,0xb5,0x3d,0x1b,0x64,0xb1,0x8f,0x78,0x06,0xbe,0xaa,0x2c,0x08,0x73,0xc7,0x2c,0xdc,0xd8,0x3f,0x9f,0x1b,0xd2,0xe1,0x4f,0x9d,0x87,0xb8,0xa9,0xdc,0xef,0xbc,0x31,0x9f,0xf7,0x84,0x09,0xe7,0xbc,0xec,0x2a,0xcb,0x3b,0x3a,0x30,0xe2,0x5b,0xbc,0xcd,0xa8,0xdb,0x46,0x80,0xec,0xaa,0x06,0x8e,0xd8,0x6c,0x35,0x65,0x52,0xb8,0xc3,0xf9
+.byte 0x97,0x68,0x06,0x2d,0x3e,0x91,0x71,0x44,0x6e,0x01,0x51,0x10,0x5b,0x74,0xb9,0x3f,0xd7,0xf9,0x5c,0x98,0xe6,0xf8,0x98,0x32,0x26,0x9b,0x5e,0x9c,0x88,0xfb,0xaa,0x70,0xd2,0x2e,0xc2,0xf6,0x02,0x92,0x33,0x55,0x92,0xba,0xfb,0x0e,0x0b,0x08,0xdf,0x5d,0xdd,0x47,0x28,0xae,0x32,0xb3,0x27,0x8d,0xd4,0x18,0x43,0x64,0xc4,0x7f,0x60,0x62
+.byte 0xd9,0x63,0xd1,0x28,0xc9,0x75,0x3b,0x44,0xb4,0x8e,0x2a,0x93,0xf9,0x4c,0x4f,0x7e,0x6b,0x98,0xc9,0x1a,0x82,0x51,0x9a,0xb2,0x80,0x70,0x2e,0xff,0x19,0x66,0x1b,0xb6,0xbc,0x15,0x8e,0xe6,0x0f,0x8e,0x04,0x10,0x94,0x44,0x6c,0x32,0x4b,0x61,0xbc,0x4a,0x16,0x7b,0x25,0x2a,0x27,0x96,0xa9,0xa9,0x61,0x10,0xc1,0x46,0xdd,0xf5,0xe3,0xe8
+.byte 0x1f,0x5b,0xa0,0x77,0xe1,0x42,0x9a,0xd4,0x04,0x33,0x68,0x72,0x1c,0x44,0x29,0xce,0x98,0xe0,0xc7,0x3a,0x9e,0x3c,0xb9,0xb4,0x29,0xef,0x57,0xee,0x8c,0x8f,0x7c,0xe6,0xe1,0x43,0x6e,0x45,0x0e,0xdd,0x4e,0x11,0x4b,0x28,0x69,0xde,0xb8,0xfa,0x32,0xbe,0xc6,0x4f,0x11,0x99,0xe5,0xe3,0xe2,0x1f,0x03,0xbe,0x4a,0xad,0x60,0x68,0xc8,0x13
+.byte 0x80,0x4e,0xb6,0xc0,0xc5,0xc7,0x97,0x5c,0x0b,0x0e,0x64,0x43,0x78,0x70,0x95,0x91,0x8e,0x36,0x6b,0xad,0x57,0xc7,0x1e,0x9c,0x54,0xc9,0x89,0xf0,0x13,0xde,0x0a,0xbe,0xc0,0xa9,0x35,0x77,0x0a,0x01,0x7f,0x98,0x51,0x82,0x92,0x14,0xe0,0x9a,0x08,0xa3,0x0c,0x6c,0x67,0xf2,0x05,0xaa,0xa9,0x4e,0xce,0x3b,0xb1,0xb6,0x8c,0x82,0x5d,0x11
+.byte 0xf2,0xe5,0xd7,0xda,0x3a,0x65,0xa0,0xe3,0xa4,0x09,0x01,0x1c,0xb2,0x08,0x90,0x94,0xb5,0x51,0x56,0x24,0x22,0xfd,0x12,0xad,0x7a,0x75,0xcf,0x0f,0x0f,0x23,0xc3,0xa6,0x1f,0xf8,0x39,0xbc,0x2f,0x18,0x53,0x14,0xef,0xdf,0x90,0x6a,0x50,0x2b,0x8c,0x8b,0xa8,0xd4,0x8c,0x59,0x8f,0xd8,0x81,0x86,0x57,0xc1,0xd1,0xfb,0xe7,0xa6,0x20,0x6e
+.byte 0x7c,0xbf,0xce,0xe3,0xce,0x28,0x35,0x7c,0x8e,0x1a,0x66,0xea,0x7d,0x81,0x09,0xdb,0xa8,0x64,0xba,0x3c,0x07,0x3f,0x23,0xd3,0x05,0x97,0x4c,0x92,0xc2,0xa4,0xe8,0x6c,0xfb,0xa0,0x9d,0x8b,0x4d,0xcb,0x3a,0x96,0xe7,0x04,0x0f,0x48,0x87,0x2c,0xdd,0x51,0xf3,0x46,0x7e,0x61,0x89,0xbe,0xb8,0xb0,0x9e,0x9c,0xc4,0x37,0x55,0xe6,0x4f,0x78
+.byte 0x7e,0xb0,0x59,0x42,0xca,0xba,0x4a,0xb2,0x50,0xbd,0x16,0x68,0x99,0x42,0xb4,0x8b,0x60,0x3d,0x54,0x41,0x17,0x11,0x39,0x42,0x5d,0x41,0xec,0xc2,0x53,0x82,0x7c,0x32,0xc9,0xd1,0x34,0x49,0xd8,0x4f,0x29,0x21,0xeb,0x97,0x98,0x4c,0xeb,0x21,0xce,0x50,0xd6,0x53,0xd9,0xf1,0x6e,0x26,0xfa,0xe4,0x71,0x34,0xd8,0x38,0xac,0x39,0x4f,0x02
+.byte 0x36,0x93,0xf2,0x08,0x88,0xdc,0x24,0xdd,0x1f,0xf5,0xe9,0x7f,0x83,0xa0,0xa4,0x6b,0xc5,0xef,0x8e,0x82,0xf9,0x92,0xbc,0x82,0x3f,0xce,0x86,0xa6,0x34,0xf8,0x16,0xa7,0xdb,0x97,0xca,0x54,0x43,0xd8,0xfc,0x31,0xde,0x73,0xd0,0x79,0x1a,0xac,0x61,0x15,0xbd,0x38,0x64,0x3b,0xc6,0xb5,0x95,0xeb,0x2e,0x68,0xe4,0x1d,0x6b,0x18,0xab,0x88
+.byte 0xb0,0x96,0x51,0x8c,0xbe,0x41,0x63,0xd6,0x9a,0x21,0x60,0xe8,0x26,0x37,0xb3,0x10,0x76,0x46,0x31,0x90,0xb0,0x9f,0x17,0xab,0x0f,0x93,0xcc,0x12,0x78,0xee,0x17,0x1c,0xd8,0xc7,0x76,0x0a,0x5a,0xb4,0x8b,0xb1,0x67,0x11,0xde,0x48,0x14,0x8a,0x2a,0xc7,0x71,0x46,0x94,0x15,0x29,0x44,0x9e,0x35,0x03,0x10,0xf7,0x51,0x8a,0xaa,0x9c,0x4a
+.byte 0x9a,0x44,0xd5,0xc7,0x37,0x9d,0xb4,0xad,0x41,0xd0,0xda,0xd2,0x1a,0xf9,0x93,0xee,0x28,0x32,0x65,0x0b,0x9c,0x12,0xe3,0xad,0x9f,0x82,0xeb,0x3f,0x03,0xe7,0x6a,0x58,0x83,0x3f,0xbe,0x9f,0x27,0xd3,0xd6,0xe2,0x45,0xbf,0x90,0xe2,0x12,0x61,0x0b,0x57,0xd7,0x06,0x72,0x39,0x2c,0x3e,0x65,0xb2,0xf4,0xf7,0x54,0xef,0x32,0x99,0x44,0x0d
+.byte 0xf0,0x5c,0xde,0x4c,0x2e,0x22,0xcd,0x3c,0x25,0x02,0xa5,0x0d,0x79,0x16,0xb0,0x51,0x3f,0x3c,0x84,0x56,0xfa,0x00,0xae,0x7a,0x36,0x45,0x3a,0xcc,0x1d,0x66,0xff,0xf4,0x49,0xce,0xb5,0x5c,0x51,0xf4,0x3e,0x07,0xf2,0x83,0x84,0x4d,0x4e,0xb7,0xce,0x03,0x7b,0x23,0x63,0xdf,0x64,0xa2,0x55,0x92,0xf9,0x2e,0xa5,0x21,0x89,0x29,0x42,0x48
+.byte 0x36,0xc5,0xab,0xd6,0x82,0xe3,0xff,0x45,0xfc,0x61,0xa6,0x4f,0xb9,0x51,0xba,0xd5,0x03,0xa9,0x0b,0xe7,0x73,0x83,0x97,0x1d,0xb2,0xc6,0x75,0xa0,0x52,0x99,0xfc,0x1b,0x27,0x7a,0x10,0xc1,0xed,0x70,0x21,0x4b,0x93,0xa4,0x20,0xed,0x16,0x76,0x97,0x82,0xab,0x21,0xfe,0xa4,0x3f,0xd9,0xbd,0x9c,0x2f,0x19,0x42,0xbc,0xb3,0x4f,0x44,0xf3
+.byte 0x9e,0xd0,0xe7,0xc9,0x7e,0x31,0xaa,0xbc,0x4b,0xba,0x73,0xe1,0xc3,0xbf,0x5d,0xa2,0xd8,0xb7,0xb6,0xfc,0x0a,0x32,0xb9,0xff,0x80,0xb6,0x2a,0x8b,0xea,0x81,0xa0,0xeb,0x1e,0x9e,0x69,0xdd,0xbe,0xc1,0x8a,0x5d,0xfb,0x66,0x21,0x98,0x5c,0x6f,0xd8,0xb4,0xcf,0x8a,0x1a,0x4b,0xde,0xa2,0x20,0xe8,0x5a,0x5a,0xee,0x14,0x09,0xcb,0x63,0x1c
+.byte 0x14,0x7d,0x9b,0x47,0xf8,0xfa,0xda,0xb7,0x0e,0xc6,0xbd,0xb2,0x13,0xb8,0x10,0xe2,0x71,0x04,0x36,0x78,0x6d,0x3a,0x8b,0x45,0xd3,0x05,0xec,0x8a,0x2d,0xfa,0x85,0x7c,0xdd,0x75,0xb3,0x2d,0xd1,0xae,0xfc,0xdd,0x02,0x2e,0xcc,0x43,0xc5,0xed,0xe4,0x3f,0xee,0x2c,0xd7,0x37,0x81,0x3a,0x44,0xe6,0xed,0x8c,0x9d,0x9d,0xfa,0xb5,0xdc,0xde
+.byte 0xb2,0x7c,0x51,0x58,0xa4,0x21,0xac,0xe2,0x79,0x96,0x90,0xe2,0x0b,0xbf,0x51,0x66,0x77,0x02,0xff,0x67,0x0a,0x70,0x1f,0x04,0x6c,0xb0,0x5b,0x2d,0x26,0x23,0x5a,0x85,0x73,0x66,0x6e,0x7c,0xb3,0xeb,0x36,0x73,0x0f,0xcd,0xb2,0x07,0xee,0x78,0xd1,0xbd,0x5e,0xfa,0x31,0xf6,0x82,0x67,0x94,0xaa,0xff,0xef,0xd2,0x23,0xfc,0x82,0xaa,0xe2
+.byte 0xef,0xc3,0x74,0x79,0x6c,0xe9,0x3f,0x8d,0xe1,0x1b,0xc8,0xb4,0xff,0x15,0xf4,0x60,0xe8,0x84,0x3f,0xaa,0xc6,0x53,0x51,0x1a,0x9b,0x04,0x9b,0xab,0xc5,0xee,0x9a,0x98,0x80,0x89,0x8d,0x5b,0xef,0x0a,0x69,0x71,0xd2,0xf3,0x49,0xc1,0xc1,0x87,0xb3,0x18,0x4b,0x82,0x02,0x87,0xb0,0xf1,0x76,0x4b,0x3e,0xad,0x95,0x51,0xb1,0x64,0xb1,0x03
+.byte 0x5b,0xd2,0x10,0x7b,0x4e,0xd4,0x08,0xf8,0xfd,0xea,0xf0,0xc7,0x16,0x43,0x86,0xa6,0xdb,0xcd,0x75,0xce,0xa9,0xfd,0xa8,0x7c,0x51,0xf7,0xa5,0x29,0x6f,0x0d,0xee,0x66,0x8f,0xc6,0xcd,0x9e,0x3f,0x00,0x24,0x21,0xca,0x69,0x79,0x27,0x03,0x62,0xdf,0xad,0xb9,0x8c,0xd8,0x08,0x88,0x0d,0x0c,0xa1,0x29,0xf9,0xba,0x92,0xb5,0xdd,0xb8,0x1a
+.byte 0xbb,0xab,0x44,0xb2,0xda,0x1b,0x8b,0xc1,0x3c,0x61,0x9f,0x7a,0x8b,0x89,0x99,0x09,0xc3,0xb4,0xe4,0x24,0xf5,0x3b,0x36,0xa6,0x61,0x0a,0xec,0x2a,0x1c,0x92,0x7c,0xb1,0x7c,0xd8,0x0b,0x98,0x48,0x8d,0x52,0xa2,0x57,0xc1,0x28,0x89,0xbb,0x60,0x5c,0x58,0x62,0x41,0x1c,0xd6,0xfb,0x69,0x09,0x93,0x90,0x31,0xc4,0x72,0x71,0xf0,0x4f,0xcf
+.byte 0x10,0xbb,0xb7,0x6c,0x3b,0x53,0xa3,0x0b,0xff,0x44,0x4c,0x37,0xd5,0x26,0x83,0x7e,0x5c,0xb9,0xa5,0xe8,0x8b,0xc4,0x15,0xf6,0xc7,0xd1,0x39,0x67,0x01,0xb7,0xca,0xa7,0x71,0xa8,0x04,0x95,0x0f,0xfc,0x0a,0x9e,0x52,0xb2,0xfb,0x48,0x47,0xb6,0xa5,0x14,0xc2,0x4f,0xa8,0xd5,0x0f,0x10,0x76,0x39,0x23,0x74,0x2e,0xe5,0x17,0xcb,0xad,0x8a
+.byte 0x4a,0x25,0xc8,0x9b,0x25,0x94,0x34,0xbc,0x4b,0x2f,0xdc,0x0a,0xcd,0xc1,0x02,0x72,0x7d,0xa0,0x10,0xa7,0x32,0x68,0xe8,0xd5,0x23,0xe8,0xc9,0xbc,0x05,0x05,0x1e,0xac,0x55,0x45,0xfb,0x42,0x2f,0x0f,0x51,0x8d,0x31,0xb1,0xbc,0x10,0xa1,0x03,0xc3,0x6f,0x35,0x08,0xa5,0x2f,0x91,0x4e,0x43,0x6b,0x62,0x3b,0x00,0x4c,0xd0,0xb8,0x33,0xbc
+.byte 0xca,0x57,0xb8,0x1b,0xb4,0x52,0x1a,0xa7,0x03,0x78,0xa0,0x4f,0xda,0x86,0xb9,0xd8,0xc6,0x69,0xe6,0x61,0x2e,0x62,0x96,0x60,0x0d,0x76,0xdc,0x5d,0x0e,0xa8,0xf3,0x86,0xde,0xcf,0x39,0x34,0xc7,0x69,0xed,0xcb,0x9a,0xf5,0xc3,0xce,0x6d,0xa5,0x7f,0xae,0x73,0xb9,0xa6,0xbf,0x88,0x93,0x2b,0x0e,0x8b,0x4b,0xa5,0xeb,0x62,0xc6,0x1a,0xc7
+.byte 0x63,0x63,0x58,0x62,0x37,0xc6,0xbc,0x00,0x72,0xac,0x3d,0x7c,0x22,0xa5,0x59,0xf1,0x6e,0x60,0x45,0x3e,0x99,0x76,0x40,0x82,0xa7,0x52,0xf3,0x48,0x8e,0x4a,0xa3,0xe1,0x3b,0xea,0x77,0xa7,0x7d,0x13,0xe7,0xc4,0xc6,0xa6,0x6e,0xda,0xe8,0x50,0xc8,0x39,0x30,0xab,0x8a,0xe1,0x08,0xa9,0xe3,0xbd,0x8d,0xbd,0x83,0x3c,0xbc,0x6c,0x92,0xed
+.byte 0xf1,0xa9,0xd3,0x50,0xf2,0x29,0x8b,0x39,0x46,0xaf,0x08,0x7e,0x00,0x64,0x2f,0xa8,0x18,0xab,0x7e,0x07,0xd3,0x63,0x2a,0xd3,0xd3,0xbb,0xf9,0xdd,0x2b,0xec,0x70,0x35,0x1a,0x94,0x6b,0x87,0xe4,0x1a,0x0a,0x44,0x46,0x08,0xa6,0xce,0x1b,0xf7,0xd7,0x20,0x87,0x1a,0x96,0x6c,0xbe,0xdf,0x73,0x3b,0xc9,0xaf,0x89,0x1c,0x2f,0x47,0xe9,0xd8
+.byte 0x03,0xa6,0x03,0x6c,0x73,0xa9,0x65,0x20,0x36,0xea,0x6f,0xe7,0x96,0x7c,0x01,0x87,0xb0,0x21,0xba,0xb4,0xed,0x1f,0x81,0x65,0x97,0x36,0xda,0x68,0x80,0x64,0x99,0xe6,0xda,0x95,0x04,0xdf,0x5d,0xfd,0x86,0xd1,0xfd,0xfa,0x1c,0xd7,0x89,0xbf,0xe6,0x99,0x6c,0xf5,0x01,0x56,0x20,0x88,0x79,0xa7,0x8d,0x88,0x82,0xe5,0x32,0x38,0xe0,0xf0
+.byte 0x98,0x63,0xa9,0xab,0xeb,0x09,0x8d,0xaf,0x3f,0xa8,0x57,0x98,0xde,0xc8,0x9c,0x8d,0x1d,0x18,0xc5,0xa8,0x82,0x51,0x9b,0x6f,0xc6,0xb8,0x09,0xd3,0xea,0xd4,0xe3,0xac,0xd1,0x0e,0x88,0xda,0xdf,0x38,0x53,0x14,0x87,0x28,0x6f,0x13,0x35,0xdb,0xfe,0xa1,0xe7,0x43,0xb5,0x02,0x46,0x08,0x1a,0x31,0x0d,0x9e,0x3d,0x3b,0xbf,0xbb,0x82,0x9c
+.byte 0x09,0xf3,0xd9,0x22,0x0a,0x82,0x07,0xd3,0xe8,0x19,0x6e,0x21,0xd2,0xa2,0xa8,0x14,0xbc,0x42,0xb6,0xeb,0x8c,0x40,0x9b,0xb2,0xa9,0x17,0xad,0x2c,0x19,0xaa,0x4b,0x22,0xf9,0x4e,0xde,0x8f,0xbe,0x78,0x9b,0xab,0xb9,0xfa,0xb1,0x3e,0x68,0x86,0x1a,0x4a,0x61,0xba,0x63,0x51,0x25,0x11,0x59,0xd0,0xb7,0x0c,0xb7,0xcc,0x45,0x05,0x6d,0x5a
+.byte 0xe2,0xd7,0x10,0x80,0x19,0xd3,0xa9,0xab,0xb6,0x9f,0x53,0x7a,0xaa,0x19,0x74,0x01,0xc9,0xd6,0x45,0x42,0x2c,0xe5,0xc0,0xcf,0x62,0xe6,0x95,0x6f,0x4c,0x90,0x50,0x97,0x61,0x83,0x73,0xd0,0xc2,0xd5,0xf0,0x05,0xca,0xe9,0x6f,0x67,0xa9,0x51,0xb8,0xb4,0x9d,0x30,0x8e,0xe3,0x29,0xf9,0x3b,0x3d,0x17,0x25,0xad,0xbb,0xb0,0x34,0x68,0x29
+.byte 0x06,0xad,0x0e,0xdf,0x41,0xa6,0xf1,0xa6,0x25,0xc4,0xf0,0x0d,0x57,0x84,0x34,0x2c,0x3b,0xb1,0x41,0xd6,0x83,0x00,0x3a,0x91,0x98,0x8e,0xd0,0x59,0x0b,0x2d,0xc9,0x65,0x03,0x91,0xcb,0x03,0x97,0x57,0xde,0x11,0x8b,0x4b,0x1b,0x85,0x0b,0xb6,0x68,0x25,0x3c,0x1a,0x04,0x7d,0xd5,0x2b,0x16,0x69,0x1f,0x64,0x8b,0x47,0x60,0x17,0xaa,0x68
+.byte 0x45,0xf2,0x0b,0xf8,0xa2,0x27,0xf8,0x47,0x86,0x41,0x94,0x3f,0x92,0xc3,0x02,0xab,0x80,0x2b,0x0e,0x3c,0xd0,0x13,0x59,0x08,0xfc,0x13,0x33,0x52,0xbb,0x2d,0x6b,0x22,0xa2,0x8b,0x9f,0x7c,0x8e,0x40,0x35,0xa4,0xc7,0x45,0xb7,0xf8,0x10,0x22,0x95,0xc5,0x48,0xc1,0x50,0x4d,0x4a,0x36,0xe1,0xec,0x1e,0x07,0xf7,0x68,0x63,0xcb,0x13,0x03
+.byte 0x70,0x63,0xb1,0x9b,0xf3,0x60,0x01,0x6e,0x63,0x5c,0x4d,0x2c,0x5c,0x5c,0x58,0x8b,0xbb,0x6e,0xd1,0x69,0xdd,0x19,0xfe,0xfb,0xd6,0xdc,0x68,0x97,0x9c,0x46,0x0d,0xdd,0x4d,0xbd,0x52,0xe4,0xd9,0xc2,0x03,0x4e,0x4c,0xe2,0x66,0x6b,0x4d,0xbe,0x6b,0xf3,0xd6,0xbe,0x2d,0xba,0xdd,0x1b,0x4f,0x60,0x02,0x74,0xa1,0xf0,0xd0,0xfa,0x23,0x33
+.byte 0x29,0x7e,0x00,0x09,0x47,0x15,0xa8,0xd8,0xdb,0xb8,0xe1,0x20,0xd5,0xe2,0x91,0xd0,0xe8,0xfa,0xa1,0x0d,0x80,0xbd,0x7d,0x62,0x9d,0xf2,0xbc,0x03,0xa1,0x44,0x9f,0x8d,0x3d,0xe3,0xb4,0xec,0x32,0xd9,0x66,0xb0,0xc7,0x75,0x11,0xaa,0xab,0xb7,0x84,0x1d,0x5b,0x4f,0x25,0x5c,0x53,0xed,0xbb,0x6d,0x06,0x1f,0x12,0x5f,0xc0,0xeb,0x55,0x3e
+.byte 0xd0,0x5b,0x4d,0x07,0xf7,0x84,0x12,0xbc,0xc8,0xd4,0xf4,0x69,0xdb,0x71,0x8a,0x00,0x58,0xf5,0x84,0xff,0xc3,0xbc,0x13,0x6e,0x5f,0xac,0xd6,0x72,0x1b,0x2d,0xbb,0x27,0xfd,0x8d,0xcc,0x59,0x79,0xb9,0x63,0xe8,0x0a,0xf3,0x7f,0xa4,0x9f,0x4c,0x35,0x9a,0xdc,0xff,0x11,0x42,0xf3,0x1c,0x86,0xd0,0x22,0x7e,0x81,0x79,0x04,0x93,0x5c,0xf2
+.byte 0xab,0xdf,0xb7,0x1d,0x84,0xbd,0xde,0xfb,0xd2,0x75,0x43,0xb8,0x19,0x63,0x97,0xfe,0x0e,0x91,0x9d,0x38,0x50,0xc5,0x7a,0xd6,0x51,0xd4,0xfc,0x8d,0xec,0xd5,0xe2,0x07,0xce,0x21,0x03,0x02,0xa1,0x61,0x8d,0xf1,0xf5,0x1f,0xb3,0xaf,0x9f,0x13,0xd8,0x81,0xd2,0xf7,0xe9,0xe2,0x62,0x49,0xca,0x1c,0x15,0x07,0x39,0xe6,0x01,0xec,0x6c,0x7d
+.byte 0x3b,0xf1,0x52,0xda,0xf2,0x97,0x55,0xef,0x6f,0x88,0x82,0x0e,0xe6,0xf4,0x3e,0x33,0xf6,0x61,0x6d,0xef,0xbf,0xa8,0x9a,0x91,0x2f,0xb3,0xd2,0x3d,0xaa,0x7a,0x4e,0x80,0xe1,0x04,0xbe,0xc7,0xf8,0xc3,0xc9,0xd8,0xa2,0x01,0x5d,0x30,0xae,0x6d,0x39,0x52,0x60,0x9d,0x07,0xd5,0xa2,0x86,0xf0,0x88,0x00,0xec,0x18,0x11,0x2d,0x69,0x86,0xa9
+.byte 0x5a,0x73,0xda,0x4e,0x4c,0xdb,0xb8,0x02,0xad,0x53,0xec,0x20,0x0f,0x35,0xe0,0x4f,0x6e,0xd5,0x04,0xcc,0xa0,0xf5,0x8c,0x7d,0x31,0x04,0xa4,0xcf,0xf0,0x27,0xd2,0xb6,0x7d,0x8c,0x26,0x5f,0x19,0xba,0x79,0x80,0xec,0x6d,0xfe,0xaf,0xc1,0x3a,0xc2,0x3d,0x14,0x3c,0xa0,0xc5,0x77,0xf4,0x96,0x56,0x51,0x8b,0x7c,0x7e,0xe5,0x23,0x5d,0x46
+.byte 0x1b,0x2e,0x28,0xc0,0x80,0x6b,0x6a,0x85,0x6c,0xcf,0xaa,0x28,0xf3,0x83,0x2d,0x42,0x6f,0xf3,0x5e,0x5d,0xa2,0x7b,0xba,0x5c,0x12,0xb0,0xda,0xa0,0xeb,0xdf,0xad,0x1d,0x4c,0x54,0xcf,0xad,0x02,0x68,0xcd,0xfe,0x5c,0x5b,0x65,0x6d,0xa5,0xcc,0xd3,0xed,0x32,0x74,0x6c,0x58,0x83,0x3a,0xc1,0x71,0xbf,0xb5,0xa2,0xbd,0x10,0xe5,0x46,0xc5
+.byte 0x00,0x82,0xb1,0xeb,0x6f,0x73,0xf9,0x12,0x23,0xe4,0xda,0xff,0xa3,0xc4,0x9c,0xf1,0xcc,0x0e,0x1a,0x7a,0x10,0x62,0x8f,0xa5,0xb2,0x35,0x51,0x67,0xb5,0x95,0xbe,0x4c,0x81,0x53,0xfc,0xdd,0x27,0x26,0x97,0x42,0x01,0xec,0x08,0x91,0xb8,0xf0,0xaf,0x57,0x54,0x73,0x52,0x8f,0xde,0xca,0xed,0x1b,0xca,0x8d,0x97,0x1e,0xdc,0xe7,0xfa,0x68
+.byte 0xaf,0x37,0xb0,0x62,0xa3,0x9f,0xbc,0xac,0x9f,0x28,0x1e,0xb7,0xaa,0xb0,0x91,0xe4,0x95,0xad,0xf9,0xe5,0xd4,0xcc,0x23,0x0f,0x4a,0x2d,0xdd,0xea,0x64,0xd1,0x04,0x3c,0xd0,0xca,0xfe,0xd3,0x19,0x9d,0x28,0xa5,0x1c,0xff,0x3e,0xae,0xe9,0xfb,0x12,0x03,0x6d,0xcf,0xbc,0x5f,0x27,0xce,0x1a,0xb9,0xc0,0x31,0x88,0x6e,0x2e,0xaf,0x35,0x5f
+.byte 0xf0,0xce,0x92,0xf8,0x6f,0xd6,0x67,0x1c,0xc6,0x5c,0xee,0x59,0xaa,0xd6,0x8c,0xa8,0x13,0xe6,0xf7,0xe2,0x82,0x2f,0x82,0x1e,0x4c,0x0d,0xab,0x3e,0xdb,0x4d,0xc5,0x90,0x32,0xe4,0xf0,0x74,0xc1,0x92,0x1b,0xdd,0xf3,0xa7,0xf6,0x6b,0x01,0x9d,0x8d,0x78,0x3d,0x5a,0x46,0x74,0x16,0x93,0x44,0xca,0xbe,0x31,0xea,0xb4,0x65,0xcd,0xe6,0xdd
+.byte 0x56,0x9d,0x63,0x48,0xf0,0xf3,0x15,0x91,0x6c,0x27,0xf9,0xf7,0x3b,0x9f,0x04,0x6d,0x4d,0x1d,0xf1,0x7c,0xd1,0x81,0x06,0xef,0x04,0x47,0x98,0x5d,0x21,0xf4,0xe0,0xa0,0x13,0xaf,0x1d,0xb0,0xd5,0x45,0x64,0x92,0x46,0x99,0xff,0xb4,0xbf,0x36,0x01,0x2d,0x23,0x6a,0xc4,0x6b,0x3f,0x91,0x10,0x03,0xaf,0x6e,0x79,0x86,0xdb,0x15,0xde,0xfa
+.byte 0x0d,0x71,0x04,0x16,0x12,0x31,0x9b,0x69,0xb9,0xe0,0xe7,0x4e,0xfd,0x0e,0xd5,0x71,0xa0,0xc7,0xd7,0x46,0xdb,0xda,0xbd,0xcd,0xdc,0x77,0xe5,0x71,0x9d,0xa1,0xf4,0x02,0x10,0xc6,0x27,0x76,0x4e,0xa6,0x35,0xe6,0x9e,0xda,0xbe,0xd8,0xc0,0x21,0x15,0xd4,0xcc,0xd5,0x4b,0xdf,0x38,0xc5,0x15,0x4b,0xfa,0x4e,0x83,0xf4,0x27,0xdb,0x8a,0xb1
+.byte 0x0e,0x1f,0xc9,0x3c,0x1c,0x36,0x35,0x54,0x8b,0x54,0xf8,0x31,0x1e,0x0e,0x1c,0x4e,0x44,0x29,0x90,0xad,0x28,0x85,0xb4,0x72,0x2d,0x1b,0x8b,0x26,0x2f,0xb6,0xc2,0x14,0x0e,0x81,0xd0,0x37,0x29,0x5c,0x0f,0xdc,0x21,0x62,0x10,0x7a,0xeb,0xa3,0x6e,0xd4,0x5b,0xb4,0x13,0x2e,0xd6,0x8f,0xd9,0x57,0x0d,0x9b,0xfd,0x1e,0x66,0xb7,0x6e,0xac
+.byte 0x88,0xb9,0x75,0x60,0x62,0x83,0x72,0x96,0xc6,0x2e,0xdc,0xfe,0x88,0xee,0x07,0x9a,0x62,0x19,0xde,0xf1,0xa5,0xfb,0xcc,0xdb,0x4a,0xeb,0x16,0x60,0x34,0x46,0xfc,0xf2,0x6d,0xee,0xfc,0xa0,0x3a,0xb1,0x11,0x03,0x8b,0xae,0x26,0xef,0x86,0x91,0x20,0x7a,0x19,0x35,0xd6,0x12,0xfc,0x73,0x5a,0xb3,0x13,0xf8,0x65,0x04,0xec,0x35,0xee,0xf8
+.byte 0x70,0xb2,0x0b,0xe1,0xfc,0x16,0x35,0xec,0x6b,0xdd,0x8b,0xdc,0x0d,0xe8,0x91,0xcf,0x18,0xff,0x44,0x1d,0xd9,0x29,0xae,0x33,0x83,0xfe,0x8d,0xe6,0x70,0xbb,0x77,0x48,0xaa,0xe6,0xbc,0x51,0xa7,0x25,0x01,0xcf,0x88,0xc4,0x8b,0xfc,0xb1,0x71,0x01,0xc7,0xfc,0xd6,0x96,0x63,0xee,0x2d,0x04,0x1d,0x80,0x24,0xd0,0x80,0x03,0xd9,0x18,0x96
+.byte 0xec,0x6a,0x98,0xed,0x6e,0x9a,0xe0,0x42,0x5a,0x9d,0xec,0xed,0x46,0x3c,0xb5,0xf0,0xd6,0x88,0x92,0x89,0x38,0x5f,0xd6,0xba,0xfd,0x32,0x31,0x81,0xe9,0xf1,0x56,0x89,0xa3,0x56,0xa6,0x03,0x00,0x60,0xe1,0xa8,0x59,0xdb,0xbe,0x72,0x39,0x6c,0x08,0x4d,0x26,0x57,0xa6,0xf6,0x13,0x7d,0x4a,0x2f,0x64,0xb8,0xa7,0x23,0x2c,0xa4,0x4a,0xad
+.byte 0xcf,0xa1,0xa2,0x32,0xbb,0xd1,0x98,0x02,0xe4,0x1a,0x41,0x26,0x23,0xba,0xa2,0x17,0x62,0xaa,0xa6,0xc7,0x74,0x9d,0xea,0xc7,0xa0,0x08,0x0a,0x1a,0x4e,0x71,0xd9,0x45,0xf7,0xe8,0x57,0x79,0x12,0xd0,0x38,0x2f,0xdb,0xbd,0x5a,0x84,0xe1,0xb2,0x62,0x7e,0x56,0xb3,0x50,0x2a,0xa0,0x32,0x1f,0x86,0x71,0xc4,0xa5,0xba,0x93,0x5b,0x22,0x97
+.byte 0xf4,0xe5,0x44,0x27,0x6b,0x06,0x84,0x55,0x19,0x45,0x12,0x75,0x4b,0xf0,0x76,0x6d,0x3c,0x0a,0x17,0xc2,0x9d,0x96,0x72,0xe7,0x5e,0x79,0x84,0x0a,0x39,0x64,0x09,0x6e,0x7e,0xd7,0x77,0x40,0x75,0x2c,0xbd,0x98,0xae,0x3e,0x34,0x08,0x4d,0xda,0x2c,0xcf,0x0c,0xa2,0x8c,0x40,0xfa,0x34,0x43,0x15,0xed,0x4f,0x69,0xa6,0xef,0x2d,0x3c,0x55
+.byte 0x7a,0xe1,0x67,0xd1,0x0a,0x89,0xe0,0x2d,0x02,0x35,0x57,0xc8,0x9a,0x4b,0xc4,0x46,0xa7,0x57,0x03,0x89,0x7d,0x3f,0x70,0x47,0x03,0x06,0xd9,0x81,0x1f,0x8d,0x7e,0x36,0x9b,0xfd,0xad,0x20,0x9d,0x5a,0x29,0xe9,0x40,0x6a,0xb8,0x07,0x6b,0xc7,0x2b,0x58,0xd2,0x1d,0xef,0x88,0xa5,0xfb,0x3b,0xd6,0x9f,0xfd,0x89,0x0e,0x50,0xd4,0xbc,0x89
+.byte 0x3f,0x3c,0x6c,0x50,0xc6,0xe3,0x8b,0x7e,0x34,0x8b,0x26,0x99,0x2a,0xfa,0xa5,0x19,0x53,0xb5,0x5e,0xfd,0x94,0xe8,0x33,0xb2,0x6d,0x9c,0x3c,0x0c,0x14,0x90,0xc4,0xa2,0x4a,0x3a,0xca,0x07,0x72,0x46,0x37,0xfc,0x02,0x5d,0xf4,0x97,0xca,0x8e,0xc6,0xc4,0x63,0xda,0x5c,0x89,0xc3,0x6c,0xb1,0x1a,0xf5,0x2a,0xbc,0x2e,0xe3,0xcd,0x2f,0xe2
+.byte 0x91,0x16,0xf9,0x94,0x0e,0x1b,0xe6,0x01,0x73,0x61,0x1e,0xcf,0x5e,0x21,0x70,0xcb,0x5b,0x87,0xc1,0x46,0x39,0x59,0xa6,0x74,0x82,0x7f,0xa2,0x6c,0x4a,0x50,0x5f,0xbd,0x1c,0x1a,0x65,0x80,0x01,0x44,0x19,0xcf,0xcd,0xef,0x3d,0x5e,0x1b,0x71,0x82,0x4f,0x8b,0xc1,0xa0,0x9a,0x77,0xee,0xac,0x06,0xdc,0x6a,0xa0,0x34,0x50,0xa4,0xe0,0xda
+.byte 0x3d,0xa0,0xf7,0x9a,0xb8,0xd5,0x59,0xe0,0x7f,0x05,0x04,0xd5,0x32,0x8c,0x49,0xf5,0x0a,0x0e,0x99,0x83,0xf5,0x47,0x2b,0x7c,0x7b,0x65,0x25,0x02,0xc4,0x88,0xbb,0x6a,0x4f,0x89,0x31,0x60,0xc2,0x47,0x8b,0x22,0xfc,0x4a,0xde,0xb3,0xb9,0xed,0xb8,0xdf,0xd7,0xd5,0x09,0x98,0xcc,0x5f,0xaf,0xbb,0x02,0xc3,0x62,0x62,0xee,0x99,0x42,0x1b
+.byte 0xbe,0x5b,0xa8,0x5c,0x40,0x03,0x86,0x29,0x29,0x06,0x0b,0x53,0x46,0x29,0x03,0x3b,0x11,0x64,0xf1,0x09,0xca,0x69,0x69,0xfa,0xcc,0x85,0x23,0x14,0x1b,0xfd,0x65,0xb9,0xf5,0x6b,0xbb,0x2a,0x9d,0x6e,0x64,0x1a,0xe1,0x37,0x39,0xd4,0x85,0x40,0xa3,0xf9,0x04,0xec,0x9e,0x3b,0x74,0x97,0xa4,0x64,0x8a,0x48,0xb2,0x62,0xc1,0x1c,0xed,0x67
+.byte 0x6f,0x23,0xae,0x0f,0x64,0x2e,0xe5,0x92,0xb6,0xb5,0x71,0x24,0xc0,0x60,0x9a,0x10,0x23,0x6b,0x4a,0x22,0xe9,0x0a,0xaa,0x09,0x62,0x39,0xe0,0x40,0xee,0x13,0x27,0x14,0x73,0xeb,0x75,0x7b,0x4a,0xe1,0x42,0x65,0x37,0xae,0x80,0x08,0x26,0xf9,0x53,0x98,0x58,0xdd,0xf5,0xed,0x26,0x37,0x37,0x85,0xb5,0x88,0x91,0x05,0x2d,0x04,0xa6,0xd5
+.byte 0xa6,0x98,0xb0,0x0e,0x4b,0x4c,0x53,0x76,0x79,0xad,0x82,0xc5,0x16,0xba,0xd8,0x20,0x5f,0x4c,0x1d,0x69,0xa0,0xe0,0xe9,0xbc,0xb8,0x5c,0x10,0x4a,0x0a,0xd3,0x52,0x9c,0x2e,0x1b,0x6c,0xf7,0x43,0x83,0x6f,0xa9,0xcc,0x00,0xed,0x16,0x4c,0xc3,0x24,0x79,0x59,0x68,0xfb,0xf9,0xf6,0xb0,0xb4,0x01,0xc2,0xdd,0xf7,0xe5,0x3b,0x60,0x48,0x49
+.byte 0x32,0x48,0x05,0xa8,0x62,0xa3,0x03,0x9f,0x3d,0x91,0xdb,0x84,0x64,0x6f,0x1e,0x50,0x8e,0xdf,0x1a,0xa0,0xb1,0xf4,0x34,0x7c,0xe6,0xb7,0x7c,0x14,0xa1,0x65,0x1a,0xb4,0xdb,0x67,0x78,0xb1,0x88,0x3c,0xc2,0x5e,0x0e,0xea,0x32,0x15,0xc7,0xda,0xe4,0x9a,0x44,0xde,0x61,0x90,0x3b,0x97,0x11,0x5b,0x6d,0xa5,0x9a,0x2f,0x1b,0x8b,0xd7,0xdd
+.byte 0x73,0xe4,0xc3,0x19,0x5d,0x68,0xcf,0x0e,0xe4,0x69,0xa5,0xeb,0x50,0x6f,0x79,0xff,0x91,0xc6,0x95,0x83,0xe8,0x72,0x6a,0x01,0x49,0x2b,0xcf,0x8f,0x93,0x1e,0xef,0x31,0x17,0x8f,0xa8,0x2b,0x5f,0x4b,0x79,0x8b,0xe5,0x6c,0xb7,0x61,0xd5,0x9e,0xe0,0xd4,0x25,0xc3,0x93,0x31,0x8f,0x66,0x6c,0x48,0x30,0x65,0xf4,0xd7,0xde,0x64,0xee,0xbd
+.byte 0xbd,0xad,0x32,0xfc,0xf3,0xd8,0x7c,0x85,0x7c,0x24,0x40,0xb6,0xd4,0xe0,0x4b,0xc0,0xab,0xcc,0xeb,0x77,0x7c,0xb7,0x33,0x3c,0x90,0x04,0xaf,0x85,0xaa,0xb4,0xaa,0x90,0x67,0x29,0xd9,0x85,0x6a,0x34,0xf4,0xc4,0x6c,0xbc,0xb4,0x86,0x54,0x83,0xd5,0x5e,0xf3,0xdd,0x1a,0x56,0x5e,0xa5,0xd8,0x06,0xc0,0xa7,0x27,0xd4,0x0d,0x5b,0x08,0xf4
+.byte 0xb4,0x15,0xf9,0xb4,0x56,0x1c,0x80,0x98,0xc9,0xcd,0xf0,0x38,0x18,0xbe,0x99,0xec,0x7e,0x0c,0x3d,0xc1,0x98,0x26,0x9d,0x50,0xe4,0x00,0xcf,0x0f,0x0b,0x77,0x86,0x31,0x55,0x38,0xa4,0x31,0x50,0x51,0x64,0x88,0x81,0x05,0x32,0x99,0x38,0xd1,0x62,0x20,0x8e,0xf0,0x29,0x31,0xf5,0x79,0xbb,0x1e,0x0f,0xba,0x51,0x94,0xa9,0x54,0xcd,0x43
+.byte 0xce,0xe5,0x2c,0x29,0xa5,0x51,0x23,0x97,0x5d,0x36,0xff,0x51,0x5c,0x66,0xb7,0x62,0x1b,0x5f,0xd7,0x2f,0x19,0x07,0xff,0x0a,0xfc,0xf6,0x6e,0xb5,0xfd,0xa9,0x92,0x40,0xd3,0xe6,0x99,0x15,0x6f,0x1e,0x91,0xad,0x1f,0x4d,0x1c,0xe2,0xd9,0xcf,0x01,0x71,0xec,0x1a,0xa3,0xba,0x48,0x40,0xfd,0x18,0xb1,0x24,0x2b,0xd2,0x37,0xb5,0x74,0xdd
+.byte 0x7e,0xf6,0x18,0xb4,0x7b,0x0e,0x7d,0x65,0x46,0x7b,0xe3,0x51,0x03,0xae,0xe1,0xd0,0x74,0xc6,0xc9,0xda,0x0e,0x79,0x6f,0xf5,0x62,0xc0,0x7e,0x76,0x3e,0x13,0x8b,0xe0,0x4c,0xfa,0x7e,0xe1,0xa2,0xee,0x9d,0x3f,0x91,0x9d,0x21,0xdd,0xc2,0xd0,0xa5,0x1d,0x17,0xd6,0xdc,0xeb,0xa3,0xc0,0x71,0xa0,0xfe,0xf0,0xaf,0x31,0xdc,0xa3,0xd4,0x21
+.byte 0x4a,0x32,0x1d,0x54,0x25,0x3b,0xc8,0x8f,0x68,0xcd,0x99,0xce,0x76,0x39,0x42,0xd8,0xca,0xf2,0x46,0x72,0xfe,0x52,0xc2,0x90,0x83,0xed,0xa0,0x6d,0x1b,0xf5,0xb1,0x09,0xae,0x2b,0x34,0x4f,0xd3,0x78,0x19,0x7f,0xad,0x8d,0x50,0x26,0x9c,0x36,0xa3,0xb5,0x3d,0x0b,0xa6,0x87,0x65,0xa0,0xdb,0x88,0x20,0xff,0xb6,0xfd,0xc5,0xbd,0x0a,0x28
+.byte 0xc8,0x9c,0x42,0x7f,0x24,0x58,0xe9,0x07,0x53,0x4b,0x9a,0x2a,0x1e,0x7b,0x90,0x97,0x78,0x74,0x80,0x5d,0xe5,0x6e,0xae,0x15,0x68,0xd4,0x2a,0x3a,0xd3,0x00,0x4f,0x4b,0xff,0x8f,0x1e,0x8f,0x9f,0x75,0xe5,0xea,0x9d,0xb9,0xed,0x8f,0xa9,0x2b,0x70,0xa8,0xcb,0x08,0x85,0xd3,0x8f,0x5d,0xc7,0x49,0x66,0xcc,0xa8,0x6d,0xbd,0x01,0x93,0xd5
+.byte 0xe6,0x75,0x2e,0x25,0x07,0x59,0x86,0x3f,0x44,0x8b,0x0b,0xb5,0x38,0xd5,0xbd,0xcf,0x48,0x8a,0xf7,0x71,0xd6,0x6b,0x2e,0x93,0x3d,0x0b,0xc0,0x75,0xee,0xa8,0x5d,0x9c,0x3d,0xa5,0xdb,0xc5,0x8d,0xac,0xda,0xf4,0xcd,0x5f,0x24,0xfe,0x86,0x14,0x44,0x65,0x3f,0x89,0x7f,0xd3,0x61,0x48,0xb0,0x43,0xf0,0x1e,0xde,0xbc,0xb7,0x51,0x0f,0xfc
+.byte 0x32,0xf2,0x04,0xe2,0x4b,0xcb,0xbb,0x63,0x7d,0x5b,0x9a,0xb1,0x91,0x57,0x89,0xdc,0xed,0xde,0x91,0x2d,0xdd,0x42,0xc8,0x3c,0xb0,0xd7,0xa5,0xbc,0xa7,0x33,0x14,0x32,0xaf,0xf7,0xe9,0x25,0xd2,0x1a,0x64,0xf7,0x1b,0xab,0x0e,0xbc,0x50,0xbc,0x85,0x44,0xe0,0xa6,0xf1,0x4a,0x32,0x2f,0x30,0x27,0x48,0x4f,0xfc,0x8a,0x5a,0x78,0xe7,0x16
+.byte 0x55,0xcf,0xca,0x15,0xa8,0xa8,0xa2,0xef,0x9a,0x16,0x02,0xf4,0xb0,0x44,0xfd,0xc4,0x51,0x01,0x4f,0x1d,0x9d,0x09,0x62,0x42,0xe9,0x8b,0x18,0xa4,0x65,0xef,0x8b,0xfe,0x71,0x9f,0x4b,0x47,0x48,0x41,0x73,0x5c,0x0c,0x52,0x7d,0x79,0xbc,0x93,0x2a,0xaa,0x81,0x99,0x21,0xa5,0x9e,0xac,0xcd,0x57,0x51,0x50,0xbc,0xc9,0x96,0xaf,0xdf,0x1a
+.byte 0x8f,0xee,0x36,0x05,0x20,0x32,0xe8,0x51,0x94,0x72,0x12,0xa3,0x17,0x25,0x7f,0x0a,0x3e,0xcc,0x22,0xcf,0x05,0xb2,0x2b,0xaa,0x36,0x01,0xdf,0xd4,0x4e,0xe1,0x02,0x43,0x4e,0xac,0x50,0x64,0xcd,0x2f,0xc2,0xa9,0xb0,0xf2,0xf2,0x4c,0xdf,0x16,0xa6,0x54,0xf7,0xbf,0x1a,0x69,0xeb,0xa1,0x5a,0xc7,0xcf,0x46,0x2d,0xc2,0x3a,0x7f,0x4a,0x14
+.byte 0x22,0x15,0x46,0x46,0x2d,0xc1,0x98,0xf7,0x0b,0xf3,0x27,0xfc,0x78,0x67,0x05,0xd8,0xe0,0xf6,0xb8,0xb6,0x0b,0xdb,0x4d,0x6b,0x7e,0x9b,0xbf,0x5c,0x15,0x97,0x49,0x9f,0x6f,0x11,0x6c,0x6e,0x1d,0x1e,0x65,0x5b,0xb9,0x60,0x8f,0xa3,0xa9,0x99,0x17,0x92,0xb8,0x65,0x25,0xc4,0xef,0xea,0xa6,0xc0,0x57,0xa9,0x4c,0x78,0xe3,0xd6,0xf2,0x19
+.byte 0x9c,0x86,0x9e,0x45,0x3e,0xfd,0x21,0x4c,0x2a,0x56,0x7c,0x23,0xf2,0x22,0xa1,0x81,0xdb,0xe6,0xfa,0x85,0x19,0x3b,0x1d,0x61,0xb3,0x21,0xb5,0x64,0x1d,0x07,0x66,0xd2,0xe5,0x9c,0xb0,0x76,0x9d,0xc9,0x02,0x6a,0x8d,0xd5,0x84,0xd5,0xa7,0x7c,0x70,0x64,0x46,0xd6,0xff,0xc7,0x9f,0x2f,0xed,0xc1,0x5a,0xcb,0x56,0x12,0x31,0x9d,0xff,0x66
+.byte 0x9a,0xf8,0x50,0xc6,0x54,0xfd,0x8d,0x49,0x32,0x8c,0xdd,0x8c,0xbe,0x30,0x79,0xaf,0x1a,0xd5,0x28,0x1d,0x03,0x87,0x12,0x60,0x7a,0xcc,0xe6,0xe8,0x4e,0x21,0x5d,0xa3,0x06,0xfb,0xdf,0xf6,0x31,0xd6,0x10,0x3e,0xec,0x23,0x69,0xc7,0x7b,0xf6,0x78,0xa6,0xd1,0x8a,0x48,0xd9,0xdc,0x35,0x1f,0xd4,0xd5,0xf2,0xe1,0xa2,0x13,0x8a,0xec,0x12
+.byte 0xa7,0xf1,0x5d,0xb2,0xc3,0x6b,0x72,0xd4,0xea,0x4f,0x21,0xff,0x68,0x51,0x51,0xd9,0xd7,0x2f,0x28,0xd7,0xdf,0xbc,0x35,0x4f,0x49,0x7e,0xe7,0x21,0x82,0xd7,0x0c,0x7c,0xf4,0x86,0x86,0x62,0xcd,0xf5,0x23,0x77,0xc1,0x14,0x8a,0xc4,0x2a,0x82,0x74,0x0e,0x90,0x93,0xd5,0x5a,0xc0,0x57,0x93,0x1a,0xe1,0x1c,0x13,0x17,0x72,0xc3,0xa6,0x54
+.byte 0xc4,0xe2,0xfc,0xd3,0xa0,0xce,0x08,0x87,0x9e,0x2a,0xaf,0xa7,0xbb,0x2d,0xaf,0xc0,0x38,0x97,0xc8,0x6d,0xb8,0x7b,0x75,0xc5,0xf2,0x79,0x62,0xdc,0x7c,0xa9,0xfd,0x19,0xa2,0xb1,0xee,0xdf,0x90,0x18,0x5a,0xdb,0x3c,0xba,0x0d,0x84,0xd6,0xaf,0x15,0xee,0xb6,0xa5,0x78,0x38,0x87,0xdf,0x42,0xd6,0xd1,0xa2,0xe9,0xe0,0xa6,0xf2,0x4e,0xa4
+.byte 0xed,0xa5,0xf6,0x66,0x7f,0x99,0xbc,0xfb,0x4b,0x37,0xca,0x5a,0xb3,0x29,0x8e,0x80,0x30,0x8b,0x74,0x7b,0xac,0x61,0xfb,0xca,0x62,0xfe,0x24,0xc4,0x6e,0xac,0x66,0x97,0xaa,0x9a,0x99,0xe6,0xa8,0xa4,0xd8,0x62,0x58,0x7c,0xd1,0xeb,0xee,0xc8,0x08,0xa0,0x54,0xde,0xb1,0xef,0x57,0x2c,0xb6,0x2c,0x78,0x22,0x10,0xbb,0xfe,0x4b,0x77,0xa5
+.byte 0x5a,0xed,0xbb,0xf8,0x97,0x96,0x20,0xa9,0x8c,0x78,0xb5,0xb9,0x55,0xc9,0xaf,0xb9,0xa1,0x1f,0x13,0x52,0xf9,0xbb,0xaa,0x98,0x01,0x57,0xa6,0x88,0xaa,0x5c,0xf0,0x62,0x5b,0x3e,0xe1,0x5f,0xf4,0x98,0x95,0x8b,0x8f,0x48,0xd6,0xd5,0x8b,0xc2,0x1d,0x45,0x7d,0xe2,0x03,0x66,0x84,0xfc,0xbd,0x8e,0x95,0x9f,0x58,0x99,0x7b,0x4c,0xb6,0xe5
+.byte 0xe2,0xf9,0x2e,0x92,0x58,0xca,0xa9,0x24,0x9c,0x7c,0x46,0xdf,0xea,0xb4,0x6e,0x0e,0xa5,0x9c,0x14,0xbf,0x25,0x5b,0x39,0x4a,0xaf,0x31,0xaa,0xd1,0x2c,0xe6,0x06,0x3d,0xc4,0x60,0xc7,0xcd,0x49,0x8d,0xe1,0x50,0x55,0xe4,0x72,0x68,0xed,0x43,0xb8,0x85,0xa3,0xc3,0xf1,0xf5,0xd1,0xcf,0xcb,0x57,0xac,0x04,0x16,0x22,0xe4,0xfc,0x4a,0x13
+.byte 0x60,0x3f,0x09,0xa4,0xf2,0x9b,0x34,0xeb,0x0c,0x10,0x57,0xc3,0x3f,0x15,0xb5,0x1b,0x6a,0xb3,0x7d,0x37,0x02,0x4c,0x0f,0x6f,0x8b,0x4d,0x5d,0x57,0x7d,0xbf,0x00,0x8a,0x74,0xb4,0x4c,0x5f,0x90,0x27,0x76,0x09,0x8c,0x18,0x3f,0x26,0x3a,0x09,0x06,0xdd,0x8b,0xff,0x0e,0xa4,0xae,0xef,0x0c,0x81,0xf2,0xf3,0x1f,0xe0,0x33,0x33,0x37,0xc6
+.byte 0xc3,0xfb,0x14,0xdd,0xa1,0x16,0x84,0x80,0xcb,0x37,0xe7,0x97,0x6d,0x21,0xa7,0x71,0x19,0x2b,0x2d,0x30,0xf5,0x89,0x2d,0x23,0x98,0xfc,0x60,0x64,0x4a,0x26,0x65,0x4a,0xef,0x12,0x59,0xa3,0x8c,0xd9,0xbd,0xdc,0xb7,0x67,0xc9,0x8d,0x51,0x72,0x56,0x6a,0xe5,0x59,0xa2,0x53,0x4f,0xb6,0x53,0xff,0xb0,0xd4,0x06,0x7f,0x79,0x23,0xf9,0xcb
+.byte 0xbf,0x9a,0x93,0xde,0x88,0x33,0x58,0x70,0xa7,0xcc,0x07,0xb1,0x44,0xb9,0x99,0x1f,0x0d,0xb9,0xc9,0x18,0xdc,0x3e,0x50,0x22,0xfb,0x4e,0x86,0x0d,0xc0,0xe7,0x7f,0xc6,0xa1,0x52,0x0d,0x8d,0x37,0xe6,0xaf,0xe3,0x13,0xbe,0xa6,0xf9,0x59,0x39,0x0f,0x17,0x66,0xce,0xb1,0x7d,0x7f,0x19,0x1a,0xf8,0x30,0x3a,0xa5,0x72,0x33,0xa4,0x03,0xb6
+.byte 0xb6,0x9b,0xde,0x7a,0x7a,0x62,0x3d,0x85,0x98,0x8e,0x5d,0x8a,0xca,0x03,0xc8,0x2c,0xae,0xf0,0xf7,0x43,0x3f,0x53,0xb2,0xbb,0x1d,0xd0,0xd4,0xa7,0xa9,0x48,0xfa,0x46,0x5e,0x44,0x35,0x50,0x55,0xdc,0xd5,0x30,0xf9,0x94,0xe6,0x5f,0x4a,0x72,0xc2,0x77,0x59,0x68,0x93,0x49,0xb8,0xba,0xb4,0x67,0xd8,0x27,0xda,0x6a,0x97,0x8b,0x37,0x7e
+.byte 0xe9,0x59,0x89,0xc7,0x5e,0xd9,0x32,0xe2,0xaa,0xd1,0xe9,0x2b,0x23,0xca,0x9d,0x89,0x7a,0xf5,0xe4,0xfb,0x29,0xcc,0x88,0xfb,0x82,0x0f,0xbf,0x47,0x54,0xca,0x2b,0x4b,0xd8,0x47,0x7f,0x65,0x38,0x5a,0xb3,0xe8,0x0b,0xd7,0xe1,0x8b,0x89,0x57,0x32,0xdb,0xa3,0x85,0xba,0xf9,0xbc,0x52,0x92,0x20,0x10,0x66,0x54,0x81,0xe1,0x49,0x3f,0xe1
+.byte 0x8c,0x2e,0x0b,0x3b,0xe7,0x49,0xb4,0x60,0x5a,0x20,0x33,0xc4,0x4e,0x81,0xef,0x96,0xda,0x73,0x90,0x2b,0xb4,0x86,0xa1,0x5c,0xcd,0xa0,0xc7,0xf3,0x06,0x0d,0x2a,0x5a,0x41,0x96,0xf5,0x40,0x1b,0x0a,0x3a,0xb7,0x38,0xe1,0xbb,0xe3,0x42,0xf9,0x52,0xe5,0x98,0xe2,0x17,0xd4,0xb0,0x09,0x73,0x75,0xc1,0x00,0x18,0x0f,0xa7,0x0b,0x58,0xc1
+.byte 0x78,0x5c,0x0c,0x05,0xd8,0xfb,0xc5,0xfd,0x5c,0x66,0xbe,0x54,0x68,0xd1,0x16,0x54,0xfb,0xc5,0x97,0xd7,0x03,0x82,0x47,0xbb,0x47,0xea,0x9e,0x8b,0x90,0x07,0xb2,0xd2,0x06,0x14,0x79,0xeb,0xb6,0xe1,0x10,0x55,0xa9,0x13,0xea,0x65,0x7a,0xd0,0xe5,0x66,0x5d,0xe7,0x7b,0x10,0x5f,0x7c,0x25,0x7d,0x4e,0x77,0xb3,0x19,0x02,0xb1,0x45,0x1c
+.byte 0x1a,0x51,0x24,0x72,0xd4,0xaa,0x03,0x0c,0x37,0x2a,0x78,0x81,0x05,0xca,0x73,0xb9,0xb5,0xd8,0xf5,0x25,0x2b,0x30,0x59,0x00,0x66,0xbd,0x6c,0x38,0xa2,0xc3,0xfb,0x43,0x85,0x6d,0xab,0xca,0xd8,0x73,0xa8,0x76,0xda,0x6e,0x00,0x19,0xd0,0xb9,0x1e,0x9b,0x33,0xe4,0x57,0x68,0xf4,0xb8,0x35,0x44,0xe6,0x74,0xd2,0x33,0x64,0xa1,0x41,0xa6
+.byte 0x5a,0xf6,0x8e,0x29,0xb5,0xa6,0x21,0x8e,0xc4,0x0c,0x0c,0x16,0x81,0x08,0xef,0x0a,0x41,0x08,0x34,0xc7,0xe1,0xd8,0xa8,0x68,0xb1,0xf3,0x9a,0x7a,0xaa,0x90,0xc0,0x77,0x32,0x70,0x50,0x5c,0x92,0xfc,0x38,0x31,0xaf,0x3e,0xd8,0xd8,0x4b,0x90,0x99,0xc4,0x17,0xde,0xa6,0xb5,0x29,0xc0,0x82,0x45,0x20,0x08,0x0c,0x4f,0x76,0x36,0x56,0x7e
+.byte 0x07,0x17,0x42,0x78,0xa1,0x2d,0x62,0x48,0x81,0x57,0xc4,0xcf,0xf4,0x89,0x34,0x78,0x10,0xe6,0x98,0x78,0xb0,0x69,0x15,0x06,0xdb,0x2b,0xbb,0x8b,0xa5,0x72,0x50,0x24,0xae,0x6b,0x33,0x49,0x7b,0x9d,0x69,0x74,0xc8,0x7c,0xca,0x7a,0x31,0x39,0x0d,0x72,0x78,0xc1,0x6b,0x97,0x50,0x97,0xea,0x90,0xab,0xe7,0xdf,0x29,0x2e,0xf7,0x6e,0x49
+.byte 0x95,0xab,0xbd,0xea,0x1f,0xd4,0x93,0x4d,0x30,0x6b,0x6d,0xb0,0x86,0x38,0x2c,0xc8,0x77,0x2c,0xb5,0xb5,0x5c,0xd9,0xbb,0xe9,0x7d,0xb2,0xb7,0x6b,0xd1,0x1c,0xd3,0xd0,0x66,0x51,0x63,0x8c,0xf3,0x13,0xad,0xcf,0xeb,0x82,0x12,0x1a,0x6d,0xf5,0x75,0x66,0xa2,0x55,0x30,0x64,0x1d,0x68,0x46,0x50,0x5a,0x93,0xf1,0xc2,0x13,0x68,0x95,0x55
+.byte 0x51,0xe0,0x56,0x3a,0x96,0x86,0x8e,0xfb,0x5f,0x3b,0x1f,0x49,0x9c,0x3d,0xe5,0xf2,0x8c,0x3f,0xd6,0x6d,0x17,0xc7,0x18,0x59,0x1a,0x8a,0x72,0xa8,0xb3,0x39,0xda,0xc4,0xfa,0xc5,0xca,0xdf,0x48,0x48,0xd1,0xd2,0xba,0x14,0x5d,0x28,0x3b,0x4c,0xb3,0xcb,0x8d,0x1b,0x91,0x46,0x6b,0x2d,0x21,0x21,0x99,0x98,0x6d,0xcc,0x6b,0x8e,0x91,0x1d
+.byte 0x42,0xc2,0x72,0x1a,0xc6,0xd2,0xaf,0xed,0x10,0xff,0x1e,0xa5,0xae,0x16,0xc0,0x05,0xdf,0x37,0xe2,0x1e,0x2e,0x15,0x21,0x0c,0x33,0x6f,0xfd,0xed,0x3f,0x7e,0xd7,0x69,0xfb,0x76,0x79,0x65,0xe9,0xd9,0x8d,0xf6,0xc0,0x6c,0xf7,0x15,0x7f,0x04,0xd7,0x71,0xcc,0xaa,0x85,0x73,0x23,0xf1,0xc8,0x62,0xd0,0x8e,0x01,0x35,0xff,0x4f,0x4f,0x13
+.byte 0xe6,0x28,0xf1,0xc1,0x7a,0x04,0xc0,0x7b,0x75,0xac,0x1c,0x55,0xb4,0x7c,0x00,0xb9,0xe0,0x14,0x67,0xb6,0xc5,0x69,0x62,0x0b,0xe6,0xb5,0x46,0x86,0x6f,0x09,0xdf,0x84,0x2c,0xa8,0x30,0x89,0x5b,0x24,0x47,0xfa,0x43,0x24,0xd5,0x07,0xf7,0xba,0xab,0x1b,0xfd,0x60,0xad,0x89,0x5f,0x60,0x87,0x78,0x48,0xbb,0xc0,0x63,0xf4,0x27,0x86,0x33
+.byte 0xf4,0x49,0x64,0x4c,0x5c,0x94,0x9a,0xb8,0x0f,0x45,0xe2,0x92,0x7d,0x9a,0x86,0xdb,0xb7,0x05,0xe8,0xd7,0x64,0x44,0xfa,0x74,0x60,0x72,0x89,0x13,0x8f,0x2e,0x96,0x33,0xa9,0x12,0x4a,0x62,0x6b,0xc3,0xcb,0x55,0xd3,0xef,0x17,0x11,0x82,0x4a,0x51,0x77,0xbf,0x63,0xa0,0x21,0xfc,0xbc,0x0c,0x6f,0x9a,0xfd,0xde,0xbe,0x9f,0x2e,0x50,0xd5
+.byte 0x32,0xa4,0xf0,0x1b,0xed,0xfa,0xbf,0xcd,0xc9,0xd8,0xf8,0x06,0xf2,0x17,0x8a,0x92,0x18,0xb8,0xc3,0xe5,0xbf,0xc2,0xf4,0x77,0xb9,0x71,0xfb,0x60,0x6e,0xe7,0xad,0xe4,0x7d,0xd4,0x59,0xa9,0xbd,0x21,0xd5,0x03,0x69,0xb5,0xf1,0xce,0xb5,0x88,0xd9,0x1d,0xc7,0xb3,0x14,0xa6,0xb1,0x30,0x8d,0xaa,0xcd,0xe5,0x50,0xc5,0x0d,0x4b,0x6d,0xde
+.byte 0x17,0x4d,0xd2,0x93,0xf3,0xc2,0x8d,0x59,0xf1,0xd0,0x2f,0xb5,0x62,0x18,0x81,0x07,0xb3,0xfb,0x08,0xb3,0xa8,0x15,0xe0,0x9a,0x4c,0xa5,0x24,0xcd,0x47,0x69,0xf9,0xf7,0xda,0xa9,0xff,0xe1,0xe2,0x43,0xe3,0x69,0xf1,0x26,0xac,0xc6,0x42,0xf2,0x32,0x42,0xfb,0x7c,0xa2,0x94,0xc6,0xaa,0xd9,0x05,0x29,0xc6,0x3d,0x45,0x44,0x1d,0x52,0x7e
+.byte 0x48,0x47,0x93,0x34,0x08,0xa0,0x93,0xc2,0x5e,0x9b,0x22,0xc1,0x2a,0xaa,0xfe,0xa2,0x26,0x00,0xa8,0xbb,0xd0,0x58,0xfd,0x5a,0x09,0x4f,0xa1,0x0c,0xff,0x66,0xcc,0x88,0x3a,0x69,0x9a,0x12,0xb6,0x05,0x6e,0xdf,0x54,0x5d,0xe7,0x03,0x8e,0x95,0x86,0x68,0x83,0x83,0x6f,0x04,0x0b,0x9c,0x05,0x05,0x77,0x14,0x83,0x47,0x98,0x5f,0x22,0xaf
+.byte 0xa8,0xfd,0xf3,0xe7,0x73,0xec,0xef,0xd7,0x57,0xd9,0xef,0xe7,0x1b,0x18,0x24,0x09,0xd9,0x14,0xf9,0x60,0xba,0x05,0x0f,0x8f,0x33,0x48,0xb1,0x06,0x41,0x2e,0x95,0x3d,0xf5,0xcf,0x14,0x50,0x5d,0xb6,0x93,0xeb,0xd5,0xf8,0x9f,0x7c,0x8f,0x23,0x35,0x39,0x30,0xc8,0xf6,0x74,0x07,0xc4,0x4c,0xcf,0xe1,0xdb,0x3e,0x9f,0x0a,0xfd,0x48,0x9e
+.byte 0x56,0xe4,0xa7,0xa3,0x07,0x06,0x18,0xbb,0x50,0x75,0x33,0x48,0xb9,0xa1,0x4e,0x63,0x65,0xd3,0xf4,0x40,0xc3,0x2d,0x52,0x9a,0xad,0x56,0x7f,0xff,0xb0,0x46,0x24,0xa1,0x78,0x5f,0xb6,0xa8,0x72,0x28,0xb3,0x6c,0x61,0x6e,0xa0,0xfc,0xcb,0xe8,0xfe,0x07,0x28,0x97,0x1c,0xda,0x76,0xc7,0x98,0x2f,0x00,0x1d,0xf2,0x17,0xbe,0x48,0x3f,0xd3
+.byte 0xc7,0xbe,0x89,0x89,0xe1,0x96,0x75,0x1e,0xee,0xf9,0x78,0x67,0xbf,0x12,0x1e,0xe2,0x14,0xbf,0xd4,0xfd,0x49,0xaa,0xbf,0xc6,0xb8,0x4f,0x84,0xcd,0x5d,0x3c,0x45,0xb3,0xb0,0x14,0x6f,0x2d,0x6f,0x35,0xfa,0x60,0x7f,0x64,0x40,0xc8,0xde,0xa8,0x2b,0x56,0x75,0x74,0xc9,0xe1,0x2c,0xe2,0x2f,0xc2,0x3e,0xba,0xa3,0x20,0xd8,0xa3,0xbc,0x69
+.byte 0x9d,0x1c,0xcf,0x5e,0xe3,0xc0,0x66,0x72,0xce,0x22,0x96,0xad,0x47,0xc9,0x5b,0xac,0x45,0xdc,0x4f,0x8e,0xf6,0xa6,0x2e,0x4a,0x1e,0x01,0xe4,0xb7,0x83,0x68,0x92,0x2b,0x98,0xdf,0x22,0x0f,0xd9,0x4f,0x6f,0x72,0x37,0x56,0xfa,0x1b,0xbb,0x5a,0x4d,0xd8,0x5b,0xc6,0x65,0xf8,0xd4,0x4e,0xa5,0xc0,0x0f,0x2d,0xc2,0x38,0xa4,0x6c,0x33,0x2f
+.byte 0x7a,0x52,0x14,0xbb,0xfb,0xb3,0xf2,0xa9,0xbf,0xa0,0xad,0xcb,0x8c,0x81,0x47,0x26,0xe9,0xfb,0xc1,0x8e,0xc6,0xe5,0x39,0x48,0xa5,0xb3,0xbc,0xb2,0xe4,0xac,0xf9,0x49,0xbb,0x34,0x2b,0xc4,0x4d,0x06,0xe4,0xd6,0x0b,0xdd,0x55,0x36,0xe6,0xaf,0x64,0xea,0x84,0xf2,0xa5,0x68,0xe3,0x4e,0x4c,0x77,0x46,0x6c,0x17,0x6e,0x08,0x99,0x96,0x1b
+.byte 0xb5,0x44,0x3b,0x94,0x2d,0x0f,0xcd,0x90,0x17,0x8f,0x80,0xcb,0xc2,0x30,0xbe,0xe1,0x36,0xdc,0x1e,0x48,0xe3,0x2c,0xe5,0xc9,0xbc,0xbd,0xff,0x3f,0x95,0x59,0x35,0x58,0x2f,0x9c,0xa6,0x1c,0x45,0xa7,0x61,0xde,0xf2,0x9c,0xa3,0x04,0x0f,0xa0,0x93,0xaf,0x69,0x2b,0x0d,0x1c,0xfc,0xff,0x97,0x1c,0x69,0x7e,0x30,0x06,0x88,0x01,0xa4,0xf1
+.byte 0x32,0x36,0xed,0x56,0x89,0xff,0xa9,0x63,0x3a,0x17,0x91,0xc5,0xba,0x6e,0x38,0x84,0xb1,0xaf,0x28,0xac,0x8a,0xb2,0x60,0xbe,0x1b,0x0a,0xd8,0x05,0x22,0x25,0x56,0xbe,0x75,0x47,0x59,0xcf,0x8c,0x2e,0xb3,0xc3,0x5f,0x06,0x81,0x65,0x39,0x78,0xed,0xe3,0xc9,0x5a,0x99,0x01,0xae,0xfb,0xf6,0xed,0x55,0xf5,0xbd,0x2f,0x93,0xf1,0x62,0x6a
+.byte 0x54,0x4f,0xe1,0x9f,0x0a,0x23,0x83,0xbc,0xc2,0xba,0xb4,0x6f,0xd9,0x88,0xc5,0x06,0x7a,0x83,0xd5,0xdb,0xeb,0x49,0x48,0xd6,0xc9,0x45,0xa2,0xd0,0xc4,0x06,0xd9,0x01,0xec,0x2d,0x6d,0xc1,0x95,0x69,0x22,0xd0,0xae,0x88,0x75,0x8b,0xd2,0x02,0x98,0x83,0xd9,0x10,0x27,0x8d,0x68,0x97,0x5e,0x6b,0xdd,0x51,0xbb,0x92,0x38,0xa8,0x12,0xde
+.byte 0x0f,0xa4,0x1e,0x2e,0xec,0xd5,0x73,0x55,0x5f,0x46,0x6a,0x0f,0xc9,0x50,0x0d,0xb3,0x55,0x20,0xe0,0x01,0xef,0x92,0x29,0x04,0x38,0x60,0xbd,0xc7,0x0b,0x1e,0x94,0x10,0x37,0xb7,0x02,0x94,0xbc,0xde,0xdb,0xb3,0xe3,0x1e,0xd5,0xe2,0xa8,0xed,0x46,0xe8,0xd4,0x8a,0x6c,0x93,0x4e,0xb7,0x73,0xa6,0x20,0x86,0xd2,0x82,0x2f,0x78,0x80,0x34
+.byte 0x44,0x79,0x84,0x2e,0x54,0xd0,0x30,0xa8,0x06,0x0c,0xcf,0x78,0xb4,0xd7,0xe2,0xc9,0x6e,0xfb,0x37,0x47,0x8f,0xe5,0x9f,0xf8,0xca,0x58,0x9c,0xb6,0x8b,0xbe,0xf4,0x3a,0xfe,0x75,0xec,0x1b,0x22,0xfd,0x93,0x92,0x07,0x09,0xcd,0xe6,0x2f,0xe6,0x51,0x0f,0x19,0x43,0x9c,0x6a,0x32,0x38,0x7d,0xf0,0x0c,0x78,0x81,0xb7,0x5c,0xbe,0x3c,0xf4
+.byte 0xc0,0x12,0x57,0x51,0x8a,0x69,0x84,0x0d,0x1e,0x0a,0xed,0x75,0xde,0x9e,0x31,0x8a,0x9b,0x18,0x82,0x01,0x5a,0xee,0x0e,0x33,0x3c,0x8c,0x95,0xb1,0x0b,0x05,0x3b,0xb2,0x85,0xab,0xaf,0x47,0xa2,0x03,0xb6,0xbb,0xda,0xf5,0xc8,0xbe,0x0e,0x4d,0xf8,0x84,0xe4,0xfb,0xd4,0x54,0x44,0x72,0xe5,0x30,0x57,0xa3,0xb6,0x47,0x8f,0xd3,0x32,0xc2
+.byte 0x83,0x07,0x4f,0x17,0x20,0x88,0xa1,0x0b,0xb3,0xef,0x4b,0x27,0x60,0xe0,0x9d,0xec,0xc2,0xdf,0xaf,0x2e,0x74,0xae,0xa4,0x2b,0x59,0x94,0x75,0xbe,0x54,0xf5,0x18,0x62,0xd9,0xe2,0x35,0xee,0x37,0x2e,0xdf,0x48,0xf8,0x80,0x32,0xcb,0xf1,0x83,0x78,0x03,0x68,0x06,0xd7,0x82,0xc6,0x76,0x2a,0x10,0x2a,0xdb,0x73,0xe6,0x65,0x24,0x9f,0x73
+.byte 0x1f,0x55,0x55,0xb6,0x10,0x65,0x80,0x70,0x5a,0x8e,0x8a,0xc8,0x4c,0xca,0x74,0x47,0x63,0x3f,0xee,0x49,0xc3,0x86,0x0f,0x66,0x56,0x08,0xee,0x9f,0xf5,0x5a,0x89,0x4c,0xb4,0x97,0x6e,0x75,0x61,0xc0,0xa7,0x92,0xa8,0x38,0x99,0x08,0x01,0x12,0x82,0x77,0x80,0x20,0x9d,0x62,0x46,0x92,0xdd,0x39,0x4d,0xcf,0xc0,0x8a,0x3e,0x30,0x9a,0xfa
+.byte 0x28,0xe8,0xd8,0xf8,0x07,0x0d,0xab,0x4c,0xd4,0x02,0x4c,0xd7,0xc3,0x16,0x89,0x24,0x84,0x52,0x7c,0xa4,0x1b,0x54,0x7f,0xc4,0x74,0x4f,0x88,0x0a,0x14,0x03,0xd9,0x1a,0x48,0xff,0x2c,0xfb,0xbf,0x33,0xf1,0xf8,0x0e,0xdd,0xc4,0x98,0xf2,0xbd,0x32,0x99,0x03,0x8e,0x56,0xc1,0x84,0x5d,0xa6,0xd7,0x21,0xf2,0x43,0xfb,0x3b,0xf5,0x6a,0x75
+.byte 0x20,0xfb,0x08,0x7b,0x66,0x15,0x47,0x31,0xb6,0xb6,0x7a,0xc9,0xe6,0xf5,0xd6,0x0a,0x14,0xb3,0x68,0x0a,0x32,0x13,0xb5,0xe6,0x56,0xbd,0xa5,0x24,0xe2,0xa3,0x7b,0x3d,0x01,0x23,0xed,0x08,0x09,0xb5,0xdb,0x7c,0xa9,0x4b,0x23,0xdb,0xa2,0x25,0x0c,0xc6,0xa4,0x0d,0xbb,0x1a,0x5d,0x1b,0x42,0x0b,0x86,0x72,0xc3,0xca,0x5b,0x14,0x04,0xa3
+.byte 0xd7,0x01,0xe7,0x17,0x78,0xd0,0x54,0xde,0xd4,0x76,0x3d,0xe1,0x7d,0x26,0x3e,0xb4,0x71,0x42,0x84,0x36,0x58,0x78,0x22,0x32,0x26,0x0e,0xc8,0x99,0x05,0xe3,0x4a,0xa6,0x5a,0x1a,0x06,0x0a,0x88,0x47,0x51,0x5c,0xa8,0x72,0x70,0x0c,0x62,0x5f,0xf3,0x1e,0x02,0x50,0x20,0xc6,0x5c,0x50,0x30,0x1f,0x4e,0x5a,0x3a,0x02,0xc9,0xca,0x3f,0xa4
+.byte 0xf1,0x66,0x05,0xf3,0x19,0xe5,0xaa,0xdb,0x75,0x51,0xc1,0xb8,0x94,0xfa,0x2d,0xb6,0x8b,0x42,0xdc,0x9a,0xa3,0x13,0xeb,0x95,0x8d,0xf0,0x65,0x87,0xc9,0xa1,0x43,0xb4,0xfe,0x76,0xf4,0xc8,0xbb,0x19,0x96,0x84,0x9d,0x2f,0x92,0xe8,0x22,0x9a,0xf0,0xd5,0xf4,0xc4,0x8d,0x19,0x59,0x21,0xbf,0x15,0xfd,0xa6,0xc4,0xde,0x77,0x58,0xae,0x93
+.byte 0xb3,0xff,0x44,0x49,0x6e,0x37,0x94,0x04,0xd2,0x96,0xe9,0x80,0xd8,0xe3,0x93,0xd8,0xb4,0x7f,0x5f,0xcf,0xe5,0x9d,0x51,0x92,0xac,0x5d,0x9f,0x23,0x3a,0x3e,0xdf,0x96,0x68,0x9a,0x46,0x9b,0x1a,0x06,0x44,0x54,0xc4,0x2e,0x19,0x0f,0x50,0xee,0x73,0xda,0x39,0x7e,0xec,0xcb,0x1d,0x39,0xf7,0x9f,0xbc,0xe0,0x6d,0x49,0x56,0xf8,0xa7,0x24
+.byte 0x70,0xab,0xe1,0xc3,0x82,0x99,0x0a,0x4d,0x64,0x41,0x37,0xab,0x92,0x76,0xeb,0x6a,0x2a,0xa5,0xab,0x75,0xd7,0xe3,0x6a,0x72,0x4a,0x2b,0x57,0x02,0xc7,0xbe,0xd5,0x35,0xce,0xdf,0xee,0xf1,0xc6,0xe6,0x69,0xb7,0x76,0x99,0x22,0xb0,0xb9,0xe1,0x18,0x91,0x9a,0x35,0xd9,0x3a,0x19,0xc7,0x77,0xf2,0x2d,0xae,0x04,0x2e,0xb7,0x35,0x97,0xa5
+.byte 0xc6,0x97,0x4e,0x5d,0xbe,0xa9,0x35,0x2b,0x53,0x1a,0x6b,0x4e,0xa8,0xa6,0x22,0x48,0x2c,0x81,0x25,0xac,0x30,0x89,0x7b,0xb3,0x38,0x34,0x42,0x0b,0xa5,0x5f,0x02,0xe8,0xee,0x12,0x9b,0xce,0xe7,0x10,0xf9,0x65,0xb6,0xc5,0x74,0x06,0xef,0xc8,0x95,0xb3,0x40,0x30,0xec,0x1f,0x8e,0xeb,0x93,0x31,0x91,0x5a,0x2f,0xc2,0x90,0x85,0xaa,0x4c
+.byte 0x51,0xc4,0xd0,0x3e,0xc8,0xc9,0x61,0x46,0x96,0xd4,0x60,0x56,0x7d,0x91,0xc4,0x24,0x76,0xfb,0x09,0x08,0x48,0x2f,0x4a,0x73,0x90,0x8e,0x9d,0xb2,0x38,0xa8,0x95,0x3e,0x6d,0x10,0x57,0x91,0x8d,0x55,0x62,0x1f,0x21,0xc7,0x01,0x15,0xb0,0x71,0x0b,0x26,0xbc,0x10,0x33,0x3e,0x79,0x37,0x64,0x85,0x98,0x42,0x21,0xcc,0xff,0x51,0x9a,0xc2
+.byte 0xe0,0x51,0xc3,0xff,0xf2,0x14,0x3d,0xe8,0x89,0x12,0xe7,0xcd,0x58,0x2f,0x87,0xfb,0x4a,0x50,0x6c,0x4d,0xdf,0x6f,0x64,0x9c,0x64,0x93,0x49,0x89,0xb6,0x0d,0x10,0x3f,0x13,0x9d,0x9a,0x35,0xf1,0xc0,0xe7,0xf0,0x9b,0xe8,0x39,0xd3,0x32,0xb2,0x23,0x67,0x77,0xdb,0xbc,0x0d,0x19,0x77,0x7a,0xbe,0x54,0x56,0x64,0xec,0xb6,0x2e,0x03,0xc5
+.byte 0x35,0xda,0xf1,0xc7,0x7d,0x0c,0x5a,0x32,0xec,0x86,0xdf,0xdb,0x94,0x73,0x4e,0xe3,0x45,0xf6,0xb2,0x63,0xc4,0xb7,0x80,0x59,0x4b,0x82,0x0b,0x61,0xa0,0xd5,0x43,0x18,0x78,0x35,0x93,0xde,0x46,0xa3,0xa2,0xd5,0xa2,0x71,0xec,0x3e,0xee,0x7a,0x89,0x7f,0xe9,0x70,0xff,0xad,0xae,0xa3,0x64,0xde,0x61,0xea,0x71,0xc2,0x37,0x98,0x8a,0x33
+.byte 0xd1,0x5f,0x03,0x08,0x23,0x24,0xc7,0x6c,0x62,0x24,0x6d,0x3f,0x44,0x8e,0x7c,0x9f,0x64,0x87,0xa5,0x79,0x0b,0x16,0x7e,0x4e,0xc0,0x0e,0xb8,0x77,0x56,0x9c,0xa5,0x7d,0x2d,0x5d,0x7d,0x81,0x13,0x2c,0x08,0xd5,0x83,0x84,0x38,0xfe,0x50,0x6f,0xa7,0x30,0x1f,0x06,0xee,0xab,0x13,0xc2,0x19,0xe6,0xcf,0x7b,0x85,0xfc,0x31,0x5b,0xdf,0xb8
+.byte 0x0e,0xe8,0x72,0xba,0x97,0x03,0x25,0xbc,0xad,0x74,0x7c,0xe1,0x59,0xf7,0x08,0xc1,0xe3,0x2d,0xb1,0x05,0xe7,0x1f,0xb9,0x0f,0x09,0xcd,0xe6,0x4f,0x5a,0xf6,0xcc,0xea,0xc7,0x92,0x35,0xf5,0xbc,0x3f,0xef,0xc9,0x2b,0xb4,0xd7,0x66,0x50,0xaa,0x80,0xb9,0xaf,0x5d,0x02,0x9c,0x77,0xdf,0xc0,0xc7,0xe2,0xbf,0x7d,0xff,0x69,0x63,0x3e,0x7c
+.byte 0x91,0x94,0xae,0xa4,0x0a,0x25,0xa3,0x1f,0xf3,0xc6,0x88,0xda,0x82,0xac,0xbc,0x1f,0x8d,0x53,0xd6,0xfd,0x2b,0x5c,0x33,0x6d,0x03,0x68,0x92,0x38,0x07,0xeb,0x85,0x7f,0x55,0x89,0x17,0x58,0x7f,0xc7,0xb4,0x7a,0xff,0x15,0xe5,0xe0,0xea,0xce,0xac,0x3f,0x0f,0x09,0x25,0xfa,0x80,0xe3,0x07,0x89,0x4e,0xbf,0x7e,0xc2,0x42,0xf1,0x18,0x78
+.byte 0x05,0xe3,0x6a,0x2e,0xf7,0x2e,0xe5,0xbf,0x63,0x9e,0x48,0x69,0xe6,0x3c,0x4b,0x12,0x73,0x58,0xde,0x0c,0x73,0x27,0x9a,0x95,0xfa,0x51,0x8c,0xbb,0x74,0x31,0x53,0x4e,0x9a,0x13,0xda,0x49,0xf0,0x8b,0xb4,0xcd,0xc1,0xe9,0xaf,0xd6,0x59,0x59,0xa8,0x24,0x94,0xd9,0x4b,0xf8,0x20,0x79,0xa0,0x79,0x01,0x08,0x84,0x9b,0x04,0xe7,0xda,0x06
+.byte 0x22,0x3e,0x85,0x23,0x0c,0xa9,0xe5,0xcd,0xd3,0xc4,0x27,0x8c,0x4e,0x75,0xe4,0x60,0xb5,0xe9,0xc5,0xb7,0xb1,0x3a,0x84,0x68,0x40,0x3e,0x36,0x1b,0x9a,0x64,0x50,0x45,0x6f,0xc6,0x58,0x70,0x46,0x1a,0xca,0xf6,0x81,0x02,0xa8,0x17,0x4d,0x92,0x0d,0xae,0x88,0x1a,0xbd,0x52,0xc0,0x32,0xb1,0x2d,0x2d,0x12,0x9c,0x29,0xfa,0xa6,0x70,0x5f
+.byte 0xe7,0x0b,0xd5,0x5d,0xa5,0x49,0x9e,0x9e,0x5b,0x55,0xbc,0xce,0x5b,0xb4,0xef,0x3f,0xe4,0x7c,0x50,0xef,0x58,0xf5,0xfe,0xcc,0xf6,0xd0,0xf1,0x3a,0x0b,0xf2,0x3e,0x1c,0xce,0x22,0x7e,0x88,0x1c,0x8f,0x9a,0x69,0x76,0xa9,0xf0,0x18,0xa8,0x76,0x7f,0x0c,0xa6,0xfd,0x67,0x43,0xc7,0x43,0x67,0x98,0x6e,0x37,0xd4,0x82,0x29,0x62,0xa6,0xcf
+.byte 0x2b,0x7c,0xee,0x14,0x4d,0x2d,0x1a,0xfc,0xc6,0xaf,0x5b,0xea,0x8a,0xa8,0x9a,0x3b,0xab,0x7d,0x76,0x15,0x50,0xe8,0x95,0x31,0xc8,0x5d,0x5d,0x19,0x68,0x07,0xf5,0xb0,0x29,0x5f,0x79,0x4f,0x0d,0x2b,0xba,0x1d,0xd2,0xf2,0x83,0x50,0x89,0x0b,0x96,0x16,0xde,0x7c,0x04,0xea,0x9c,0x75,0x97,0x7e,0xd7,0x2c,0xee,0x82,0x7c,0xbf,0x0b,0x71
+.byte 0x05,0x59,0xd7,0x11,0x70,0x8e,0x41,0x62,0x91,0x38,0x3a,0x69,0x3f,0x3d,0xde,0x8e,0x03,0x0a,0xea,0xfb,0xea,0x36,0xf0,0x5c,0xb6,0xdf,0x9a,0x66,0x9e,0x64,0x43,0xaf,0xb7,0x83,0xd1,0xef,0x7c,0xb6,0x9b,0x40,0xd8,0x0f,0x0e,0x0b,0xa7,0xd0,0x98,0xca,0x8e,0x3b,0xed,0xb7,0xa5,0x19,0xca,0x67,0x30,0x87,0x17,0x0e,0xc4,0xe1,0xaa,0x6e
+.byte 0xdb,0x67,0xbd,0xf5,0xed,0x10,0x68,0xb1,0x43,0x73,0xaa,0x99,0x1a,0x83,0x0d,0x1a,0x5a,0x8b,0xc8,0xff,0xe9,0xe0,0x1c,0x15,0xda,0xb0,0x99,0x90,0xce,0x1f,0xfd,0x17,0xd2,0xfa,0x8f,0x3a,0xe8,0x1b,0xd3,0x96,0x2a,0x0d,0xa9,0x4d,0x6d,0x77,0x53,0xe8,0x8f,0xc7,0x6b,0xb4,0x3b,0x6d,0x0c,0x8e,0x35,0x67,0x09,0x6e,0x43,0x36,0x52,0x3e
+.byte 0x0e,0xf6,0x4f,0x16,0x40,0x45,0x7f,0xab,0x39,0xf2,0x23,0xfb,0x4e,0xea,0x6e,0xcf,0xa0,0xb6,0xec,0x6d,0x93,0x1b,0x6f,0x9f,0xd6,0xce,0xcd,0x1e,0x90,0x5c,0x7d,0x61,0xc4,0xae,0x02,0xb2,0x7a,0xb2,0x25,0x59,0xac,0x0a,0xcb,0xc6,0x28,0xa2,0x9c,0x7b,0x4b,0x05,0x5a,0x23,0x55,0xc8,0x9a,0x72,0xe6,0x3b,0x91,0xa2,0x9b,0x12,0x1c,0x1f
+.byte 0x4b,0x85,0x42,0x9d,0x73,0xf9,0x50,0x3e,0x12,0xc4,0x51,0xb4,0xe1,0x2a,0x08,0xfc,0xf9,0xc8,0x5a,0x53,0x79,0xcc,0xd1,0x24,0x4c,0xc1,0xf6,0xe7,0x10,0x9d,0xe6,0xce,0xcc,0xc7,0x04,0xf8,0x7a,0xd4,0x2f,0x0a,0x97,0x32,0xaf,0x38,0x77,0x97,0x78,0xc8,0xa9,0x9a,0xca,0x65,0xee,0x2b,0x07,0x0e,0xb1,0xaa,0x3c,0xee,0x03,0x85,0xf7,0x09
+.byte 0xd1,0x03,0xe5,0x4f,0x8a,0x6b,0xba,0x83,0xd2,0x6a,0x05,0xe6,0x4e,0x59,0x21,0x26,0xcc,0x8d,0x4a,0x91,0x21,0x6b,0xe5,0x7a,0x83,0xed,0x4e,0x95,0x4b,0x16,0x98,0x3f,0x2d,0x51,0xc5,0x67,0x56,0x58,0xc9,0xc3,0x32,0xff,0x91,0x9d,0x7f,0x6d,0xc7,0x8a,0x40,0x58,0x56,0x35,0xca,0xc1,0xa9,0x07,0xe2,0xc6,0xe1,0x8f,0x7b,0x7c,0x68,0x4e
+.byte 0xde,0x19,0xc8,0x9c,0x41,0x65,0x74,0x33,0xb5,0x5b,0xf7,0x47,0x91,0x51,0x41,0x56,0x54,0xaa,0x8e,0xa5,0x1f,0xdb,0x50,0xa4,0x97,0x7a,0xea,0x86,0x2e,0xfd,0xdd,0x64,0x23,0x6e,0x44,0x28,0xfb,0xae,0xe8,0xc2,0x38,0x96,0x56,0x2e,0xd8,0x7e,0x3a,0xc8,0xc6,0x7f,0x20,0x15,0xad,0x9f,0xfa,0x5c,0x55,0xf5,0xe1,0x9a,0x07,0x84,0x5b,0x81
+.byte 0x39,0x4b,0x70,0xc3,0xfd,0x2b,0xc5,0xb7,0x47,0x36,0x74,0x5a,0x85,0xaa,0x45,0x94,0x8e,0xbe,0x7f,0x6c,0x45,0xf5,0x02,0x4e,0x5f,0x16,0x04,0x7e,0xfa,0xb8,0xa9,0x38,0xc4,0xd9,0xca,0x5f,0x7a,0xe3,0x96,0x78,0x82,0xa0,0xac,0xef,0xc4,0x2a,0xb5,0xf4,0x7d,0x28,0x8c,0x25,0xba,0x4e,0xd5,0xd5,0xd1,0x24,0xc6,0x05,0xb2,0x18,0x2d,0x66
+.byte 0xea,0xe3,0x42,0x79,0x33,0x9e,0x70,0x3a,0x1b,0x5a,0x8e,0xcb,0x03,0xa8,0x43,0xf3,0xd5,0x66,0x41,0x10,0xd7,0x09,0xf0,0x28,0xe5,0x25,0xe6,0xac,0x9a,0xe6,0x34,0x36,0xfb,0xc4,0xa6,0x9a,0xd0,0x24,0x4d,0x18,0xf9,0xd1,0x8e,0xca,0x92,0x83,0x0f,0x55,0x54,0x6d,0x72,0x81,0x81,0xdb,0x72,0x1f,0xd6,0x32,0xb9,0x32,0x45,0x84,0x9c,0x66
+.byte 0x68,0x7e,0xab,0xb3,0xca,0xf5,0x4f,0xdd,0xb4,0xee,0xbb,0x05,0x70,0xbe,0x4f,0xd1,0x27,0x01,0xcc,0x7c,0x4f,0x47,0x55,0xce,0x91,0x73,0x6f,0xff,0x8d,0xfc,0x0c,0x4c,0xaa,0xfc,0xce,0x9f,0xf3,0x4a,0x46,0x92,0x89,0x84,0x8f,0x4d,0x94,0x37,0xda,0xe3,0x11,0x0d,0x63,0x60,0xcb,0x40,0x8f,0xe8,0x0f,0xf9,0xa1,0x89,0x64,0x44,0x45,0x74
+.byte 0xc5,0xa2,0x73,0x33,0x08,0xa2,0x59,0xb0,0xeb,0x7b,0x7b,0xa7,0x28,0x4c,0x13,0x6a,0x04,0x15,0x14,0xd0,0x3e,0x5e,0xec,0xe1,0x3f,0xe5,0x93,0x06,0x6b,0x60,0x50,0x1c,0x90,0xc0,0x5c,0xea,0x7e,0x58,0xf1,0xed,0xba,0x43,0x0b,0x84,0xf7,0xa4,0xbd,0x4c,0xed,0x88,0x5b,0xae,0xa2,0x0a,0xf6,0x06,0xfd,0x43,0x63,0xfe,0x8a,0x03,0x21,0x8b
+.byte 0x27,0xc6,0xef,0xa3,0xa9,0x3a,0xc1,0x8b,0x65,0x62,0x25,0x85,0xaa,0x2f,0xff,0x22,0x96,0xb7,0x5c,0x82,0xde,0x21,0x4e,0x0d,0x8d,0xd9,0x7f,0x97,0x79,0x95,0x6c,0xe6,0xfd,0xb1,0x7c,0x84,0xc8,0x73,0xbc,0x50,0x2f,0x87,0x03,0x56,0xcf,0xea,0x7f,0xed,0x17,0x7d,0xf7,0x61,0x6b,0x6f,0x5b,0xd3,0xe4,0x83,0xbd,0x8b,0xd3,0x8e,0x51,0x57
+.byte 0x3d,0xcc,0xe4,0x09,0xb9,0x73,0x1f,0xb4,0x47,0x5e,0xf2,0x10,0x3e,0xf4,0x9c,0x86,0x02,0xdf,0x3e,0x75,0x1c,0x9b,0xb5,0x0f,0x31,0xc6,0xbb,0x00,0xb4,0x8a,0x1a,0xe5,0x0d,0x9c,0x3e,0x93,0x61,0x5a,0x61,0x86,0x12,0x64,0xaa,0xfd,0xa2,0x6e,0x8f,0xcc,0xcd,0x60,0xa1,0xad,0x6d,0xdc,0xa2,0x7b,0x5a,0xe0,0xee,0x27,0x5d,0xc5,0xfe,0x1f
+.byte 0x7b,0x9f,0x33,0xf1,0xee,0x2a,0x58,0x39,0x56,0x14,0x4f,0x2f,0x11,0x26,0x6b,0x56,0x7c,0x75,0xb7,0xc3,0xa7,0xf6,0x54,0xd8,0xa7,0xbb,0x73,0xb5,0xa5,0x83,0x1e,0x65,0x7e,0xa7,0x85,0x74,0xa4,0x04,0x0e,0x26,0x01,0x88,0xbc,0x8b,0x98,0x0c,0x9b,0x74,0x22,0x44,0x16,0x16,0xed,0x94,0x81,0x81,0x13,0x26,0xc9,0x27,0xa9,0xa7,0xe0,0x45
+.byte 0x69,0x6e,0x33,0xcc,0xa3,0x15,0x10,0x99,0x84,0x06,0x95,0x00,0xbb,0xc6,0x8e,0x4e,0x37,0x1b,0x23,0xb2,0xf7,0x4d,0xd7,0x24,0x68,0x6b,0xaa,0x2e,0x57,0x8d,0xd6,0x4e,0xa2,0x69,0xd8,0x8d,0x84,0xb2,0x85,0x91,0x30,0xbf,0x41,0xab,0xcf,0x5c,0xa6,0x51,0x1e,0xf5,0x79,0x5a,0x20,0xfa,0x3d,0x0a,0xc5,0xd7,0x3f,0xa6,0xcc,0xf6,0x9b,0x76
+.byte 0xe0,0xec,0x9e,0x0b,0x23,0xe4,0x74,0x36,0x14,0x6f,0x24,0x9d,0xe7,0xb2,0x41,0xd7,0x68,0x37,0x67,0xdc,0x01,0xb1,0x20,0xf9,0x8b,0x0b,0xf5,0xa7,0x95,0x78,0xa0,0x6c,0x4b,0xc0,0x44,0x92,0x4a,0x75,0x0f,0x61,0xde,0xc3,0xc2,0x3d,0x17,0xa0,0x4d,0x57,0x8b,0x11,0x35,0xbd,0x49,0x87,0x05,0xba,0x5d,0x1f,0x76,0xd4,0x0f,0xb0,0x5b,0x5f
+.byte 0xb7,0xf8,0xcf,0x12,0x54,0x19,0x9a,0x49,0x6a,0x42,0xad,0x93,0x85,0x0b,0xe7,0x8c,0x30,0x59,0x82,0x82,0x2d,0xd9,0x89,0xf5,0x8c,0x39,0x9c,0xf5,0xcd,0x25,0x22,0x74,0xcf,0x56,0xa2,0x15,0x40,0xa6,0xa8,0xfc,0xdc,0x85,0x9e,0xab,0xd6,0x94,0x5d,0xd6,0x73,0x07,0xed,0x7b,0x76,0x11,0x67,0xf5,0x52,0xac,0x1a,0x69,0x1f,0x4a,0xa2,0xaa
+.byte 0x4d,0x11,0xe0,0xc4,0x4c,0x6e,0x9e,0x8e,0x13,0x46,0x0b,0x95,0x40,0x53,0x35,0x53,0x58,0x7f,0x81,0x5f,0x17,0xd7,0x5e,0x53,0x86,0xf3,0x1b,0x70,0xf1,0x95,0x8f,0xf6,0xd4,0x6f,0x55,0x92,0xa2,0x38,0xd3,0x43,0x6c,0x7e,0xa2,0x21,0x5b,0x18,0x11,0xdd,0x03,0x52,0xe6,0xe5,0xc0,0xc5,0x4e,0x8e,0xda,0xdb,0x91,0xcf,0xf7,0x75,0xc2,0x33
+.byte 0x69,0xd1,0xd1,0x29,0x9d,0x51,0x79,0x91,0xe4,0x58,0x05,0xa5,0xf6,0x54,0x16,0x3e,0x42,0xf3,0xc4,0x1f,0x88,0x94,0xfc,0x6b,0x53,0xb1,0xd5,0x17,0xe6,0xab,0x77,0x33,0x8a,0xd0,0x93,0x74,0x02,0xe0,0x81,0x5e,0xbe,0x2f,0x4d,0xcd,0x25,0x0b,0xd0,0x06,0xd8,0xc9,0xf9,0xcf,0x8e,0xf8,0xc3,0xe2,0x33,0x60,0xe5,0xfa,0x89,0x68,0xf8,0xb7
+.byte 0xef,0x9d,0xfc,0x9d,0x76,0x13,0x2d,0x9d,0x18,0x7d,0x05,0xb4,0xa7,0xa3,0x8a,0x91,0xe0,0x73,0x65,0x89,0xb4,0xc1,0x53,0x7c,0xdc,0xf2,0xab,0x39,0x94,0xc7,0x3d,0xf8,0x1c,0x8f,0x49,0x37,0xee,0xc1,0x19,0x84,0x15,0x3b,0x36,0xb2,0xc2,0xe1,0x16,0xe2,0xfb,0xde,0x1f,0x0e,0xa4,0xea,0x59,0x67,0x2d,0xea,0x47,0xe5,0x2c,0xd1,0xb5,0xa9
+.byte 0xbd,0x5c,0x92,0x34,0x8b,0xc5,0xab,0x4f,0x2b,0x6b,0xc4,0x8b,0xdb,0xbb,0xcb,0x86,0x34,0x35,0xa0,0x5c,0x29,0x1a,0x8b,0xce,0xdc,0xd7,0x46,0x2b,0x20,0x9d,0xea,0xa8,0x97,0x68,0x37,0x56,0x03,0x7d,0x4f,0xb6,0xfc,0x30,0x82,0x68,0xb4,0x56,0xf3,0xbe,0x58,0xcc,0x20,0xc1,0x53,0x9f,0xbb,0x0b,0x2b,0x6e,0xa0,0x2d,0xc0,0x61,0x02,0x0b
+.byte 0xf9,0x0e,0x55,0xb8,0xb8,0x23,0x6e,0x50,0xc0,0x36,0xb8,0xf6,0x5e,0xb3,0xa7,0x8f,0xf8,0x7f,0xd0,0x5d,0x0a,0xc4,0x2b,0xa9,0xd3,0x76,0xcf,0x4d,0x27,0xda,0xac,0xf3,0xb0,0xca,0x00,0xa0,0x94,0x12,0x20,0x89,0x22,0xa9,0x89,0xe4,0x23,0x71,0xe0,0xdb,0xec,0xb0,0xa9,0x2e,0x45,0xf6,0x8d,0x1e,0x4b,0x0e,0xc7,0xf8,0x40,0xd6,0xf4,0x2f
+.byte 0x80,0x3e,0xf8,0xfb,0xcf,0x7b,0x54,0xb5,0xbd,0x55,0xf2,0x37,0x46,0x9f,0x32,0x45,0x87,0xa3,0x6a,0x51,0x25,0x43,0x54,0xa2,0x92,0xc6,0xbe,0xa4,0x33,0x54,0x82,0xc7,0xf1,0xe4,0x52,0xf9,0x09,0xac,0xc3,0xb1,0x25,0x86,0xc7,0x89,0x83,0x2c,0xf6,0x35,0x9e,0xd1,0xd8,0xb1,0x71,0xed,0xfa,0xae,0x09,0x83,0xb3,0xf0,0xde,0x24,0xed,0x3c
+.byte 0xc6,0x60,0xe8,0x15,0x49,0x93,0x29,0x82,0xbf,0x1d,0x23,0x17,0x11,0xea,0xa7,0x53,0x83,0xa5,0xc1,0x9e,0x02,0x17,0x08,0x99,0xa6,0x72,0xaf,0x82,0x3f,0x0b,0x69,0xca,0xb8,0x72,0xa9,0x31,0x71,0x20,0x32,0x57,0x89,0x9b,0x16,0x92,0x54,0xc0,0x99,0x6d,0xa4,0xbf,0x5a,0xb5,0x53,0xa7,0x4c,0x69,0xd8,0xf7,0xe7,0x4c,0xc0,0x76,0xb6,0x35
+.byte 0xdd,0xe7,0xb2,0xd9,0x1c,0xd5,0xf7,0x39,0x32,0x44,0x48,0x02,0x85,0x69,0x02,0xad,0xe6,0xfc,0xbb,0x07,0x9e,0x7f,0xee,0x6d,0x07,0x12,0x21,0xeb,0x67,0x4d,0x74,0x90,0x8f,0x79,0x51,0x9d,0x8a,0x63,0x24,0xab,0x6f,0x8f,0x73,0xd3,0x91,0x68,0x15,0xa9,0x6a,0x84,0x92,0xc2,0xd4,0x4d,0xa8,0xe1,0x4f,0xa2,0x1e,0x34,0xa3,0x9a,0x04,0xf2
+.byte 0xfc,0xc4,0xe7,0xd0,0x52,0xc4,0x49,0x51,0x8e,0x7d,0xaa,0x74,0xaa,0x08,0xbe,0x08,0xf6,0xe4,0xc1,0x61,0xff,0x2e,0x9c,0x17,0x61,0xb6,0x01,0x44,0x18,0xe8,0x5e,0xa9,0xfb,0x02,0x21,0xbb,0x08,0x5c,0xe0,0xd3,0x0c,0x98,0xc5,0x93,0x2a,0x1c,0x69,0xf3,0xe8,0x8b,0x36,0xa0,0x9d,0x1e,0xda,0x18,0x14,0x06,0x7f,0x75,0x3d,0x42,0x92,0x5a
+.byte 0xb9,0xb7,0xc0,0xc0,0xb0,0xc5,0xa9,0xb2,0x67,0x24,0xc2,0x28,0x29,0xcb,0x78,0x8e,0xf3,0xd1,0x37,0x63,0xca,0xc8,0x9a,0x1b,0x38,0xa5,0x9f,0x0e,0x0d,0x26,0x5b,0xfe,0x2f,0xdf,0x4f,0xb9,0x21,0x8c,0xc8,0xe0,0x9f,0x71,0xb9,0xc3,0x6c,0xd8,0xd3,0x2f,0xe4,0x3c,0x67,0x35,0x45,0x74,0x7f,0xcb,0x13,0xda,0x64,0x47,0xff,0x6f,0x05,0xf0
+.byte 0x87,0x8d,0x0d,0x1f,0x10,0x47,0x0e,0xf6,0x9d,0x89,0x6d,0x79,0x04,0x77,0x8a,0x6c,0xeb,0x7d,0x9b,0xd7,0x65,0x82,0xa8,0x95,0xa2,0x8c,0x02,0x91,0x0d,0xf2,0xe8,0x65,0x60,0x0d,0xb6,0x1d,0xf4,0xf3,0x41,0x75,0x33,0x21,0x13,0x22,0x93,0x01,0x2f,0x11,0xe7,0xed,0x45,0x56,0x90,0xec,0x0b,0x99,0x8e,0x84,0xc8,0x76,0x31,0x1d,0xb9,0xcb
+.byte 0x87,0x3f,0x5f,0x39,0xeb,0xe8,0x9e,0x5e,0x96,0x9e,0x42,0x64,0xf3,0xef,0x00,0x1f,0x2a,0x6c,0x18,0x67,0xbd,0xdd,0xf9,0x65,0x11,0x1b,0x9c,0xd7,0xf3,0x3d,0xb2,0x6f,0x88,0xf7,0xd2,0x26,0x06,0xef,0xc8,0x23,0x3f,0x46,0x5d,0xf0,0x96,0x40,0xb1,0xdd,0xad,0xe4,0xee,0xb6,0xc2,0x67,0x18,0x46,0x67,0xc4,0xa5,0x7e,0x3e,0xce,0x72,0x47
+.byte 0xca,0xc3,0xa7,0x94,0x56,0xe2,0x23,0x03,0xcf,0xd0,0x18,0x55,0x30,0xe3,0x14,0x00,0xda,0x0f,0xaa,0x7f,0x20,0xaf,0x3b,0x24,0x43,0x7a,0xaa,0xd4,0x12,0x42,0x10,0xe4,0x44,0x8a,0x7f,0xf1,0x74,0x9d,0xe0,0x28,0x60,0xce,0xdd,0x04,0x96,0x03,0x80,0xcb,0xaa,0xa9,0xb5,0xc7,0xb4,0xbb,0xc7,0x9a,0x93,0xd8,0xff,0x3b,0x8f,0x1f,0xb7,0xce
+.byte 0xed,0xbc,0xde,0x9f,0x9e,0x56,0x96,0x65,0xba,0xe7,0x89,0x03,0xb2,0xbd,0xfe,0xa7,0x02,0xeb,0x33,0x9a,0x8b,0x5b,0x36,0x64,0x17,0x9f,0xd2,0xe4,0x75,0xb5,0xfb,0x21,0x03,0xa4,0xe7,0xb4,0x49,0x72,0xfd,0xf3,0x1e,0x5f,0xdb,0xe5,0x6c,0x92,0x51,0xe7,0x91,0x55,0xb7,0x82,0x18,0x05,0xc3,0x2c,0xf1,0x23,0x61,0x36,0xad,0x80,0x1b,0xde
+.byte 0xe1,0x51,0x4e,0x51,0xa1,0xf6,0x5a,0xb9,0x03,0x48,0xa7,0x12,0x88,0x63,0x30,0xff,0x48,0xfc,0x92,0x30,0x9a,0xca,0x08,0x1b,0x64,0xa9,0x74,0x2a,0x64,0x42,0x7d,0xa9,0xa4,0x9d,0xcb,0x59,0x71,0x53,0xc1,0xa8,0xa6,0xb5,0x47,0xf9,0x87,0xb5,0x41,0x58,0x92,0x14,0xf7,0xbd,0x10,0x45,0x37,0x20,0x1d,0x5b,0x42,0x04,0xed,0x69,0x4c,0xa5
+.byte 0xdc,0x2a,0x58,0xba,0x00,0x1e,0x05,0x9c,0x3c,0xbf,0x65,0x76,0xd1,0x11,0xe0,0x15,0x22,0xb0,0x2a,0x53,0x32,0x0f,0x6e,0x08,0x4e,0x27,0xc2,0x71,0x14,0x20,0xee,0xb0,0x0b,0x60,0xef,0x54,0xae,0x2c,0xe0,0x1d,0x30,0xac,0x0d,0x3a,0x93,0x15,0x0a,0xe7,0x14,0xf3,0x1a,0x67,0xb1,0x43,0x85,0xbd,0x06,0x53,0xab,0x6d,0x5d,0xe7,0xe3,0x82
+.byte 0xb8,0x39,0x35,0x10,0x87,0xe7,0x90,0x4d,0x9c,0x6f,0x83,0xad,0xa2,0x43,0x7a,0x5d,0xc1,0x8a,0x39,0xa3,0xa6,0xda,0x48,0x5c,0x9b,0xe1,0x0d,0x69,0xfc,0x87,0x18,0xdd,0x34,0x9a,0xb4,0x9c,0x04,0x0d,0x49,0x18,0x3e,0x38,0xd8,0x01,0x67,0xb1,0x7f,0x6b,0xb5,0xfe,0x58,0x1c,0x64,0x11,0x10,0x6b,0xc1,0xca,0x56,0xe3,0x12,0x8c,0xb4,0xac
+.byte 0x03,0xbd,0xc1,0x54,0xbe,0x5c,0x70,0x6f,0xdd,0x73,0xa3,0x84,0xcd,0x0b,0x1b,0xbf,0x05,0xac,0x27,0x11,0xe8,0x5f,0xc3,0xb9,0x68,0xc2,0xe9,0x3f,0x5a,0x9b,0x28,0xca,0x65,0x5e,0x66,0x4e,0x50,0xa9,0x81,0xb1,0x10,0xc1,0x2c,0xa5,0x62,0xc8,0x52,0x07,0xa5,0xa1,0x99,0x16,0x7b,0x08,0xa4,0x1e,0xf4,0x50,0x8f,0xb2,0x42,0xa5,0x19,0xa2
+.byte 0x34,0x91,0xcf,0xa7,0x5e,0x73,0x6b,0xc2,0xa3,0x4d,0xdd,0x7c,0x26,0x46,0x34,0xe6,0x5d,0x54,0x52,0xe3,0x1e,0xc1,0x10,0x36,0x7c,0xc9,0xd2,0x1e,0xca,0xeb,0x80,0xc5,0x3c,0x04,0xf6,0xb7,0x09,0xd4,0x3e,0x67,0xc3,0xf6,0x6b,0xd4,0x60,0x00,0xc9,0x68,0x17,0x39,0xbc,0xcd,0x14,0x32,0xfc,0x33,0xa4,0xb0,0x6f,0x12,0x6b,0x5f,0xe2,0x15
+.byte 0x1c,0x9a,0x15,0x4f,0x0b,0x7d,0x4c,0xa0,0x89,0x40,0xb3,0x0e,0x84,0x90,0xb3,0xc6,0x3e,0xa5,0x0b,0x81,0x66,0x14,0x5f,0x8d,0xe0,0xbf,0xf7,0x9d,0xa4,0x4e,0x69,0xd5,0xac,0x0f,0x6c,0x29,0x94,0x8f,0x3b,0x4b,0xed,0x5b,0x6e,0xe1,0x58,0x5d,0x32,0x19,0xe6,0xbd,0xfb,0xd5,0xb7,0x0f,0x72,0x0e,0x5b,0x14,0xd3,0xf3,0x09,0xa8,0xea,0xf7
+.byte 0x98,0x2f,0x42,0x07,0x8e,0x72,0x27,0x53,0x8d,0x0b,0xea,0x74,0x38,0xbc,0xaf,0xb8,0x76,0x65,0x97,0xda,0xa7,0x06,0x37,0x29,0x09,0xbe,0xaa,0xe6,0xf7,0xb6,0xb1,0x5f,0x71,0x1f,0x5d,0x14,0x47,0xdf,0x20,0xa3,0x94,0x93,0x7d,0x21,0xe6,0x22,0x7e,0x38,0x1a,0x26,0x83,0xc7,0x32,0xdf,0x58,0xcd,0xab,0x67,0xae,0x94,0xa5,0x68,0xcb,0xe3
+.byte 0x51,0x70,0xc0,0xc4,0x41,0x9f,0xca,0x05,0xc9,0x51,0x2a,0x8e,0x53,0x89,0x3f,0x52,0x6b,0x29,0x64,0xa8,0xb8,0xdf,0x02,0xb1,0x41,0x4e,0x36,0x42,0x32,0xa8,0xc0,0x91,0xf0,0x69,0x69,0x55,0x99,0xb7,0x78,0x4f,0x79,0x5b,0xc5,0xab,0xc6,0xed,0x15,0x88,0x6b,0x94,0x0a,0xdd,0xea,0x47,0xf9,0x0e,0xb8,0x89,0x15,0x68,0x3e,0xc0,0x50,0xf8
+.byte 0xa1,0x2d,0x2a,0x11,0x8a,0xc5,0xb0,0x09,0x4f,0x7d,0x90,0x5f,0x49,0x35,0xe9,0xdd,0xfc,0xac,0xea,0x1b,0x20,0xad,0xd2,0xe6,0xb6,0xbf,0x3c,0x0e,0x7b,0xdf,0x2f,0x55,0x58,0x0e,0x25,0x53,0x62,0xd3,0x73,0xb8,0x3e,0x12,0x91,0xcb,0x23,0xf2,0xc0,0x5d,0x74,0x2b,0x51,0xcc,0xa2,0xb1,0x5a,0xd2,0xf4,0x9b,0xc9,0xa5,0x83,0x2b,0x5a,0x8a
+.byte 0x0b,0xe9,0x09,0x59,0xb5,0x44,0xc9,0x55,0xcc,0xbd,0xb6,0x69,0x66,0x9a,0x0c,0x15,0xae,0x76,0x35,0xbe,0xe9,0x37,0x70,0x9e,0xdc,0x97,0x5a,0x82,0x97,0xf6,0x1a,0x45,0xd7,0x27,0xfe,0x1f,0xc3,0x7c,0x3a,0x52,0x85,0x12,0x73,0x8a,0x8e,0x07,0xec,0x1f,0x59,0x3f,0xb0,0x32,0x07,0x92,0x3e,0x81,0xe0,0x7a,0x9a,0xc9,0x91,0xca,0x84,0xf1
+.byte 0xe1,0x32,0x57,0x0a,0x3c,0x9a,0x20,0xa8,0xbe,0x84,0x91,0x44,0x66,0x81,0xdd,0x12,0xa8,0x46,0x15,0x18,0xfc,0xae,0x5e,0x9a,0xf3,0xd9,0xb9,0x6a,0xbb,0x90,0x1c,0x61,0x7f,0x61,0x2c,0xa7,0x12,0x1e,0x05,0xee,0x0c,0x66,0x9e,0xc2,0xc8,0xb9,0xe0,0xc9,0xc4,0xb9,0xee,0x3a,0x6f,0x97,0x2a,0x5e,0xcb,0xd9,0xff,0xd1,0x37,0x5e,0xa0,0x03
+.byte 0x70,0xc1,0x2f,0x15,0xf9,0xf7,0x90,0xbe,0x23,0xe7,0x7c,0x90,0x4b,0xe4,0x5a,0x01,0x65,0x27,0x2d,0x4b,0xd3,0xa8,0x8c,0x1d,0x2d,0x5d,0x48,0xac,0x6b,0x59,0xc9,0x78,0xb2,0xee,0xda,0x6e,0xa8,0x68,0x08,0x99,0x22,0x25,0xfe,0xc2,0xb8,0x83,0xa8,0x08,0xbb,0x6e,0x64,0xae,0x2e,0xbb,0x93,0xaf,0xdc,0xeb,0xa3,0x11,0xa7,0x5d,0x3f,0x22
+.byte 0xf1,0x95,0x27,0xf6,0xd6,0xa6,0xc3,0x56,0x0a,0xd0,0x17,0x43,0x35,0xd2,0xe7,0xa4,0x8f,0x6c,0x1c,0xc4,0x4d,0xa7,0x3b,0xb8,0x7f,0x0c,0xa0,0xd6,0x56,0x82,0xf4,0x16,0x96,0xcd,0xcf,0x6f,0x78,0xec,0xbb,0xb2,0xdb,0x67,0xcf,0x78,0x0c,0x22,0x1d,0x72,0x21,0x8e,0x40,0x85,0xa5,0x07,0x3b,0x0e,0xfa,0x44,0xb0,0xfe,0xbf,0x54,0x80,0x41
+.byte 0xdc,0xa7,0xc7,0xdb,0xaa,0x04,0x42,0x0d,0x42,0x03,0x17,0xc8,0x57,0xd7,0x08,0x34,0x37,0xf5,0x9a,0x90,0x30,0x43,0x54,0x5b,0x58,0x50,0x4e,0xc4,0x56,0x57,0xff,0xf0,0x05,0x82,0xca,0x2e,0x20,0xb0,0xbd,0xd0,0x00,0x7d,0x60,0x3f,0xdb,0x9c,0x08,0x7e,0x21,0x63,0xbc,0x89,0xbf,0xcb,0xcc,0x36,0xb5,0x36,0x41,0xb4,0x9c,0x5c,0x9d,0xa6
+.byte 0x74,0xa4,0x4f,0x6a,0xcb,0x63,0x51,0xb1,0x92,0xa0,0x03,0x9b,0x88,0x03,0xd5,0x82,0x30,0xfb,0x69,0x49,0x20,0xb0,0x37,0x50,0xe4,0x02,0x9e,0x11,0x09,0x20,0x1a,0x41,0x8d,0xdd,0xa0,0x18,0xb4,0x74,0x04,0x1e,0x3a,0xea,0xb4,0x28,0x01,0x7f,0x0b,0x73,0x27,0x5f,0x76,0x2e,0x71,0xfa,0x50,0x1b,0x43,0x8d,0x0d,0x6c,0x87,0xc3,0x10,0x7b
+.byte 0x42,0x7d,0x17,0xa6,0x00,0x5b,0x83,0x6c,0x7b,0x7f,0x72,0xd8,0x90,0x4d,0x7f,0x54,0x72,0x17,0x21,0xe4,0x45,0x74,0x20,0x53,0x30,0x46,0x90,0xbf,0x2f,0xac,0x01,0xbd,0x40,0xa9,0xc5,0xbe,0xbd,0x9b,0x59,0x62,0x03,0x30,0x80,0xe3,0x8e,0x23,0x7b,0x2d,0x63,0x4f,0x30,0xe3,0xb8,0x56,0x87,0x57,0x43,0xdc,0x6a,0x3c,0x13,0xed,0x93,0xc9
+.byte 0x1a,0x1b,0xea,0x38,0x67,0x33,0x7f,0x11,0x5c,0x96,0x20,0x4d,0xf6,0x82,0x51,0x45,0xca,0x20,0xfd,0x59,0xef,0x4c,0xb4,0xb0,0xb2,0x0f,0xdb,0x4c,0x00,0x7a,0x18,0x58,0xb0,0xd3,0x65,0x73,0x42,0xe5,0x05,0x76,0xd7,0xa2,0x1e,0x9f,0x59,0xc0,0xd0,0x76,0x29,0x1b,0x12,0x29,0x9b,0xe4,0x7d,0x45,0x13,0xb4,0x57,0xf2,0x0b,0xd1,0xb5,0x60
+.byte 0x6d,0x15,0x0b,0xca,0x5e,0xe4,0x80,0xda,0x56,0x95,0x41,0x18,0x54,0xa7,0xad,0x40,0xe5,0xd7,0xa7,0x3e,0xf7,0x73,0x40,0x70,0xb3,0x23,0xdb,0x22,0x62,0xc7,0x44,0xfb,0x64,0x18,0x18,0x05,0x84,0x07,0x68,0x06,0x7f,0xb9,0xc3,0xf9,0x55,0xe2,0x0d,0x37,0x51,0x34,0xc3,0x55,0x3c,0x29,0x5d,0x1d,0x27,0x77,0xd3,0xe1,0x6a,0x60,0x9f,0x10
+.byte 0xef,0xb1,0x93,0xbf,0x2a,0xb7,0xe8,0x42,0x4d,0xfd,0xa9,0xa9,0x2f,0xb6,0x07,0x5b,0xe8,0xf7,0xd7,0x10,0x47,0x71,0x56,0xba,0x11,0x11,0x32,0xc4,0x22,0xf4,0x12,0x6f,0xc3,0xef,0x81,0xc5,0x82,0xb4,0x1b,0x99,0xbb,0x1a,0x63,0x6b,0x3a,0x70,0x4f,0xec,0x2c,0xf9,0xde,0x1a,0x2e,0x62,0x27,0x1c,0x81,0x21,0x30,0x08,0x30,0xf6,0xf5,0xc1
+.byte 0x6d,0x0b,0xeb,0x34,0xd9,0x3a,0xa2,0xa2,0xc6,0x17,0x60,0x85,0x65,0x43,0xd6,0x3d,0x71,0xac,0xc2,0xaf,0x2b,0x9e,0x62,0xf2,0x08,0x47,0x6f,0x42,0xa8,0x21,0xad,0x42,0x98,0xa0,0xef,0xdf,0xd8,0xda,0x10,0xad,0xf7,0xe5,0xf9,0x22,0x89,0x44,0xbf,0x86,0x86,0x2b,0x02,0xd1,0x9e,0x8f,0xb7,0x10,0x63,0xb1,0xcc,0x40,0x6b,0xa3,0x8e,0x09
+.byte 0xb8,0xe3,0x77,0x3c,0xde,0x36,0x7a,0xb7,0x78,0x4f,0x99,0x5d,0x9a,0x9e,0x19,0x2d,0xb5,0xd9,0x9c,0x95,0x1f,0xa1,0xcc,0x61,0x31,0x1c,0x96,0xe5,0xca,0xeb,0x26,0x34,0xa4,0x63,0x5c,0x7c,0x0f,0x23,0xd1,0xe1,0x09,0xf4,0xab,0xf6,0x73,0x2f,0x8a,0x62,0xf0,0xd3,0x8c,0x44,0xe5,0xe9,0x9d,0x58,0x71,0xfa,0xf5,0x39,0xa5,0x6f,0xf7,0x04
+.byte 0x43,0x0a,0x78,0x54,0xfb,0xa7,0x66,0x57,0x1f,0x61,0xd6,0xda,0xff,0x4f,0x32,0x9d,0x80,0x6b,0x77,0xed,0xda,0xaf,0xbc,0x9e,0xea,0x77,0x04,0xf3,0x47,0x96,0xd1,0x44,0x8e,0xca,0xfe,0xb0,0xa3,0xa6,0x1d,0x8d,0xa4,0xb5,0x8c,0x35,0x28,0xf3,0xaa,0xab,0x28,0x1e,0xc9,0x94,0x12,0x07,0xc6,0xea,0x23,0xf9,0x69,0xc3,0x14,0x27,0xcc,0x55
+.byte 0x27,0x0b,0x27,0x64,0x23,0x38,0x05,0xd9,0xb4,0xf7,0x00,0xf3,0x02,0xae,0xc8,0x5a,0xbd,0x2f,0x20,0xd5,0x45,0xa6,0x09,0x6f,0x1a,0x09,0xb7,0xe7,0x6f,0xf6,0xa6,0x6f,0xc7,0x03,0x4e,0xa3,0x72,0xb5,0xfc,0x17,0xcf,0x1e,0x64,0x8b,0xc4,0xa2,0xba,0x83,0x0e,0x2a,0x11,0xba,0x71,0xe0,0x1c,0x9f,0x70,0x6e,0xf4,0xd9,0x47,0x31,0xf7,0xaf
+.byte 0xf7,0x1a,0xe7,0xc1,0xe9,0x66,0xa4,0x48,0xd4,0x25,0x8b,0xf7,0x6f,0x33,0x72,0xff,0x93,0x2e,0xcd,0xc7,0xae,0x3b,0x71,0x3f,0x84,0x7f,0xe6,0xb5,0x58,0x4f,0x95,0x34,0xe7,0x89,0x10,0xd3,0x2b,0x5c,0x30,0x9b,0xd3,0xef,0x98,0xf3,0x33,0x0e,0x6d,0x5f,0x7e,0xba,0x55,0x7a,0xb6,0xf3,0xb6,0xcd,0xa8,0x10,0x68,0x85,0x6f,0xea,0x54,0xc3
+.byte 0x66,0x51,0x5a,0xfc,0x11,0x83,0x9e,0x68,0x95,0xdb,0xec,0x74,0xf0,0x86,0x4a,0x90,0x24,0x66,0xf2,0x61,0x40,0x2e,0x3b,0x53,0xea,0xc1,0x3e,0x1c,0x69,0xaf,0x5f,0x04,0xb5,0xbd,0x3d,0x44,0x1c,0xc6,0x49,0x65,0xf6,0x78,0xfd,0x69,0x49,0x95,0x96,0xa1,0xa0,0xa9,0x78,0x1a,0xf6,0x0f,0xe9,0x52,0x93,0x9c,0x96,0x6c,0x5e,0x67,0x63,0x2d
+.byte 0x18,0x22,0x2a,0xcc,0x7f,0x2f,0xd3,0x72,0x82,0x98,0xae,0xb0,0x2b,0xa6,0x96,0x41,0x25,0x47,0x3c,0x92,0xc5,0x0f,0x2c,0xd4,0x43,0x09,0x0b,0x94,0x73,0x73,0x29,0xc2,0x8a,0xa3,0xcc,0x8d,0xed,0x40,0x6d,0x40,0x18,0x7c,0x32,0x1e,0xe1,0x4e,0x26,0xa7,0xa4,0xd5,0xcb,0xfa,0x90,0xba,0xb2,0x04,0x1d,0x5d,0xbe,0x32,0x6c,0x71,0x09,0x51
+.byte 0xdb,0xe3,0xb0,0xe1,0x34,0x74,0xa3,0x2b,0xf2,0xcb,0x9e,0xc0,0xae,0x88,0x40,0x90,0xb6,0x22,0xc8,0xac,0xff,0x45,0xc6,0xfa,0xce,0x0f,0x03,0x9d,0xc0,0xb2,0x2e,0xdb,0x1e,0x6c,0xa5,0xbe,0xb5,0xb3,0xaa,0xd5,0x2d,0x06,0x4d,0x29,0xa3,0xbe,0x25,0x5f,0x21,0x42,0x8d,0x27,0xaa,0x6f,0x59,0x88,0x61,0x4d,0x72,0x9f,0x64,0xfc,0x07,0xaf
+.byte 0xeb,0x02,0x5e,0xb9,0x1f,0xfe,0x1a,0x67,0x10,0x35,0xe9,0x9f,0x5f,0x9c,0x8d,0x4a,0xb3,0x10,0x99,0x8d,0x5b,0x9c,0x8b,0x8a,0x0c,0x02,0x8b,0x44,0x1a,0xaa,0xe7,0x14,0x05,0x3d,0x9e,0x62,0xfc,0x76,0x49,0x56,0x46,0xae,0xcc,0x0e,0x47,0x58,0x4d,0x94,0x33,0x4d,0x23,0x24,0x44,0x52,0x2e,0x18,0xf7,0x53,0x6b,0x24,0x67,0xb8,0x88,0x46
+.byte 0x70,0xc8,0xcb,0x60,0xac,0x70,0x85,0xdd,0x00,0xa1,0x5d,0xbb,0x94,0x07,0x0a,0xb6,0x1c,0x88,0x59,0xa7,0x88,0x7e,0x1e,0xc9,0x1d,0x7c,0xa0,0x1c,0xad,0xe4,0xa5,0x36,0xa5,0x35,0xe8,0xda,0x27,0x15,0xbc,0x7b,0x1e,0x8a,0x33,0x74,0x4b,0xc1,0xc7,0x9d,0xa9,0x21,0x98,0x02,0xe5,0xf4,0x8b,0x8e,0x2d,0x64,0x81,0xea,0xa6,0xbe,0xe2,0x05
+.byte 0x16,0xba,0xac,0x75,0x79,0xa4,0xc0,0xd3,0x9d,0xe0,0x25,0x63,0x22,0xb3,0x9c,0xee,0x04,0x8f,0x60,0xab,0x52,0x43,0x05,0x16,0xd4,0xb3,0x88,0xe8,0x68,0xc3,0x81,0x94,0xc4,0xee,0x13,0xaf,0xdd,0x36,0x23,0xe6,0x78,0xc9,0xf6,0x42,0xf0,0xf7,0x89,0x64,0x79,0x13,0xe8,0xed,0x50,0x03,0x16,0x78,0x6d,0xf4,0xdf,0x85,0x2e,0x4e,0x8f,0x2c
+.byte 0x5b,0xfe,0x4c,0xf2,0x49,0xde,0xf2,0xa4,0x96,0xe0,0x8a,0x25,0xc8,0x6d,0x22,0xff,0xab,0xfc,0x18,0xe8,0x7f,0xd5,0xc1,0x7e,0x44,0x8e,0x21,0xb4,0xc8,0x79,0xc0,0x55,0xaa,0xb7,0x28,0xa1,0x3a,0xbd,0xc2,0x1d,0xf8,0x87,0xf9,0x35,0x30,0x25,0xb2,0xaa,0x8f,0x3c,0x0d,0x64,0xf2,0xd1,0xa0,0x51,0xbf,0x9b,0x9a,0x9a,0x9c,0x18,0x43,0xea
+.byte 0xd2,0x54,0x50,0xe0,0xca,0x1a,0x29,0x16,0x9f,0x49,0x47,0x56,0x65,0x21,0x0f,0xb0,0x53,0x41,0xe3,0xec,0xe0,0x15,0xcb,0xd0,0x61,0x05,0x67,0xd6,0x02,0x1a,0x31,0x80,0xa4,0x9f,0xf5,0x9b,0x28,0xcd,0x43,0xd5,0x70,0x05,0x67,0xe8,0x76,0xb7,0x99,0x98,0x0a,0xd6,0x27,0xe9,0xfb,0x62,0xff,0x66,0x47,0xf7,0xbe,0x5e,0x35,0xa0,0x3b,0x56
+.byte 0x58,0x78,0x9b,0x9c,0x5b,0x9f,0xf5,0x6b,0x1a,0x6a,0xfd,0x8e,0xe3,0xd9,0xa2,0x8b,0x2e,0xef,0xc7,0xd3,0x74,0xb1,0xea,0x6a,0x03,0x8b,0xe2,0x78,0xbe,0xf1,0x75,0x7f,0x02,0x03,0xbc,0xd3,0x15,0x2c,0x87,0x01,0x95,0xa6,0x87,0x2d,0xf8,0x63,0xfe,0x33,0x8f,0xc5,0xc9,0x0a,0x06,0x79,0x93,0x46,0xd7,0x0b,0x61,0x06,0x68,0xae,0x9b,0x46
+.byte 0x6f,0x9e,0x1b,0x21,0x58,0xc1,0x72,0xa9,0x05,0xa7,0xaa,0x88,0xee,0xed,0x8d,0x7f,0x55,0x3b,0xb8,0xb8,0xf8,0x42,0x26,0x4a,0x78,0xe3,0x17,0xe8,0xac,0xb3,0xdb,0x9b,0x90,0x7d,0x8d,0x65,0x00,0x39,0x40,0xc2,0xe2,0x9c,0xc6,0x16,0x35,0x54,0x64,0x09,0xc8,0xc7,0x08,0x77,0x90,0x9d,0xb4,0xd4,0xe1,0x36,0xd4,0x5e,0x63,0xb0,0xba,0x81
+.byte 0x0c,0x4e,0x24,0x20,0xc0,0x7f,0xfc,0x02,0x3d,0x83,0x60,0x8a,0xf5,0xff,0x87,0x60,0x9c,0xd5,0xc0,0x94,0x64,0xe2,0x3f,0xeb,0x9a,0xe5,0xb6,0x50,0x13,0x36,0xf4,0x96,0x5d,0xf4,0xb5,0xab,0xa4,0x28,0x17,0x38,0x7f,0xca,0xf7,0x0c,0xcf,0xae,0xf8,0xef,0x41,0x6d,0x9c,0xa1,0x53,0x33,0xcb,0x8d,0x21,0xab,0x3a,0x8c,0x72,0x8d,0xf3,0xf2
+.byte 0x05,0x69,0xf5,0xe8,0x6b,0x5b,0x42,0x85,0xb1,0x2e,0x6f,0xf8,0x62,0x00,0x1c,0x48,0x6c,0x85,0x72,0x93,0x34,0x67,0x80,0xe7,0x2a,0xfe,0xcf,0x54,0xc6,0x94,0xf2,0x5a,0x48,0xab,0x40,0x52,0x66,0x7d,0x7a,0x75,0x68,0x77,0xfd,0xb2,0xdd,0xb1,0xdb,0x72,0x50,0x31,0x53,0x24,0xbd,0xb0,0x6e,0x1f,0xbd,0xa6,0x90,0x67,0x07,0x1d,0x31,0xf3
+.byte 0x8c,0x82,0xf7,0x53,0x85,0x54,0x64,0x7c,0x76,0x7b,0x5f,0xaa,0xe0,0xe0,0x36,0xa4,0x13,0xb3,0x0b,0x99,0x09,0xfe,0xed,0xbb,0x81,0x4b,0xb3,0x16,0x45,0x2e,0x3a,0xfe,0x60,0x9c,0xdc,0xcb,0x00,0x5a,0x41,0xc4,0x80,0x3c,0x9d,0x15,0x05,0xfa,0x5e,0x37,0x64,0x89,0x9c,0x2d,0xb8,0xf7,0xbc,0x35,0x8c,0x49,0xfe,0x0a,0x43,0x1a,0x59,0xaf
+.byte 0x1e,0x50,0x08,0x0f,0x2d,0xb8,0x5d,0x63,0x7f,0x95,0x6a,0xe6,0xad,0x88,0xc3,0xac,0x05,0x14,0x44,0xb0,0x70,0x83,0x5f,0x94,0x45,0x3d,0xe5,0xbd,0xb8,0x92,0x28,0x20,0xd5,0xa0,0x83,0xd2,0xe2,0x41,0x71,0x27,0x29,0x1b,0x2a,0x3a,0x08,0xca,0x75,0xec,0x16,0x4a,0xcf,0x39,0xed,0xbe,0x2a,0x26,0x9b,0xa3,0x26,0xc6,0x89,0xf2,0xc6,0x8d
+.byte 0x49,0x3a,0xfe,0xda,0x16,0x54,0x55,0x7e,0x7f,0x65,0x65,0xd2,0x16,0xdd,0xe2,0xa3,0x86,0x7a,0x69,0x82,0x99,0x58,0x45,0x16,0x4c,0x69,0xff,0x72,0xf2,0xbc,0xbb,0xdd,0xe1,0xb4,0x56,0xcf,0xc0,0x84,0xd6,0x2c,0xd8,0xce,0xf4,0x67,0xd8,0x1d,0xb7,0x77,0x6d,0x96,0xf4,0x28,0x7a,0x33,0x03,0x97,0x72,0x37,0xd9,0x35,0xcf,0x20,0x28,0xc2
+.byte 0xc4,0xea,0xf9,0x99,0x89,0xe0,0xcc,0x3d,0xec,0x2c,0xbf,0x06,0x78,0x91,0x1b,0x55,0x1b,0x51,0x9b,0xbe,0xf7,0x4a,0xf8,0x9f,0x46,0xab,0xee,0x5d,0x4e,0x29,0x36,0xf3,0xb9,0xa7,0x85,0x9b,0xf7,0xa1,0x9e,0x2a,0xbb,0xb3,0x0a,0x61,0xb5,0x0f,0x79,0xf4,0xe2,0xd2,0x2c,0x15,0xf7,0x4f,0xca,0xa9,0x46,0x25,0x1c,0xdc,0xfa,0x0f,0x9e,0xfa
+.byte 0xf5,0xb8,0x54,0x7a,0xe3,0x98,0x3c,0x3b,0x85,0xf8,0xb3,0x7c,0x70,0x40,0x86,0x2a,0x66,0xd1,0x4d,0x83,0x38,0xc2,0x24,0x8e,0x30,0xc0,0x9e,0x54,0x4c,0x7a,0x62,0x9a,0x55,0x8e,0x11,0x02,0xef,0x30,0x08,0x5c,0xf3,0x57,0xa7,0xbe,0x32,0x04,0xab,0xb1,0x3a,0x51,0x6e,0xcd,0x6f,0xc1,0xd8,0xd0,0x7d,0x4f,0x1b,0xa9,0x1e,0x12,0x92,0x94
+.byte 0xd7,0x40,0xa9,0x99,0x70,0x06,0xcb,0x46,0xa5,0xe0,0x77,0xbe,0x6d,0x48,0xab,0x67,0x4e,0xa7,0x0e,0xfe,0x1f,0x53,0x24,0xbc,0x89,0xcb,0x70,0xac,0x05,0xa2,0xf4,0xa3,0x44,0xde,0xcb,0x18,0x95,0x78,0x70,0x0f,0x69,0xf0,0x5e,0xbd,0xe7,0xfc,0xd3,0x17,0x3e,0x18,0xb0,0x2f,0xa6,0xfe,0x82,0x81,0xe7,0x74,0x44,0xfb,0x43,0x5e,0xda,0xf4
+.byte 0xfb,0xfe,0x5c,0xb4,0x3c,0x1d,0xea,0x0d,0x2d,0xdb,0xee,0x1f,0xc5,0xbd,0xb2,0xa0,0x52,0x76,0x9e,0xad,0xfa,0x19,0x37,0xb0,0x15,0x53,0x82,0x25,0x86,0xd9,0xce,0x99,0x84,0x67,0x5f,0x57,0xb2,0x6f,0x99,0xa4,0x56,0xb5,0x01,0x4f,0xdf,0xa2,0xca,0x8c,0x23,0x51,0xd3,0xc7,0x72,0x9b,0x90,0x72,0x29,0x0c,0xca,0x86,0xff,0xc3,0xd9,0x9e
+.byte 0x87,0xe4,0x8d,0xc6,0xac,0xba,0xfb,0x73,0xa9,0xcd,0x5d,0x16,0xfc,0x12,0xea,0x30,0xd5,0x7d,0x7b,0x16,0xa6,0x2c,0xeb,0x3c,0x3e,0x46,0x7c,0xee,0x03,0xd6,0x7a,0xe8,0x88,0x1c,0x17,0xa9,0x08,0xe9,0xd5,0x38,0x59,0x54,0x0b,0xb0,0x77,0x1b,0x76,0x09,0x53,0xca,0x38,0x12,0xd1,0xb5,0x2c,0xe3,0xd6,0xa0,0xca,0x9f,0x65,0x56,0xea,0x95
+.byte 0xab,0xc1,0xf4,0x98,0xaf,0x1a,0xe7,0x2b,0x1e,0x8d,0x75,0x43,0x43,0x9f,0x42,0x5c,0x2c,0xa5,0xd7,0x9a,0xcd,0xc2,0xab,0xd9,0x1f,0x1f,0xde,0x8a,0x3e,0xf8,0x0f,0x56,0x8a,0x01,0xde,0x47,0x41,0xd8,0xa0,0xc8,0x32,0x4d,0xa3,0x75,0x80,0x87,0xb1,0x1e,0x05,0x06,0x5e,0x2c,0x9a,0x7b,0xd3,0x22,0xe0,0x53,0x8f,0x4f,0x35,0x5f,0x46,0x3a
+.byte 0xb2,0xfe,0x62,0x44,0x54,0x38,0xe0,0x03,0x5e,0xda,0xcb,0x86,0xdf,0xda,0x67,0x66,0x40,0x27,0x97,0xf0,0xc2,0xbd,0xce,0xce,0x37,0xeb,0x47,0xe2,0x56,0x7e,0x54,0xe9,0x51,0xda,0xec,0xd5,0xe6,0xc1,0x69,0x6e,0x4c,0x3d,0x92,0xdc,0xa0,0x51,0xe2,0x2b,0xb8,0x96,0xb6,0xce,0xdf,0x35,0xdb,0xd0,0xd4,0x42,0xe3,0x94,0x89,0x09,0x1b,0xb4
+.byte 0xe2,0x8f,0xfb,0x23,0x62,0x35,0x56,0xc7,0x94,0x40,0xd7,0x2d,0xdb,0x80,0xc9,0xbd,0x4d,0xe3,0x14,0x30,0x44,0x43,0xad,0xeb,0x3d,0x89,0xe9,0x61,0xd7,0x80,0x15,0x59,0xcd,0xda,0x38,0x11,0x3b,0x84,0x14,0x85,0xef,0x55,0xf2,0x01,0x2c,0xed,0x74,0xf5,0x71,0x75,0x0c,0x52,0x0c,0x41,0x86,0xbe,0x84,0xc5,0x89,0x8b,0xa5,0x6d,0xc3,0xfa
+.byte 0x2b,0xe5,0xe7,0xe8,0xdd,0xf9,0xe8,0x27,0x08,0x5d,0xdf,0x61,0xdc,0xb2,0xe0,0x8c,0xe8,0xda,0xa8,0x68,0x22,0x51,0x6b,0xdf,0xd0,0x92,0x87,0x6a,0x43,0xff,0xd1,0x9d,0x9a,0x4c,0x03,0xdf,0x3e,0xc1,0x31,0x33,0x6e,0x2a,0x55,0xc1,0x58,0x59,0x69,0x66,0x05,0xd1,0xa7,0xa1,0x3b,0x98,0x1d,0x44,0x74,0xc7,0x7e,0xc0,0x07,0xd9,0x9c,0x87
+.byte 0x5f,0xc3,0x44,0x25,0x7b,0x96,0xbc,0x20,0x5d,0x14,0x08,0x34,0xe9,0xad,0x34,0xa3,0xc3,0x95,0x1a,0xc1,0xd1,0x37,0x43,0x49,0x66,0xff,0x39,0x70,0x27,0xa0,0x2b,0x39,0x9d,0x1b,0x78,0x52,0x55,0x77,0x30,0xe8,0x72,0x65,0x8a,0xc8,0xa4,0xe6,0xb7,0xd6,0x66,0x82,0xa7,0x1d,0xde,0x3e,0xc2,0x23,0x5a,0x8b,0x51,0xe4,0x44,0x03,0xf3,0x89
+.byte 0x10,0xb0,0x9a,0x09,0x5d,0xe3,0xe9,0x4a,0x0b,0xe3,0x86,0x58,0xf8,0xe3,0x1a,0x3f,0x7f,0x42,0xa5,0xd7,0xb0,0x24,0xb7,0xbc,0x1d,0x40,0xe7,0x2f,0x42,0x8c,0xa8,0x3c,0x33,0xee,0x9f,0xaf,0xd1,0x51,0x8e,0x34,0x82,0xc5,0x16,0xef,0xb1,0xa6,0xa8,0x0e,0xae,0xe6,0xc3,0x2f,0xb3,0x06,0xd4,0x4c,0xec,0xee,0x9e,0xff,0x88,0x82,0x4b,0xb8
+.byte 0xc5,0xef,0x94,0xe2,0x68,0x48,0x23,0xa2,0xc8,0xe4,0xdb,0x33,0xf9,0xee,0x73,0xc2,0xe6,0xa1,0x64,0xf9,0xf6,0xab,0x5a,0xdc,0xa5,0xb3,0xd8,0xae,0xf4,0x1f,0x47,0xfe,0xa0,0xee,0xf5,0xee,0x41,0x30,0xa6,0xbe,0x34,0x2c,0x1a,0x24,0x8a,0x80,0xb1,0x79,0x7e,0x2c,0xc0,0x65,0x68,0x46,0xae,0x0a,0x01,0x77,0xce,0xa2,0x5f,0xc3,0x00,0x8f
+.byte 0xd4,0x0f,0xbe,0xbf,0x81,0x20,0x4e,0xb8,0x21,0x5f,0xfa,0xb2,0xf2,0x02,0x83,0x41,0xa8,0xf1,0xe8,0x2c,0x7e,0x0e,0xe6,0xf0,0x6e,0xd5,0x7b,0xcb,0x4e,0xed,0x06,0xc4,0x18,0xfb,0x0e,0x0d,0x8e,0x22,0x8a,0x40,0x4d,0x66,0xa5,0x0c,0x74,0xf3,0x9e,0xd9,0x90,0xf8,0x71,0xe4,0x92,0x05,0x3d,0x2d,0xa0,0xed,0x42,0x88,0x18,0x9a,0xc7,0xe4
+.byte 0x41,0x5d,0xde,0x44,0x2e,0x26,0x30,0xfe,0x51,0xa8,0x91,0xa3,0xa6,0xfd,0x3e,0x04,0x7f,0x3a,0xa9,0x1c,0x21,0x98,0xab,0xaa,0x39,0x9d,0xe4,0x51,0x75,0xeb,0x90,0x6b,0xab,0x11,0x89,0xa9,0x22,0xa8,0xc5,0x92,0x16,0x51,0xe1,0x77,0x09,0x53,0x7f,0xb6,0x80,0x4b,0xf5,0xf5,0xa2,0x0e,0x36,0x24,0x7f,0xe7,0xcc,0x67,0xfb,0x2c,0x6e,0xc2
+.byte 0x16,0x47,0x41,0xc2,0x77,0xf4,0xcf,0x49,0x37,0x17,0x67,0x34,0x14,0x92,0x7d,0x0f,0x14,0xe8,0x4b,0x4c,0xc3,0xbb,0x78,0xf7,0xa0,0x59,0xbe,0x06,0x10,0x38,0xe6,0x2c,0x08,0x15,0xba,0xc6,0x49,0x38,0x9a,0x91,0x2b,0x4d,0x82,0x42,0x0e,0xe4,0x02,0xef,0x2b,0xa2,0x06,0xcc,0x3a,0x3c,0xb9,0xc5,0xb5,0x71,0x1e,0x17,0x5d,0x65,0x35,0x91
+.byte 0x89,0x54,0x97,0xa8,0x7b,0x02,0x24,0xf9,0xdb,0xb5,0x52,0xf7,0xd0,0xa0,0x42,0x48,0x01,0xf4,0x47,0x7c,0x84,0x7c,0x8a,0xb4,0xf4,0x30,0xec,0xb9,0x21,0x44,0x87,0xb2,0x96,0xa4,0x3b,0x0d,0x93,0x26,0x09,0xc8,0xfa,0x28,0x6f,0x09,0xb7,0x03,0x85,0x66,0x21,0x2d,0xf1,0xaa,0x3f,0x0b,0x59,0x15,0xfe,0x8b,0x2b,0xe0,0x81,0x38,0x63,0x70
+.byte 0x09,0x37,0x38,0x62,0x04,0x8e,0x3f,0x23,0x65,0xf8,0xf7,0xc0,0x30,0xb8,0x04,0xb4,0x17,0xd7,0x21,0xcc,0x8b,0x31,0xd3,0x7b,0x11,0xea,0xc5,0x51,0x01,0x93,0x5f,0xe3,0xf3,0x1e,0x0d,0x41,0x52,0x2a,0xfd,0x27,0x02,0x00,0x58,0x0d,0x1f,0x16,0xd7,0x50,0x09,0xea,0x3f,0x9f,0x72,0xae,0x7a,0x79,0x4b,0x69,0x61,0xfc,0xac,0x5c,0x4d,0x6a
+.byte 0x65,0x5d,0xa5,0x67,0x76,0xe4,0x24,0x3f,0xa0,0x6f,0xf6,0x60,0xd2,0x70,0x8e,0x2e,0xbe,0xf9,0x8b,0xab,0x22,0xc8,0x9c,0x5b,0x26,0xc5,0x75,0xeb,0x96,0xa2,0x4f,0xdf,0x6c,0x05,0x9a,0x15,0xef,0xbf,0x3e,0x35,0x6d,0x8d,0x48,0xa4,0x33,0xc2,0xe8,0x3b,0x89,0xe4,0x0c,0xb2,0x9a,0xc6,0x89,0x52,0xba,0xc7,0x2a,0xa5,0xfb,0xe5,0xde,0x06
+.byte 0xbd,0xc3,0x4f,0xe8,0xa9,0x9d,0x36,0xa5,0xcc,0x90,0xcd,0x68,0x49,0x52,0x6e,0x9a,0x85,0xd4,0x1b,0xe5,0x3f,0x54,0xc8,0xb4,0x7a,0x76,0xbf,0xa8,0xf4,0x25,0x05,0xeb,0x43,0x0c,0x2b,0x1c,0x59,0x5b,0x51,0x7f,0xd5,0x13,0x54,0x37,0x44,0x37,0x2f,0x79,0x1c,0x1f,0x18,0x57,0x60,0xab,0xf7,0xcc,0x5d,0xd5,0xdd,0x69,0xab,0x7f,0xc7,0x9d
+.byte 0x7f,0xd7,0x6a,0xdc,0x34,0x3d,0x6e,0x2c,0x1e,0xb8,0x74,0xef,0xec,0x14,0x83,0x98,0x20,0x85,0x8a,0x95,0x93,0x26,0xed,0xbb,0x7d,0xfe,0x63,0xaa,0x20,0xbb,0x40,0x7b,0x35,0x1d,0xe5,0x64,0xc0,0x64,0x83,0x90,0x59,0xb4,0xae,0xf7,0xfe,0x14,0xb2,0xaa,0x72,0xf7,0x34,0x61,0xe0,0x61,0x06,0xb3,0xdc,0x09,0x5f,0xe1,0x57,0x65,0x83,0x8a
+.byte 0x6d,0x46,0x54,0x8f,0xbf,0x38,0x12,0xf5,0xa3,0xfc,0x7b,0x90,0x4f,0x30,0xed,0xc1,0xab,0xb2,0x6e,0xee,0x7c,0x5e,0x35,0x70,0x80,0xb0,0xae,0x93,0xdc,0x4e,0x8f,0x6c,0x37,0xef,0xc9,0x4c,0x3a,0x41,0x14,0x91,0x99,0x0d,0x48,0xbe,0x5e,0x9b,0xc5,0xa6,0x4d,0x07,0x0d,0xd5,0xe6,0x5d,0x26,0x6b,0xa0,0xf3,0xb2,0x28,0x15,0x57,0xdb,0x7b
+.byte 0x8e,0x6b,0x88,0xc3,0x81,0xb6,0x16,0xd1,0x3c,0xd0,0x2d,0x5a,0x23,0x35,0x8e,0xb0,0x8b,0x5c,0x99,0x6a,0x7a,0x55,0xb1,0xf9,0x45,0x97,0x94,0x05,0x6e,0x58,0xd4,0x53,0x8d,0x73,0x43,0x02,0x68,0xdf,0x7c,0x37,0x1a,0x6b,0x71,0x04,0xa0,0x31,0x77,0xbc,0xe0,0x16,0x5a,0x2a,0x9a,0xb2,0x40,0xe4,0xbb,0xd0,0xfd,0x35,0xcb,0x7f,0xf4,0x13
+.byte 0x0f,0xb5,0x93,0x9a,0x7d,0x50,0xf8,0xfe,0x56,0x34,0x83,0x20,0xce,0x3d,0x02,0x2e,0x0b,0x95,0x76,0x88,0x47,0x8c,0x75,0x51,0x14,0x52,0x49,0xbc,0xed,0x66,0x0e,0x81,0x65,0x5e,0x64,0xfb,0x45,0x59,0x3d,0x2b,0xd6,0x3a,0xc6,0xfd,0x50,0xe4,0xeb,0x0c,0x68,0x38,0x0f,0xdd,0xa2,0xdc,0xaa,0x26,0xf5,0x7b,0x40,0x6a,0x90,0xf8,0x08,0x2c
+.byte 0xe8,0x8f,0x8e,0xc1,0xf2,0x6b,0x87,0xeb,0x7a,0x02,0x9e,0x26,0x3e,0x6b,0xb9,0x71,0x2e,0x6f,0x26,0x20,0xa9,0xc0,0x7c,0xe5,0x6c,0x6b,0xd4,0xc4,0x7b,0x54,0x8e,0x4a,0x7a,0xef,0xfc,0x03,0x02,0x1d,0x6a,0x16,0x99,0x35,0x12,0x49,0xba,0x86,0x37,0x7a,0xb0,0x8d,0x58,0x6f,0x1c,0xba,0xa9,0x5d,0x93,0xdf,0x98,0x50,0x7e,0xea,0x0a,0x88
+.byte 0x1a,0xd4,0x63,0x91,0x23,0x43,0x43,0x17,0x2e,0xe6,0x04,0x95,0x96,0xa8,0x2b,0xb4,0x9e,0x91,0x6c,0x13,0x52,0x8c,0xbf,0x7d,0x50,0xfc,0x79,0xef,0xa1,0x3e,0x90,0xba,0xac,0xd1,0x0d,0xb0,0x4d,0xd5,0x7a,0xc7,0xbd,0x82,0xb7,0x03,0x9c,0x0b,0xbc,0xa7,0x3c,0x05,0x8f,0xbd,0x0d,0x7f,0x80,0xeb,0xe9,0xbd,0x8f,0xdc,0xcd,0x86,0x23,0x26
+.byte 0xb0,0xa4,0xdc,0x63,0xef,0xad,0x61,0x53,0x7e,0x23,0x34,0x0d,0xd9,0x75,0x7c,0xa7,0x57,0xba,0x28,0x0c,0x82,0x7f,0x68,0xe5,0x24,0xdc,0x23,0x99,0xcd,0x6f,0x03,0x59,0x4f,0x35,0x47,0xc4,0x11,0xc0,0x0c,0x2b,0x16,0x94,0xb8,0x28,0xf2,0x0a,0x91,0x2e,0x1c,0xde,0x75,0x50,0x52,0x00,0x0a,0x92,0x80,0xca,0x39,0x3a,0xdf,0x16,0xb7,0xe2
+.byte 0xbd,0x98,0x7b,0x70,0x48,0x85,0x6d,0x48,0xa0,0x1b,0x0a,0xbb,0xa8,0xb6,0xca,0x9c,0x4e,0xda,0x0a,0x17,0x0b,0x30,0xf5,0xa2,0x9b,0x5a,0x89,0xf4,0x53,0x89,0x38,0x34,0x2b,0x7d,0x14,0x04,0x44,0xa3,0x8f,0x70,0x29,0xa5,0x3e,0xdd,0x5a,0x61,0xa1,0x04,0xac,0xd8,0xd3,0xec,0x42,0xc4,0xd9,0x2c,0x13,0x80,0xf8,0xc9,0xec,0x54,0xa7,0xa0
+.byte 0xe6,0x37,0x04,0x38,0x5f,0x1e,0x0b,0xfb,0x38,0x06,0xb9,0xe2,0x05,0x12,0x12,0xa2,0x28,0xff,0x12,0xae,0x44,0xd8,0x0d,0x2c,0x5a,0x8f,0xfb,0x1d,0x98,0x69,0x85,0x69,0x99,0xc0,0x63,0xc5,0x88,0xa7,0x2d,0x56,0x76,0x32,0x23,0x4c,0xf7,0x29,0xd6,0x3e,0x45,0xfa,0xd7,0x61,0xf4,0x9a,0xa6,0x9e,0x4a,0xe7,0xe7,0xf9,0xbf,0x1f,0x09,0x82
+.byte 0xbe,0x36,0xa0,0xdd,0x91,0x47,0x3b,0xbc,0x52,0xf2,0xc2,0x04,0x96,0x85,0xb6,0x93,0xac,0x99,0x94,0xbe,0xfd,0xe6,0x53,0x9f,0x75,0xab,0x38,0xdd,0x81,0xc0,0x79,0x25,0xcd,0x73,0x72,0x5b,0x4d,0xc0,0xba,0xa9,0x18,0xaa,0x76,0x51,0x15,0xef,0xb9,0x22,0xdd,0x5f,0x22,0x62,0x6c,0x36,0xf6,0xc0,0x72,0x34,0x01,0x7a,0xaf,0xe2,0x87,0x1b
+.byte 0x5f,0x33,0x9c,0xd5,0xe2,0x81,0x03,0xbe,0x4e,0xac,0xcc,0x17,0xc5,0xc6,0xf8,0x0f,0x24,0xe0,0x26,0x56,0x8a,0x20,0x2e,0xe4,0x05,0xc8,0x0f,0x89,0x24,0x0e,0xd4,0xb7,0x07,0xd1,0x99,0x8c,0x55,0xfd,0x75,0xc1,0xdb,0xaa,0xd1,0xd2,0xa6,0xf2,0xf0,0x3c,0xae,0x62,0x0e,0x1f,0xaa,0xc9,0xa5,0x16,0x09,0x2c,0xc0,0x61,0x55,0x72,0x70,0x63
+.byte 0x22,0xb6,0x41,0xa5,0x08,0x34,0x6a,0x1b,0xfc,0x42,0x81,0xe7,0x25,0x98,0xcf,0xba,0x18,0xb0,0x36,0x90,0x72,0x65,0x75,0xf3,0x57,0x68,0xd0,0x86,0xe4,0xaf,0x33,0xb6,0x2b,0xef,0x96,0x97,0x17,0x42,0x6b,0x8e,0x19,0xaa,0x4b,0x9d,0xc7,0x73,0x34,0x5f,0x41,0x24,0x12,0xfb,0x66,0xa2,0x1e,0x91,0x41,0xc2,0x78,0x08,0x66,0xc4,0xb2,0x86
+.byte 0x67,0x70,0xe6,0x96,0x76,0x8d,0xa4,0x69,0x6f,0xe5,0x35,0x8b,0x20,0x3d,0x6a,0xcb,0x65,0x7b,0x82,0x7b,0xf6,0x2d,0xd8,0xd0,0xda,0x69,0x8b,0xcd,0xdf,0x15,0xf6,0x3a,0x2c,0xfe,0xc7,0x84,0x20,0x11,0xcc,0x18,0x4f,0xc7,0x2e,0x1c,0x46,0x41,0x6b,0x91,0x79,0xa0,0xbb,0xf4,0x48,0xd7,0x0c,0x9a,0x88,0x01,0xda,0xa1,0xd1,0x8f,0x27,0x49
+.byte 0x9d,0xa0,0x3f,0x5a,0xc2,0xf7,0x26,0x9b,0xe5,0xff,0xa4,0xcb,0x86,0x32,0xb3,0x3c,0xd5,0xe5,0x7c,0xbb,0x5e,0xfe,0x3d,0xcf,0x60,0x1c,0x16,0x8e,0x0c,0xc4,0xa9,0xf2,0xb2,0x42,0x1d,0x13,0xb0,0xa8,0xff,0x90,0xbc,0xd9,0x9a,0x6d,0x78,0x7a,0x46,0x1a,0xa8,0x35,0x4e,0xa4,0x79,0xd5,0xb4,0x36,0x47,0x62,0x3c,0x0e,0x23,0x56,0xca,0xa2
+.byte 0x60,0xe6,0xca,0xf6,0xc3,0xd6,0x7c,0x5d,0x54,0x9c,0x0c,0xfa,0x9a,0x0f,0x3a,0x8c,0x64,0x52,0xdb,0x62,0x5e,0x93,0x82,0xef,0x9e,0x8d,0x30,0xa5,0xe7,0x3d,0x52,0x11,0xd4,0x93,0xb1,0x77,0x8f,0xee,0x54,0x9c,0x80,0x47,0xa9,0x21,0xa8,0xf7,0x16,0x4b,0xbb,0xab,0x75,0x52,0xed,0x0c,0x85,0xf8,0x04,0xf4,0x80,0x08,0x4a,0xb5,0x2d,0x2d
+.byte 0xd8,0x98,0x57,0x24,0xd5,0xc8,0x77,0xa0,0xd8,0xb5,0xb1,0x83,0x92,0xb4,0xc7,0x42,0x36,0xd1,0xa5,0xd6,0xbd,0x89,0xc6,0x76,0x31,0x92,0x31,0x67,0x2c,0xa4,0xb2,0x2b,0xcf,0x94,0x20,0x6a,0x17,0x63,0xb9,0x76,0xac,0x9c,0x1c,0x95,0x3e,0x57,0xf8,0x87,0x0d,0xef,0x36,0xcd,0x87,0xd1,0x58,0x2c,0x9a,0x5e,0x54,0x0e,0xac,0x97,0xbd,0x15
+.byte 0xc4,0xdb,0xea,0xd3,0x21,0x05,0x2d,0x78,0xce,0x4c,0x60,0xf3,0xf8,0xeb,0xd9,0x19,0x89,0xb0,0x83,0xc0,0xe4,0x42,0x08,0x5c,0x1a,0x1c,0x53,0xf3,0x1e,0x5a,0x28,0x92,0x0d,0x32,0xbe,0x4a,0x9a,0x70,0x78,0x93,0xc1,0x66,0x81,0xda,0xe7,0x3d,0x05,0xc5,0xaa,0xdc,0x51,0x6b,0xaf,0x67,0x4d,0x18,0xfe,0x29,0xe0,0xfa,0x5c,0xe5,0x9a,0x18
+.byte 0x7f,0x8f,0xaa,0x21,0xa5,0xd0,0x8b,0x62,0x32,0x6b,0x93,0x02,0x19,0x62,0xd3,0xd6,0x74,0xea,0x83,0xdb,0x6c,0x57,0xe3,0x1f,0x1f,0x90,0xd0,0x22,0xf7,0x9a,0x4a,0x14,0xf4,0x8a,0xb3,0x86,0xa5,0x4c,0x1e,0xdf,0x49,0xa5,0x78,0x30,0x5e,0xf0,0x9a,0x69,0x0d,0xaa,0xe9,0x47,0x01,0xae,0x51,0xcf,0x32,0x4c,0xec,0x03,0x08,0xe7,0xcb,0x35
+.byte 0x59,0xd2,0x48,0xd4,0xfa,0x6a,0x45,0x6b,0x66,0x1f,0xb8,0x1e,0x45,0x85,0xef,0x14,0x25,0x34,0x48,0x50,0x59,0xf3,0x76,0x09,0x32,0xf5,0xe4,0xa8,0x98,0xb0,0x9a,0x70,0xec,0x0a,0x17,0x87,0xcf,0x6d,0x96,0x7d,0x50,0x5e,0x3a,0xff,0x57,0xa7,0xaf,0x04,0x0d,0xdc,0xcc,0xad,0xe3,0x09,0xd3,0x92,0xab,0xd8,0x3a,0x61,0x1f,0x9c,0xc4,0x36
+.byte 0x3b,0xf3,0xf6,0x87,0x43,0xea,0xc8,0xff,0x29,0x19,0x9e,0x87,0x44,0xc7,0xe5,0x5c,0x43,0x30,0x9a,0xb2,0xd8,0x47,0x4a,0x87,0xcc,0xc7,0x8e,0x99,0x32,0xdd,0x3c,0x37,0xda,0xa0,0x39,0x04,0x55,0xca,0xcf,0x2f,0xce,0x8b,0x22,0x35,0x2c,0x29,0x89,0xef,0x5c,0x05,0x82,0x55,0xf3,0x8d,0x64,0x7f,0x69,0xf7,0x3d,0x43,0x27,0xf3,0x4c,0xd7
+.byte 0x43,0x89,0x47,0xd5,0x0b,0x01,0x1b,0x17,0x6c,0x7e,0x63,0x18,0x87,0x8b,0x8f,0x20,0x0d,0xa4,0x1e,0xa5,0x3b,0xf1,0x5c,0xe5,0xc8,0x23,0xd4,0xee,0x79,0x3e,0xd1,0xbc,0x83,0x30,0x03,0x64,0x80,0x7e,0xda,0x13,0x7c,0x52,0x88,0xc1,0x7c,0xa7,0x8a,0x5d,0x8d,0x7b,0x57,0x4e,0x59,0x97,0x83,0x52,0x03,0x04,0x6b,0xd2,0xf3,0xff,0x1c,0x4e
+.byte 0x3b,0xae,0x70,0x61,0x3b,0x8b,0xaf,0x56,0x3d,0x28,0x73,0x24,0x39,0x4b,0xb8,0x6e,0x89,0x28,0xe6,0xc8,0x5c,0xe9,0xf8,0xec,0x8f,0xf7,0x75,0x1a,0x13,0xc1,0x8e,0x53,0x4e,0xe5,0xef,0x37,0xce,0xa1,0x54,0xca,0xcc,0xf5,0x01,0x29,0x2a,0x8f,0x00,0x1c,0xde,0xcd,0x5e,0x24,0x0b,0xa5,0x94,0x0c,0x8a,0xab,0x54,0x1e,0x80,0x2a,0x0d,0x84
+.byte 0x38,0x4c,0x17,0xea,0x84,0x07,0x9c,0xbd,0x85,0xd8,0x1b,0x57,0x6a,0xde,0xb3,0x86,0xa3,0xf8,0x6d,0x03,0x3e,0xf1,0x37,0xae,0x7d,0x02,0x33,0xc5,0x7b,0xf6,0x64,0xdb,0x3e,0xb0,0x48,0xda,0x49,0xec,0x89,0xb4,0x83,0xff,0xe1,0x6f,0x9a,0x7e,0x0a,0xda,0x6e,0xec,0x70,0x0b,0x51,0xac,0x82,0xac,0xb8,0xce,0x16,0xe7,0x47,0xab,0xe8,0xc7
+.byte 0x56,0xd1,0xab,0x73,0x72,0x5c,0xe7,0x9e,0xb8,0x77,0xa7,0xc1,0x47,0x9c,0x4e,0x16,0x68,0xce,0x21,0x23,0x2d,0x6c,0xcf,0x79,0xd6,0xd4,0xdf,0x74,0x30,0xb8,0x0f,0x60,0xea,0xbf,0x39,0x77,0x45,0xdc,0xaf,0x25,0xbd,0xc5,0x8d,0x0b,0x44,0x21,0xc1,0xc1,0x2e,0x54,0x2a,0x32,0x6c,0xea,0x51,0xe0,0x7d,0xa8,0x09,0x94,0x2f,0x4e,0xfe,0x27
+.byte 0xe8,0x63,0xfb,0x71,0xca,0x01,0x7d,0xc9,0x70,0xd8,0xe4,0x82,0xbf,0x3f,0xea,0x64,0x5e,0xa9,0x84,0x1d,0x2c,0xfd,0x8a,0x7d,0x33,0x73,0x5c,0x82,0xbe,0x9e,0x46,0xfc,0x39,0x5e,0x38,0x2a,0x20,0xd9,0xa9,0x20,0x46,0x23,0xc1,0x8b,0x0a,0x9c,0x42,0xb6,0x50,0x9f,0xc8,0x7d,0x4a,0x85,0x98,0xed,0x92,0x13,0xd3,0xd6,0xe6,0x6d,0x50,0x6e
+.byte 0x93,0x63,0x41,0xa3,0x63,0x97,0x52,0xe3,0xaf,0x09,0xe1,0x40,0x12,0x41,0xed,0xb3,0xc5,0xb8,0x9f,0xc1,0xf2,0xd2,0xe6,0x16,0x94,0x97,0xdb,0xae,0xdb,0xd4,0x1f,0x5a,0x2f,0xf1,0xb1,0x22,0xf6,0x60,0xa4,0x0e,0xd8,0x2f,0xf7,0xf7,0x3f,0x6c,0x7d,0x73,0xe3,0x1d,0x99,0x04,0x7f,0x4f,0x70,0x2a,0x8c,0x43,0x80,0xa3,0xd0,0x25,0x75,0xd8
+.byte 0xb6,0xc8,0x90,0xa2,0x26,0xee,0xba,0xc5,0x1a,0xdc,0x1f,0x81,0x65,0x54,0xc6,0x57,0x6e,0xa2,0x03,0x32,0xf5,0x14,0xb2,0xdd,0x4d,0x21,0xaa,0xb9,0x78,0x4f,0x76,0xab,0xbe,0xfe,0x5d,0xc6,0xaf,0xed,0x6f,0xf9,0xaa,0x31,0x21,0x08,0xa4,0x6e,0xfb,0x78,0xdc,0xed,0x0c,0x05,0xff,0x1e,0x60,0x38,0x60,0x94,0xa9,0x92,0xa7,0x07,0x6e,0x6f
+.byte 0x6d,0x89,0x8a,0x73,0xfb,0xaf,0x01,0x34,0x7d,0x7d,0x33,0x76,0xff,0x1f,0x6b,0x79,0x5e,0xff,0x50,0x14,0x80,0x7d,0x55,0x0e,0x2d,0xc3,0x77,0x85,0x30,0x20,0xf6,0xc8,0xc7,0xb7,0x73,0x1b,0xd1,0x87,0x69,0x44,0xeb,0x02,0x5e,0x45,0x66,0x6f,0x28,0x00,0x1f,0xf8,0x58,0x93,0xe5,0x21,0xbc,0x19,0x8d,0x72,0x19,0xaa,0x9a,0xbb,0xc6,0x47
+.byte 0xe6,0x0b,0xe4,0x76,0x13,0xc7,0xc4,0x1b,0x9d,0x85,0xba,0x17,0xb6,0x30,0x2a,0xdb,0x7c,0x36,0xd7,0xd8,0x8b,0x9c,0x99,0x92,0x64,0x03,0x4f,0xd4,0x1f,0x04,0x2e,0x45,0x34,0x55,0x92,0x99,0x77,0xb8,0x45,0xce,0x59,0x22,0x3c,0x6e,0xe5,0x18,0xb0,0x83,0x42,0x42,0x75,0x1c,0x34,0x0f,0x2e,0x59,0x06,0x94,0x17,0xea,0xc3,0xdb,0x0b,0x2f
+.byte 0x44,0x97,0x54,0xe8,0x76,0xd3,0x25,0x24,0xe9,0x21,0x4f,0xd7,0x01,0x7d,0xbe,0x90,0x8a,0x0a,0x7d,0x4e,0x91,0x5f,0x4c,0x32,0x83,0x42,0x55,0x95,0x3c,0x7a,0x3e,0x46,0x8a,0x5d,0x0c,0x05,0xcd,0x0b,0xf6,0x3e,0x4d,0xf3,0x55,0xea,0x42,0x3e,0x19,0x0e,0xda,0xd4,0x22,0x88,0xe2,0x29,0x06,0x9e,0xea,0x1c,0x27,0x96,0x7f,0x3a,0x8a,0x28
+.byte 0x2f,0x7d,0xa2,0x65,0x37,0xae,0xb6,0x6a,0x59,0x41,0x19,0x73,0x91,0x64,0x77,0x4e,0x5a,0x1a,0x85,0x9f,0xc5,0xb0,0x85,0xc1,0x96,0x47,0x69,0x9c,0x36,0x70,0x36,0xa3,0x2e,0x1a,0x7d,0x11,0x59,0x55,0xec,0x4c,0x49,0xa1,0x86,0x3c,0x3d,0x24,0xb8,0x7a,0x84,0xca,0x4c,0x3f,0x7e,0x81,0x95,0x39,0x41,0xfe,0xc4,0x74,0xe5,0x89,0x7e,0xdc
+.byte 0x86,0xd2,0xdb,0x8b,0xb8,0xa2,0xbb,0x15,0x64,0x89,0xf9,0x00,0x7d,0x56,0xec,0x8b,0xc8,0x05,0xcd,0x76,0x6c,0xcb,0xaf,0x7e,0xd2,0xdd,0x67,0xb3,0x99,0x16,0x63,0xf2,0x6d,0x49,0x7d,0xeb,0x67,0x24,0x98,0xf1,0x28,0xa3,0xb2,0x14,0xfc,0x95,0xf6,0x55,0xa0,0xb5,0x8c,0x26,0x2f,0xc6,0x08,0x49,0x57,0x4c,0x20,0xbc,0x48,0xab,0x24,0xef
+.byte 0xe9,0xab,0x6b,0x77,0x4d,0x3b,0x61,0x84,0x68,0x67,0x72,0xc2,0xcf,0xab,0x8e,0xac,0x39,0xec,0x43,0x03,0xbb,0x4f,0x32,0x7d,0x7d,0x51,0x69,0x30,0xee,0x4f,0xd0,0xb9,0xa5,0x22,0xdd,0x47,0x06,0xad,0xac,0x62,0x20,0xff,0x7b,0x8c,0x90,0x91,0xb3,0xd8,0x89,0xd3,0xea,0x81,0xdc,0xca,0x31,0xc3,0x65,0xca,0x4c,0x50,0x0a,0x85,0xf7,0xaf
+.byte 0xe3,0x67,0x57,0x53,0x1d,0x4e,0x42,0x17,0x2d,0x14,0x80,0x29,0x09,0x2b,0x48,0x45,0x43,0xb9,0xad,0x1f,0xb7,0x2d,0xab,0xfa,0x6a,0x1b,0x3c,0x7d,0x76,0xd7,0x36,0x20,0xb0,0xd3,0xc0,0x5e,0xc7,0x20,0x06,0x0c,0xa9,0x6a,0xb2,0x67,0xad,0x91,0x49,0xfc,0x4d,0xb2,0x15,0x61,0x61,0xfa,0x33,0x6c,0x94,0x92,0x58,0xef,0x46,0x82,0x9c,0x04
+.byte 0x52,0x21,0x28,0x08,0xb4,0xa9,0xd4,0x2e,0xd9,0x8c,0x93,0xd0,0xd8,0x4f,0x33,0x1d,0x0b,0x7e,0x07,0x12,0x40,0x64,0x3d,0xa2,0x8f,0xa3,0x96,0x45,0x0e,0xfc,0x9b,0x55,0x5f,0x3c,0xa2,0x57,0x3e,0x51,0x40,0x69,0xdc,0x7a,0x51,0xd2,0x3b,0x79,0x2f,0xd2,0x01,0x18,0xbf,0xd5,0xd2,0xd1,0x0e,0x08,0xcf,0xac,0x07,0x4d,0xd1,0x92,0xc7,0xca
+.byte 0x92,0x75,0x0b,0x80,0x29,0xf1,0x46,0x24,0xba,0x47,0x6b,0x4a,0x64,0xfb,0x31,0x69,0xe9,0x40,0x0d,0x69,0x50,0xd0,0xdf,0xf8,0xcb,0x6a,0xe8,0xd4,0xc2,0xbd,0x0b,0x23,0x00,0xe0,0x29,0x0a,0x0a,0x8e,0x19,0xec,0xa9,0x14,0xe4,0x5d,0x4c,0x30,0xc9,0x85,0x42,0xd6,0x9f,0x83,0x8f,0x2a,0x5b,0x22,0x37,0xe4,0x71,0x3b,0x19,0x86,0xd4,0xda
+.byte 0xb5,0x81,0x8e,0x84,0x57,0xcd,0x13,0x64,0xc3,0x23,0xfd,0x91,0x8a,0xe4,0xb9,0x32,0x12,0x17,0x02,0xa6,0x8d,0xec,0x44,0x9d,0xa5,0x7c,0x96,0x14,0xd1,0xd5,0x93,0x02,0x0c,0x9d,0xfc,0x26,0xa0,0xd2,0x41,0xaa,0x75,0xe8,0x82,0x6f,0x47,0x1d,0xe8,0xcf,0x94,0xe3,0x35,0xa9,0x76,0x1e,0xdb,0x92,0x5f,0x32,0x49,0xf4,0xd5,0x59,0x9c,0x4e
+.byte 0xf7,0x89,0xda,0x23,0x7f,0x46,0x0e,0xfc,0xaf,0x1c,0x6f,0xcc,0x59,0xa5,0x43,0x04,0xbf,0x55,0xab,0x7d,0x36,0xa3,0xa5,0x03,0x7f,0xdf,0x33,0x6c,0x6d,0xd0,0x53,0xaa,0xef,0x54,0xc1,0x62,0xa0,0xd6,0x3a,0x67,0x87,0xe3,0x76,0x17,0x45,0xbe,0x7f,0x55,0xc8,0x8b,0xe8,0x1c,0xa8,0xe6,0xa6,0xb2,0xbf,0xe5,0x45,0xc0,0x88,0x22,0x36,0xa0
+.byte 0xec,0x21,0xdc,0x3e,0x6b,0xd2,0xc7,0xdf,0x5b,0xa4,0x32,0x28,0xca,0x23,0xe1,0x50,0x55,0x72,0x59,0x28,0x1c,0xf7,0x93,0x91,0x07,0x3c,0x4e,0x81,0x20,0x58,0x9b,0x07,0x38,0x37,0x68,0x2c,0x29,0xba,0x20,0x11,0xa9,0xa0,0x29,0x65,0x57,0xb1,0xe3,0xb1,0xfb,0xe2,0x70,0xee,0x1f,0xcd,0xf5,0x61,0xea,0x7a,0x08,0xb4,0x1e,0xfe,0xe7,0x4d
+.byte 0x32,0xa0,0xfd,0xb4,0x52,0xa1,0x4b,0x67,0xba,0x5e,0x90,0xe7,0x56,0xec,0x06,0x03,0xb6,0xe6,0xc6,0x98,0xa1,0x41,0xf4,0xaf,0xde,0xe2,0x67,0xef,0xaa,0x05,0x97,0xc5,0x80,0x32,0xd0,0x43,0xc2,0x02,0x7a,0xcc,0x4c,0xdd,0xe9,0x1e,0xd0,0x4f,0xad,0xf3,0x4b,0x2c,0x5e,0xb8,0xd8,0x84,0xc2,0x43,0xc7,0xa9,0x86,0x4d,0x10,0xae,0xb7,0xe3
+.byte 0x5c,0xd5,0x2a,0xba,0x3b,0xd3,0x7b,0x5d,0xc8,0xe0,0x67,0x87,0xbe,0xbf,0x71,0x4e,0x22,0x68,0x12,0x53,0x95,0x73,0x5c,0x30,0x7b,0x2b,0xfd,0xc1,0x3c,0xfc,0xc4,0x0f,0xdd,0x5b,0x3e,0x1b,0x72,0x71,0xa6,0xe3,0x1f,0x2d,0x51,0xe2,0x61,0x3d,0xa0,0x60,0xc2,0x6b,0x41,0x8f,0x94,0x83,0x29,0xa3,0xb6,0xa7,0xc7,0x11,0x8f,0x1c,0xb5,0x19
+.byte 0x66,0x44,0xc7,0x05,0x58,0x83,0x28,0x69,0x0c,0xb6,0x65,0xe5,0x93,0x1c,0xb1,0xf6,0xf9,0xea,0xda,0x84,0x26,0x8e,0xa2,0xbb,0x9b,0x55,0xd3,0xbc,0x42,0x56,0x8f,0xce,0x6e,0x74,0x40,0xf2,0x02,0xa6,0x22,0x22,0x6e,0x20,0x0e,0x4b,0x8b,0x15,0xa5,0x04,0xf0,0xe0,0x7b,0x27,0x0a,0x38,0xe3,0x99,0x04,0xd0,0x5b,0x64,0xd2,0x04,0x92,0x61
+.byte 0x57,0x74,0xbc,0x1e,0x98,0x01,0x4b,0x2f,0x46,0x56,0x1c,0xeb,0x49,0x2d,0x66,0xac,0x85,0x96,0x48,0xfd,0xa1,0xf0,0xf5,0xc0,0xdb,0x7a,0xf2,0x0b,0x57,0x86,0xac,0x4c,0x6a,0x02,0x97,0x13,0xef,0x08,0xf6,0x18,0xe1,0x5c,0xb3,0x18,0x3d,0x70,0xc0,0x76,0x5e,0xd0,0xb8,0x44,0x32,0x25,0x75,0x62,0xa2,0x80,0x78,0x8c,0xc4,0x2a,0x84,0xbc
+.byte 0x51,0xd4,0xee,0x44,0x48,0xe5,0xc4,0x48,0xbf,0xc0,0x27,0xc1,0x77,0x25,0xf5,0x59,0x6b,0x60,0xae,0xa5,0x42,0xfe,0xc3,0x06,0x91,0xe3,0xdb,0xa9,0x4b,0xe2,0x73,0x95,0x1f,0xf6,0xb6,0x66,0x71,0x63,0xb3,0x14,0x4a,0x3d,0x36,0x84,0xbe,0x2a,0x7c,0x7c,0xba,0x0e,0x8d,0x9a,0x73,0x52,0x21,0x89,0x02,0x8f,0x94,0xa5,0x9a,0x11,0x2e,0x6e
+.byte 0x78,0xf7,0x07,0xf8,0xb1,0x42,0x96,0x06,0x78,0xf0,0x53,0x86,0xec,0x2b,0x1f,0xa7,0x84,0x79,0x37,0xc7,0x61,0x83,0x8e,0x62,0x65,0x49,0xdd,0xfe,0xee,0x97,0x70,0xa2,0x73,0xb5,0x85,0xaf,0x10,0xed,0xb8,0x74,0xec,0x42,0xd0,0x14,0x47,0xa6,0x90,0x7c,0x07,0x22,0xb4,0x4e,0xfc,0x12,0xa1,0x9d,0xd4,0x73,0x8f,0x6a,0x55,0xf8,0x56,0x25
+.byte 0xdb,0x9b,0xe8,0x10,0x87,0x7a,0x4b,0x42,0x9c,0xbb,0x6e,0xf1,0xd7,0x1d,0xf4,0x07,0x31,0x9c,0x94,0x3a,0xb6,0xad,0x4b,0xf4,0x57,0x3d,0x2f,0xba,0x23,0x36,0x34,0x52,0x62,0xf7,0x64,0xc7,0x47,0xeb,0x41,0xad,0x07,0xfb,0x3e,0x08,0x74,0x92,0x58,0x0f,0x73,0xe2,0x53,0x35,0xda,0xae,0x64,0x3c,0x47,0x89,0xaf,0xce,0x59,0x35,0x75,0x8b
+.byte 0x50,0xee,0xbf,0xbe,0xd1,0xf4,0x2f,0x11,0xa3,0xfe,0xce,0xfd,0x15,0x0d,0x32,0x17,0x00,0xfb,0xad,0x02,0x70,0x5c,0xeb,0x59,0xfb,0x87,0xe5,0xed,0x0e,0xde,0x97,0xe7,0x75,0xb6,0xdc,0xe9,0xb0,0x08,0x26,0x0e,0x11,0xd4,0x4f,0xc4,0x92,0x71,0x7c,0x63,0xef,0xc0,0x14,0x64,0xe1,0x0f,0x7e,0xe6,0xcb,0x5b,0x4c,0xd4,0x16,0x8b,0x7b,0x8b
+.byte 0x2f,0x2a,0x77,0xef,0xd3,0xdf,0x56,0xc0,0x5a,0x94,0x72,0xd5,0x36,0x12,0xfa,0x25,0xd7,0x77,0x52,0xdd,0xea,0x11,0x2f,0x6b,0x16,0x6e,0xe3,0xa2,0x84,0xba,0x55,0xc2,0xb0,0xe2,0x3b,0x53,0xb6,0xa4,0xc6,0xa5,0x3f,0x1b,0xb3,0x38,0xc0,0x2f,0x1a,0x80,0xe0,0xa4,0x60,0x49,0x8c,0xe3,0x23,0x5f,0x59,0xfd,0x2a,0x0f,0xe8,0x4c,0xaf,0xd7
+.byte 0x36,0xc7,0x25,0x21,0xad,0x41,0x54,0x27,0x95,0x15,0x42,0xbc,0xb3,0x77,0x4e,0x97,0xf4,0x3c,0x54,0xcc,0x19,0x63,0x62,0x67,0x97,0x5a,0xd0,0x59,0xfb,0xce,0xcd,0xe1,0x3c,0xb6,0xc9,0x49,0xc4,0xff,0xde,0xf9,0x89,0x87,0x9c,0xdf,0x4e,0x8c,0x9d,0xe5,0xbd,0x0d,0x0c,0x6e,0x93,0xfd,0xea,0x90,0xf2,0x80,0x7e,0x00,0x9a,0x06,0x02,0x87
+.byte 0xae,0xca,0xf4,0x46,0xbb,0xb5,0x52,0xee,0x18,0xb0,0xf1,0x61,0xcb,0xe1,0x65,0x9c,0x0b,0xfb,0xe6,0x3b,0xeb,0x3a,0x1a,0x22,0x41,0x0b,0x99,0xa4,0x8e,0x01,0x5e,0x7c,0x4e,0x1a,0xaa,0xab,0xd3,0x8b,0x99,0x7f,0xba,0x6b,0xec,0xe7,0x3a,0xd6,0x55,0x46,0x20,0x1b,0x10,0x39,0x06,0xcc,0x90,0xc1,0x6a,0xa5,0x27,0x7c,0xca,0xa5,0x58,0x07
+.byte 0xd7,0xaf,0x6d,0x12,0xa6,0x68,0xc7,0x0e,0x19,0x53,0x44,0x22,0x85,0xbb,0x72,0x9c,0x4d,0xfb,0xeb,0x94,0x3a,0xa0,0x64,0xf5,0x25,0xe8,0xee,0x7a,0x3b,0x71,0x0e,0xbb,0x40,0xa2,0xb3,0xc9,0x6b,0x14,0x0f,0xc3,0x75,0xac,0x1b,0x5c,0xf1,0x34,0x51,0xcb,0xeb,0x5f,0x40,0x0f,0x82,0xe9,0xd2,0x6d,0x95,0x88,0x84,0xea,0xe9,0xe3,0xa0,0xe9
+.byte 0xef,0x3b,0x33,0xfe,0x32,0x52,0x93,0xce,0x95,0x4b,0x64,0x3c,0x97,0x76,0x91,0xd8,0xce,0xb5,0xc2,0xda,0x58,0x23,0x27,0xe2,0x3d,0xbe,0xf6,0x31,0x79,0x73,0x0e,0x31,0xd7,0xa3,0xaa,0xac,0xcf,0x31,0x1e,0x75,0x58,0x14,0x21,0x52,0x1c,0x3e,0x4f,0x2a,0x2b,0x9a,0x22,0xbc,0x42,0x68,0x5b,0x83,0xc2,0x8c,0xd4,0xe8,0xd9,0x02,0x0d,0x13
+.byte 0x2f,0x08,0xd3,0x11,0xb7,0x4b,0x84,0x67,0x43,0xda,0x20,0xdb,0x89,0xd5,0x9e,0x14,0x54,0x3d,0x49,0xda,0xac,0x3f,0x8f,0xf5,0x17,0xfe,0xb8,0x5f,0xc3,0x20,0x38,0x27,0x21,0x32,0xbf,0xf3,0x9b,0x2c,0x0b,0x9b,0xeb,0x64,0x87,0xf7,0x9d,0xed,0x15,0x05,0x21,0x69,0xcf,0x2d,0xf8,0xfb,0xf2,0x81,0x51,0x08,0xc7,0x18,0x81,0xdf,0xed,0xa4
+.byte 0x70,0xb3,0x07,0xfa,0x00,0xd5,0x65,0xb9,0x5a,0x82,0x67,0x6f,0x10,0xfc,0x46,0x05,0x9a,0x85,0x64,0x14,0x60,0x64,0x4d,0x1f,0x13,0x57,0xbb,0x7c,0x4a,0x10,0x84,0x8c,0x57,0x36,0x13,0x22,0x00,0x04,0x2d,0xcf,0x27,0x3d,0xf4,0x27,0x3e,0x32,0xb3,0x87,0xda,0x82,0xaa,0xad,0xd7,0xa7,0xc5,0x3c,0x45,0xec,0x28,0x82,0x79,0x95,0x8f,0x56
+.byte 0x50,0x5f,0xc2,0x15,0xab,0x18,0x58,0x4f,0x69,0x46,0xce,0x29,0x33,0x42,0x53,0xe9,0xea,0xe5,0xa8,0x5b,0x90,0xc4,0xf4,0xbf,0x8a,0x20,0x62,0xad,0xa5,0xea,0x6a,0x4e,0xb4,0x20,0x2d,0xca,0x90,0xdf,0xbd,0xab,0x5b,0xc3,0x33,0x7c,0x53,0x1f,0xf5,0x2e,0xc0,0xbf,0x19,0xe1,0xa1,0x5a,0x63,0xf3,0x13,0x4d,0x6e,0xef,0x4f,0x3a,0x94,0x18
+.byte 0xbe,0x79,0xdb,0xbf,0xc2,0x2c,0xb3,0x36,0x59,0xab,0x21,0x1d,0x98,0x60,0x70,0xdd,0x95,0x51,0x19,0x07,0xd6,0x68,0x0e,0x2a,0xd4,0x4c,0x30,0x18,0x1c,0xe4,0xe1,0x89,0x15,0x25,0xea,0x27,0xcf,0x51,0x56,0xc9,0xa9,0xa7,0x31,0x08,0x17,0xfb,0xfc,0xf6,0x0c,0x5d,0xf1,0x7c,0x36,0xcb,0xad,0xef,0x29,0xf5,0x2e,0x23,0x09,0xcf,0x31,0x6f
+.byte 0x74,0x12,0xd2,0xc2,0xc7,0x19,0xa5,0x6e,0x20,0x09,0x67,0xdc,0x41,0x69,0xbe,0x15,0xd6,0xeb,0x7b,0xba,0x63,0xae,0x65,0xd8,0x67,0xec,0x6e,0xcc,0x1d,0x04,0x08,0xfb,0x7c,0x34,0x1d,0x5f,0x1e,0x51,0x1c,0x30,0x72,0xd3,0x0c,0x48,0x60,0x3d,0x52,0xae,0xe6,0x78,0x44,0x6d,0xb8,0x40,0x08,0xb7,0x7a,0xa9,0xfc,0xa0,0x86,0xff,0x32,0xd6
+.byte 0x5a,0x31,0x4e,0xe2,0x65,0xab,0xb0,0x84,0xb6,0x74,0x3e,0xa6,0x67,0x7c,0xa2,0x0f,0x23,0x22,0xab,0x72,0x7e,0xeb,0x45,0xa9,0x2a,0xb4,0xd3,0xcc,0x27,0x5c,0x12,0xdb,0x14,0x68,0x73,0x0f,0x36,0xbf,0x9f,0x14,0x12,0xe9,0xef,0x04,0x2a,0x63,0x41,0x4b,0x04,0x9b,0x4c,0xc4,0xb2,0xb9,0x1c,0xc0,0xb8,0xcc,0x23,0x61,0xc4,0xed,0x27,0x1e
+.byte 0x1d,0x97,0x3d,0x40,0x4c,0x1f,0xeb,0x6e,0xc4,0xfb,0x5c,0x2d,0xf5,0xf1,0xbb,0x05,0x47,0xa2,0x1a,0x9c,0x2b,0x8f,0xce,0x98,0x09,0x6b,0x86,0x22,0xf8,0x3a,0xae,0xf3,0xb4,0x66,0x2f,0xdb,0x20,0xa5,0xc6,0xb6,0x35,0xb5,0x5a,0x68,0xb5,0x37,0x2c,0xab,0x13,0x3d,0x2d,0xcb,0x38,0xed,0x3c,0x7a,0x1f,0x26,0x08,0x58,0x94,0x52,0x30,0xec
+.byte 0x06,0x9f,0x90,0x97,0x4d,0x90,0x49,0x23,0xaf,0x00,0x90,0x6b,0x96,0x37,0x02,0x4c,0x35,0xc0,0x3e,0x66,0x2c,0x52,0xbc,0x75,0x28,0xd7,0x8f,0x25,0xbe,0x91,0x10,0x22,0x67,0xbf,0x4a,0x4d,0x62,0xc4,0xe9,0xda,0xe2,0x79,0xcc,0x76,0xeb,0x99,0x87,0xac,0x39,0x7d,0xf6,0x5a,0x37,0x85,0x30,0x33,0x65,0x3f,0xd9,0xd6,0x17,0xf8,0xf0,0x86
+.byte 0xee,0x5c,0x2f,0xb0,0xb3,0x4f,0x83,0x6c,0x4a,0x8f,0xfc,0x80,0x91,0xaf,0x4b,0x21,0x9c,0x9b,0x44,0x3c,0xed,0x67,0xfb,0xa3,0x31,0x7f,0xd4,0x73,0x72,0xb9,0xc1,0x31,0x96,0x47,0x8e,0x99,0x8e,0x62,0x1a,0xfd,0xc7,0x9d,0x2f,0x4c,0xda,0xe5,0xae,0x17,0xb6,0x40,0x5f,0x9e,0xa8,0xf2,0xcc,0xd7,0xd5,0x40,0x33,0x88,0x57,0x63,0x9b,0xde
+.byte 0x82,0x71,0x68,0xfe,0xaf,0x29,0x6c,0xc1,0x2c,0x2f,0x02,0x42,0xd7,0xa5,0x28,0x05,0xca,0xa0,0xb6,0x8c,0x43,0x90,0x05,0xe2,0x1c,0xb7,0x76,0x79,0x39,0xd3,0x23,0xe1,0xe7,0xbb,0x19,0x65,0x1a,0xb4,0xbb,0x5a,0xcf,0x43,0x70,0x26,0x1a,0x2f,0x61,0x78,0x75,0x08,0xb0,0x88,0xe5,0x4a,0x46,0x0a,0xfc,0xcb,0x46,0x18,0xb0,0x8d,0x9b,0xeb
+.byte 0xf5,0xe1,0x83,0x04,0x84,0x4f,0xd6,0xa0,0x4f,0xb2,0x4c,0x44,0x08,0xde,0xd6,0x82,0xb5,0x9a,0x45,0x15,0xb8,0x21,0xc7,0xf5,0xe2,0xfd,0x02,0x27,0x18,0x13,0x24,0x18,0x01,0xd1,0x2a,0xff,0x63,0xf2,0xa4,0x97,0xc8,0x4b,0x3b,0xae,0x49,0x47,0x54,0xe8,0x75,0xe7,0x16,0x77,0x22,0x10,0x7b,0x3c,0xf0,0xdb,0x49,0x6e,0xd6,0x55,0x9d,0x43
+.byte 0x6f,0x6e,0x2d,0x97,0xea,0x16,0x2e,0x0c,0x85,0x89,0x67,0xe1,0x7b,0x38,0xa6,0x2b,0x89,0xf0,0xcd,0x90,0xcd,0xba,0x9a,0x70,0xa9,0xe3,0xff,0xe0,0xbd,0x15,0x3e,0x4b,0x13,0x62,0x7b,0x59,0x64,0x18,0x96,0xe9,0x6a,0xf3,0x69,0x2d,0x2d,0x25,0xe7,0x91,0xd3,0xbc,0x74,0x58,0x66,0x2f,0x5e,0x8b,0x52,0xf6,0x91,0x24,0xa8,0x6f,0xa5,0xce
+.byte 0xa1,0x4e,0x3b,0xe9,0xc5,0x30,0x7e,0xa5,0xc7,0xe2,0xb3,0x71,0x3b,0x25,0xb9,0x5f,0xe5,0x9c,0xf8,0x46,0x23,0xc5,0xa2,0xc1,0x1f,0x3f,0x43,0xa6,0xaa,0xf1,0x36,0x27,0xc6,0xa8,0xed,0x0d,0x50,0x71,0xf1,0x38,0x27,0xb7,0x16,0x43,0x7c,0x7f,0x77,0x5b,0x25,0x59,0xb7,0x08,0x0d,0xc8,0x84,0xe4,0xc2,0x03,0x95,0xe5,0xf3,0x0a,0x9c,0x1f
+.byte 0xde,0x98,0x7c,0xa9,0xe2,0x70,0x9e,0xde,0xf6,0x80,0xd0,0xf8,0x86,0x4a,0x7a,0x0d,0x16,0xaa,0xde,0xba,0x02,0x30,0x8a,0xe6,0x03,0x0f,0xa1,0xf1,0xe8,0xd6,0xf8,0xce,0x7b,0xba,0x74,0xa8,0x25,0xb0,0x49,0x22,0xa6,0x81,0x7e,0x71,0xc5,0x97,0x9e,0xa8,0x46,0xa7,0xe9,0x8b,0x7c,0x7c,0x4c,0xc5,0x3c,0x93,0x08,0xb9,0x8b,0x3c,0x33,0xd6
+.byte 0xc4,0x37,0xc8,0x05,0xe7,0xfe,0xc2,0x7c,0x02,0xe6,0xda,0x09,0x52,0x2c,0xc6,0xa8,0x6e,0x44,0x7e,0x55,0xf0,0x32,0x10,0xcb,0x1e,0xa7,0x77,0x8d,0xc7,0xfe,0xb5,0xf6,0x3b,0x49,0xf2,0xfb,0xe0,0x41,0x98,0xd3,0x17,0xa6,0x5d,0x3f,0x4c,0x95,0xb0,0x02,0x8d,0xab,0x36,0xb7,0xa0,0x92,0x40,0x5e,0x15,0xfb,0xa9,0xb4,0xa3,0x04,0x8b,0x6b
+.byte 0x81,0x44,0x59,0x22,0x10,0xcb,0xc5,0x52,0x3f,0x78,0x70,0x00,0xe2,0xa2,0xf7,0x76,0x62,0x72,0x06,0x8b,0xbb,0x56,0x0f,0x8c,0x67,0x2f,0x52,0x3f,0x3b,0xdc,0x15,0x79,0x55,0x89,0x6c,0x61,0x23,0xcc,0x6b,0x41,0x77,0xe5,0xc4,0x90,0x51,0xc3,0x87,0x22,0x1e,0x89,0xf5,0x5b,0x41,0xd7,0x34,0x22,0x3c,0xbd,0x29,0xaa,0x54,0xed,0x5a,0x90
+.byte 0x17,0x24,0xba,0x7a,0x46,0x5f,0x54,0x33,0x56,0x7e,0x2d,0x03,0x59,0xcb,0xbb,0x7a,0xce,0xbb,0x8d,0xf7,0xb6,0x38,0x00,0x18,0x6a,0xa1,0x6c,0xdf,0x42,0x49,0x4d,0x9b,0x4f,0xd6,0x85,0x54,0x1f,0xad,0x17,0xdd,0x66,0x0e,0x7c,0x30,0x86,0x82,0x1c,0x5a,0x81,0x08,0x55,0x51,0x5b,0x06,0x54,0x52,0x3e,0x8b,0x6e,0x72,0x92,0xd2,0x05,0x5d
+.byte 0xe4,0xe8,0x0e,0x62,0x1d,0xec,0xb1,0x7f,0x42,0x05,0xd5,0xd3,0x60,0xd4,0xdc,0xa4,0x48,0xc0,0xf0,0x89,0xef,0x5b,0xae,0x5f,0xcd,0xf0,0x62,0xaa,0x3e,0xd5,0x1a,0xbe,0xe3,0x08,0xd5,0xe8,0x00,0x21,0x8c,0x0b,0x0c,0x8e,0x24,0xac,0xb2,0xea,0x44,0x9f,0xce,0x53,0x45,0x9a,0x85,0x67,0x99,0x85,0xea,0x92,0xa7,0x1d,0x86,0xb4,0x3b,0x22
+.byte 0xa2,0xcd,0x35,0x65,0xb5,0xa6,0xdb,0x6d,0x48,0xd1,0xa4,0x76,0x0c,0x00,0x30,0x62,0x86,0x06,0xda,0xa8,0xfe,0xec,0x70,0x87,0x4a,0xe8,0x2e,0x4d,0xe3,0x94,0x0b,0xdf,0x81,0xcd,0xfe,0x23,0x79,0x2c,0x2b,0xae,0xf7,0x75,0x49,0x47,0x24,0x46,0x09,0x10,0x62,0x39,0x3b,0x50,0xf1,0xfa,0xf7,0x5f,0xe4,0x7c,0xa5,0xc0,0x25,0x9e,0x20,0x4d
+.byte 0xc8,0x6b,0x93,0xc5,0x4a,0x6b,0x62,0xb8,0x3b,0xe5,0x0d,0x92,0x70,0x26,0xa5,0x2b,0xd0,0x9f,0x03,0x8b,0xd3,0x1a,0xc4,0xb0,0xa3,0xc7,0xf4,0x35,0xe5,0x1d,0xe0,0xaa,0x43,0xab,0x64,0x10,0x2b,0xa4,0x09,0x42,0xee,0xba,0xb7,0xbf,0xfd,0xa6,0xff,0x76,0xe5,0x12,0xd6,0x50,0x9a,0x26,0x6b,0x3a,0xd3,0xe6,0x7d,0x3e,0x0e,0x9b,0x95,0xd7
+.byte 0xbf,0xb6,0x7e,0xfb,0x3c,0x24,0xa4,0x26,0x98,0x88,0x81,0xf4,0x56,0xa4,0xf7,0xe8,0x87,0x15,0x5e,0x9f,0x84,0xdd,0x04,0x66,0x43,0xd8,0x76,0xc2,0xa3,0xfd,0x4b,0x58,0x09,0x06,0xa6,0x60,0x5c,0x3f,0x75,0x80,0xd7,0xc4,0x29,0xf9,0x0b,0x1e,0x4d,0xe5,0x26,0xf6,0xae,0x7a,0xc1,0x05,0xf3,0xf1,0x6c,0xee,0xed,0x56,0x0b,0x51,0x66,0xbe
+.byte 0x99,0xec,0x9c,0xc2,0x97,0xe2,0xed,0x09,0x1d,0xa8,0x18,0xaa,0x1c,0x9e,0x20,0x62,0xb1,0x80,0x68,0x3e,0x28,0x1f,0x4f,0x50,0x0e,0x41,0xaf,0x17,0x44,0x79,0x16,0xca,0x17,0xe9,0x13,0x66,0x0a,0x04,0x68,0x41,0xe2,0x1d,0xc7,0x00,0x1e,0x66,0xa3,0x6c,0x2d,0x52,0x8c,0x0b,0x7c,0x03,0x48,0x73,0x3b,0xa9,0x84,0xe5,0x31,0x12,0x0f,0xe8
+.byte 0x1e,0x58,0x4d,0xd0,0x1b,0xb7,0xcf,0x75,0xd5,0x2c,0xca,0x33,0x17,0x95,0x9c,0x30,0xc7,0x7f,0xe9,0xde,0xae,0x19,0x72,0x00,0x2a,0xf5,0xde,0x93,0x3f,0xf5,0x44,0xe5,0xf8,0xc7,0xeb,0x1a,0x5d,0x5b,0x11,0x30,0x09,0xf5,0x49,0x66,0x70,0x1a,0xd5,0xe6,0xfc,0xe6,0x59,0x3d,0x17,0x6c,0xb5,0x0c,0xdf,0x1e,0x9c,0x48,0xd1,0xde,0x12,0xd6
+.byte 0xc8,0x48,0xc8,0x73,0x6d,0xfc,0xec,0x07,0xce,0x02,0xe5,0xb3,0x18,0xb9,0x55,0x4d,0x64,0x07,0xf3,0xaa,0x3c,0xf1,0x71,0x22,0x31,0xbb,0x74,0x2c,0x9f,0x7b,0x68,0x9d,0x80,0x49,0x32,0x48,0x9b,0x54,0xf3,0x74,0x37,0xac,0x4e,0xb2,0x96,0xdf,0x9d,0xeb,0x43,0xe0,0xd0,0xa0,0xe3,0x77,0xbd,0x8b,0x92,0x95,0x9d,0x63,0x8d,0xa8,0x23,0x07
+.byte 0xb0,0xcb,0x9d,0x8d,0x3f,0xe2,0xd5,0x81,0x6a,0xe5,0xc2,0xfe,0xda,0x1c,0x25,0x25,0x5b,0xa8,0xad,0x06,0xec,0x0d,0x4b,0x68,0xc3,0x45,0x81,0x38,0xb0,0x22,0x71,0xa4,0x2b,0xf3,0xa6,0x05,0xae,0x0c,0x48,0x94,0x0d,0x3d,0x48,0x51,0x76,0xdf,0x79,0x66,0x0e,0x28,0xc0,0xc1,0x6f,0xc8,0x8f,0xf7,0x7d,0x37,0x06,0xa2,0x8a,0x3a,0x6b,0xab
+.byte 0xe0,0x55,0x8e,0xec,0x89,0xe2,0xca,0xc4,0x01,0x03,0x5d,0xa1,0x84,0x21,0x44,0xbb,0x6b,0x36,0x63,0x57,0x4f,0x54,0x88,0x81,0xbe,0xf8,0x53,0xf7,0x57,0xee,0x30,0x85,0x03,0x11,0x86,0xff,0xe4,0xd6,0xc4,0xf0,0x3c,0xcf,0xfd,0x38,0xd8,0xcb,0xd0,0x96,0x03,0xf2,0xc7,0xfa,0x18,0xc8,0x1b,0xe6,0x77,0x3c,0x61,0xa9,0x14,0xdb,0xb4,0x5c
+.byte 0x2d,0xee,0xd7,0xe8,0xc4,0x0c,0x69,0x0c,0x55,0xe2,0x99,0x4b,0xc4,0x89,0xc8,0xee,0x48,0x0e,0x16,0xd7,0xa4,0x78,0x25,0xda,0xd3,0xa8,0xac,0x89,0x66,0x67,0x0d,0x51,0x21,0x0e,0x91,0xfb,0xb5,0xab,0x33,0xcb,0x3e,0xc7,0x0f,0x03,0x22,0x51,0x71,0x03,0xa0,0x3c,0xa9,0x35,0xcb,0x40,0xa7,0xbe,0xe7,0xc3,0x51,0x43,0xd8,0x9a,0x24,0xb7
+.byte 0x7e,0xfb,0x26,0x8d,0xa5,0x1a,0x6b,0xe7,0x97,0xe4,0xdd,0xc0,0x3e,0x98,0x67,0x55,0x79,0x56,0xb9,0x7e,0x25,0x4c,0x5c,0x5a,0x47,0x0a,0xce,0xb6,0x4d,0x2c,0x69,0x73,0xaa,0xf0,0x12,0xbb,0x9d,0xe1,0x60,0xc4,0x5b,0x10,0x32,0x6d,0x89,0x54,0xb1,0xfe,0x36,0xbe,0xb2,0x60,0x9a,0x91,0x73,0x9c,0x32,0x61,0xad,0x9a,0xf7,0x56,0x5f,0x5a
+.byte 0x54,0xaf,0xb2,0x0c,0x5b,0x1a,0xe6,0x98,0x94,0xed,0x69,0x0b,0x8d,0x06,0x87,0xc9,0x20,0xdc,0x92,0x2d,0x5e,0xba,0xbb,0x15,0xef,0xc1,0x07,0x18,0x44,0x3f,0xf4,0x48,0x3e,0x7b,0xa4,0x9e,0x14,0x6b,0x97,0xdd,0x68,0x33,0x18,0xdd,0x47,0x08,0xa6,0x3b,0x8d,0x79,0x58,0x92,0xd9,0xda,0x82,0x34,0xa7,0x99,0xbc,0x43,0xa3,0x0a,0x7e,0x85
+.byte 0x0b,0xab,0x0e,0xc2,0x94,0x22,0x2d,0x05,0x99,0x9d,0x5c,0xc7,0xb2,0x7b,0x18,0x3e,0xb2,0xdd,0x47,0xb3,0xd7,0xcf,0x19,0xc7,0x55,0x5e,0x64,0xd8,0x7b,0xb4,0xf6,0x11,0x72,0xed,0xbd,0xfc,0xd8,0xe9,0x9f,0xcd,0x9a,0xeb,0xb2,0x6c,0x04,0xb9,0x88,0xf7,0x60,0x68,0xc3,0xf2,0xfd,0xa0,0x8c,0x82,0xc5,0xf7,0x5d,0xc3,0x9a,0x1e,0x49,0x27
+.byte 0x69,0x35,0xb0,0x8f,0xe9,0xb3,0xe4,0x09,0xd8,0x1a,0x73,0x9e,0x56,0x41,0xfa,0xe0,0x94,0x9e,0x0e,0x65,0xe6,0x5b,0xe2,0x12,0x39,0xca,0x86,0x0c,0xae,0xee,0x24,0x58,0xfd,0x85,0x09,0x7a,0xad,0x54,0xde,0xda,0x06,0x73,0x7d,0x11,0x7e,0x91,0x44,0xf3,0x4b,0x61,0xce,0x8a,0xff,0x76,0x92,0x2e,0x43,0x52,0xcf,0x63,0x3f,0xc4,0x1f,0x7f
+.byte 0x4d,0x67,0x21,0xed,0xd7,0x88,0xdb,0x36,0x56,0x11,0xb2,0x3b,0xee,0x5f,0x2d,0x5f,0x17,0x98,0xa1,0xd5,0xcc,0x82,0xfd,0xc2,0x56,0x69,0xaa,0x68,0x86,0xaf,0x48,0x77,0xba,0xe9,0xd9,0x42,0xcd,0xaa,0xe3,0xad,0x2b,0x17,0xef,0xd3,0x54,0xc5,0x4e,0x31,0x0b,0x14,0xb7,0x73,0xc1,0x6f,0xc3,0x06,0x41,0x1a,0x11,0x19,0x9f,0xe9,0x9f,0x61
+.byte 0x4f,0x13,0x9b,0x3e,0xcd,0x7c,0xd6,0x2a,0xb3,0x87,0x84,0x58,0x58,0x10,0x1f,0xa0,0x2e,0x5c,0x15,0x8b,0x5e,0x37,0xd4,0x22,0x93,0xd9,0x67,0xe1,0xa8,0x35,0xe2,0x95,0xd8,0x4c,0x2c,0x65,0xc9,0x21,0xaf,0xf9,0xdd,0x3d,0x2c,0x0e,0x0c,0xcc,0x6b,0xad,0xb3,0x6d,0xd2,0x3e,0x65,0x8e,0x82,0x70,0x41,0xd6,0xaa,0x97,0xab,0x38,0x78,0xe4
+.byte 0x62,0x7c,0x5f,0x22,0xa3,0x1e,0xf2,0x6c,0xfe,0x3c,0xa9,0xb5,0x57,0xcd,0x96,0x11,0xd0,0x8b,0xcf,0x6d,0x06,0xcf,0x7c,0xda,0x1d,0xe4,0x22,0x5c,0x5d,0x9f,0xa8,0x24,0x55,0x45,0x93,0xc6,0xeb,0xfc,0xb5,0x71,0x5a,0x1d,0x52,0x40,0x95,0xc7,0x76,0x32,0xfb,0x2b,0x0c,0x7d,0x64,0xfa,0x5b,0x5e,0x7a,0x3b,0x0b,0xa0,0x99,0x5d,0x19,0x16
+.byte 0xe4,0x8e,0xae,0x49,0xee,0xc5,0xb2,0x24,0xd7,0x0b,0xa4,0x20,0xa6,0x74,0xc4,0x36,0x1d,0x43,0x25,0xd6,0x71,0x54,0x69,0x79,0xea,0xa3,0xd5,0xe9,0x75,0x53,0xcf,0x99,0x4e,0x3b,0xc0,0x52,0x28,0x80,0xe5,0x07,0x65,0x83,0xb3,0x24,0xfe,0x13,0x92,0xd6,0x18,0xf7,0xa3,0xeb,0x9e,0xf0,0xd5,0x69,0x93,0x79,0xda,0xb7,0x2e,0xe2,0x01,0xdd
+.byte 0x9a,0xc3,0x7b,0x3b,0x17,0x88,0xe5,0xe9,0x9b,0x46,0x5c,0x5f,0x0e,0x1e,0x80,0x9b,0x11,0x1f,0xa4,0x08,0x90,0x14,0x08,0xb4,0x73,0x32,0x72,0xbe,0x43,0x4f,0x70,0x90,0xe7,0x80,0xdd,0xfd,0xa7,0xea,0x13,0xd9,0x5d,0xae,0x93,0x24,0x2b,0x1e,0xc7,0xf4,0x81,0xbb,0x5f,0xb0,0xb9,0xe4,0x35,0x39,0xf4,0x9a,0x49,0xb5,0xc0,0x47,0x18,0xc3
+.byte 0xcc,0xbe,0x26,0x36,0x44,0x2d,0x65,0x24,0xa3,0x09,0xde,0x69,0x3b,0xb8,0xdc,0x52,0x98,0x2e,0x38,0x5f,0xf7,0xb1,0x84,0xdd,0xea,0xe2,0xe5,0xec,0x96,0x31,0xb1,0x93,0xc0,0x5b,0xc4,0x87,0x4a,0x51,0x58,0x2d,0xea,0x47,0xab,0xfd,0xd3,0x76,0xf1,0xbc,0x52,0xa7,0x94,0x6c,0x74,0x1e,0x84,0x07,0x1f,0x5c,0x18,0xb9,0x06,0x37,0xf0,0xfb
+.byte 0xbd,0x5d,0xaf,0xa8,0x06,0xc9,0x86,0xf0,0xd1,0x78,0x84,0x95,0x01,0xdd,0x70,0x9d,0x71,0x51,0xb7,0x80,0x69,0xbe,0xe8,0xfb,0x8f,0x43,0x72,0xd9,0xa9,0xf1,0x90,0xbb,0xf1,0xb5,0xc0,0x75,0x93,0x4e,0x14,0xc5,0x14,0x77,0x59,0xf8,0xe5,0x81,0x11,0x25,0x48,0x51,0x46,0x2a,0x69,0x59,0x92,0xe7,0xa7,0x39,0x96,0xad,0x67,0x30,0xaa,0xb2
+.byte 0x5d,0x95,0x94,0x83,0x83,0x93,0xf3,0x52,0x81,0x1c,0x27,0x78,0x1d,0x19,0x35,0x6e,0x8f,0x16,0xe5,0x3b,0xce,0x80,0x2a,0x3a,0x89,0xb7,0x51,0xfc,0x34,0x24,0xa2,0x61,0x95,0x9e,0xd4,0x69,0xa1,0x2f,0x49,0x16,0x2d,0x12,0x05,0xfe,0x69,0x62,0x12,0xa4,0x2c,0x04,0x7b,0xce,0x3f,0x34,0xc4,0x48,0x1a,0xe6,0x64,0x4b,0x8a,0xbf,0x68,0xdd
+.byte 0x54,0x15,0xd3,0x25,0x49,0xdd,0xed,0x5e,0x2c,0x0e,0x25,0xbe,0x77,0xcf,0x94,0xf4,0xe9,0xf3,0xcc,0xe6,0x94,0xf9,0xb2,0x5d,0x24,0x53,0x63,0xbb,0x66,0x8d,0x73,0xef,0x79,0x5c,0x95,0x1a,0x64,0xc3,0xfd,0xc0,0xd3,0x71,0xf4,0x79,0x19,0x79,0xa5,0x30,0xf8,0x2c,0x28,0xc2,0xc2,0x9d,0x12,0x50,0x95,0x38,0xec,0xd5,0xc6,0x28,0x94,0xaa
+.byte 0x83,0x66,0x3b,0xe3,0x51,0xc7,0x6a,0x75,0x2a,0x9b,0xb9,0xb0,0xa2,0xe1,0xfd,0xaf,0x58,0xd2,0x4b,0xf4,0x22,0xef,0x77,0x1e,0xa0,0x00,0xd7,0x9e,0x20,0x63,0x87,0x1d,0x98,0xab,0x0e,0x57,0x31,0x4b,0xda,0x90,0x3a,0xe6,0x6e,0x5e,0xd4,0x17,0x06,0x83,0x4f,0x90,0x33,0x1c,0xe5,0xea,0xf7,0x8d,0x95,0xa2,0x1e,0x7d,0x27,0x15,0x49,0x68
+.byte 0x3a,0x54,0xe3,0x1e,0x60,0x72,0x42,0xa6,0x8c,0x5b,0x63,0x1d,0x7d,0xb1,0xe2,0x7e,0x8b,0x19,0xf4,0x25,0x6c,0x77,0x64,0x15,0x5e,0x4c,0xfa,0x35,0x68,0xd2,0x54,0x11,0x5a,0xac,0x85,0xb0,0xb3,0xe8,0xa8,0x70,0x36,0xa8,0xe5,0x04,0xd1,0x82,0xdc,0x62,0x63,0xe6,0x3f,0x86,0x46,0x77,0x08,0x6b,0xa8,0x09,0xd0,0x56,0x09,0x87,0x9c,0x65
+.byte 0x8e,0x53,0xae,0xa6,0x2b,0x59,0x23,0xca,0xe9,0xc7,0xc4,0xb5,0xb9,0xca,0x20,0xf6,0xcc,0x62,0xfd,0xb5,0x66,0x66,0x86,0x99,0xb2,0x5a,0xeb,0xac,0xff,0x22,0xf4,0x94,0x9c,0x6d,0xc9,0xce,0xf3,0x8d,0x26,0x7f,0x06,0x40,0x71,0x8b,0x3e,0x5c,0x3e,0xe6,0x11,0x64,0x91,0x79,0xbe,0x66,0x80,0xd2,0xf6,0x2d,0x28,0x4b,0x6c,0x8d,0x9c,0x5b
+.byte 0x1e,0xd1,0x15,0xb0,0xdf,0xfb,0x57,0xaf,0x4a,0xab,0xde,0x12,0xe9,0xb8,0x41,0x3d,0xc3,0xff,0xb2,0xc1,0x86,0xb0,0x06,0x5b,0xaf,0xa4,0x30,0x62,0xd0,0xd8,0x91,0x36,0x28,0xc1,0xc2,0xef,0x60,0x5d,0x42,0x04,0xd5,0x6b,0x10,0xa9,0x6c,0x88,0x5c,0x56,0x59,0x4a,0x87,0xdc,0x7c,0x41,0x03,0xb3,0x7c,0x35,0x8c,0x52,0x0e,0xc1,0xd5,0xdf
+.byte 0x9b,0x8a,0x2e,0xc2,0x6b,0x06,0x7f,0xb4,0x93,0xc9,0x52,0xd0,0xc5,0x57,0x78,0x9e,0xf9,0x08,0x36,0xbc,0x4b,0xc1,0xbd,0x71,0x35,0xf8,0x73,0xae,0x9c,0xbc,0xf1,0xd1,0xba,0xe3,0x7f,0x49,0x9b,0x9b,0xb3,0xe2,0x7d,0x7d,0x18,0x6d,0x0d,0x96,0xe3,0x50,0x28,0xf2,0x7c,0x7a,0x71,0x27,0x33,0x3c,0xd3,0xeb,0x3d,0x5a,0x79,0xb5,0x69,0xed
+.byte 0x40,0x38,0xbe,0xc9,0xad,0x11,0x7b,0x9d,0xe6,0x71,0xc8,0x89,0x54,0x51,0xf0,0x8f,0xdc,0xad,0x96,0xc3,0x04,0x60,0x5f,0x6d,0xa0,0x37,0xba,0x1c,0x69,0xca,0x42,0x26,0xeb,0x31,0x34,0x8d,0xae,0x25,0xe2,0x29,0x8d,0x19,0x9f,0xfa,0x75,0x91,0x4b,0x51,0xcd,0x76,0xd6,0x8f,0xa2,0x40,0x79,0xc3,0xbb,0x61,0xaf,0xc4,0x69,0xf5,0x8b,0x8a
+.byte 0xb6,0x2c,0x25,0xb9,0x3c,0x8e,0x13,0xa4,0x0f,0x52,0x72,0x11,0x4b,0x89,0x63,0x01,0x05,0x54,0xd5,0x0d,0x5f,0x91,0x59,0x84,0x64,0xac,0xf7,0x9c,0xa3,0x48,0x31,0x4a,0x2e,0xea,0xf8,0xf8,0x0e,0xf0,0xd9,0x4d,0x06,0x60,0x11,0x4a,0x72,0x6f,0x93,0x93,0x85,0xf0,0x20,0x55,0x8b,0x37,0xf1,0x29,0x92,0x2d,0x1f,0xa1,0x6c,0x7c,0x90,0x4f
+.byte 0xdb,0x78,0xcc,0x6c,0xb2,0x14,0x85,0x07,0x34,0xc8,0x98,0x18,0x52,0x2d,0x6b,0x13,0x63,0xc5,0x31,0x20,0x8e,0xa9,0x88,0x6b,0xb3,0x3f,0x1a,0x68,0x2f,0xf9,0xf3,0x97,0x29,0x68,0x22,0x89,0xb0,0x45,0xc4,0xf4,0x1f,0x31,0xba,0x97,0x14,0x59,0xae,0x05,0xe0,0x99,0x5b,0x29,0xcf,0xe3,0xf0,0x2a,0x0c,0xca,0x5f,0xc1,0xe7,0xe7,0x11,0x48
+.byte 0x73,0xc0,0x86,0x0b,0x59,0xc2,0x8a,0xfa,0x44,0x51,0x1c,0x84,0xdf,0x2f,0x4d,0xab,0xca,0xea,0xe1,0x48,0x9a,0xa1,0x86,0x60,0x47,0x7a,0x86,0x30,0x6a,0xba,0xbe,0x6a,0x9b,0x34,0xf4,0x52,0x0e,0xae,0x7f,0xbd,0xe0,0xf4,0x5f,0xfd,0xbc,0x57,0x02,0x95,0x6f,0xad,0x78,0x2e,0xa7,0x46,0x1c,0x2d,0x98,0x40,0xb7,0xfa,0xb5,0x08,0xee,0xb5
+.byte 0x25,0x51,0xaa,0x1a,0x14,0x41,0x48,0xe0,0x8f,0xe7,0x2f,0xfc,0xfd,0x47,0x10,0x55,0x90,0x02,0xeb,0x7f,0x0d,0x40,0xa8,0x4b,0x82,0xdc,0xab,0x43,0x35,0x62,0xa1,0x1d,0x5a,0xb0,0xc0,0x93,0x75,0x3d,0x68,0xd9,0xf8,0x31,0x22,0xfd,0x30,0xda,0xea,0xea,0x7c,0x30,0xf8,0x6f,0x75,0x5f,0x07,0x39,0xfe,0x69,0x93,0x73,0x22,0xa2,0x72,0xed
+.byte 0x39,0x2f,0x00,0x5c,0xc3,0x14,0x86,0x90,0xda,0xc9,0x09,0x43,0x80,0x85,0x22,0x98,0xb0,0x4e,0x05,0x47,0x8f,0xc7,0xba,0x2e,0x4c,0x8f,0x57,0x8a,0xe9,0xb0,0x97,0x3b,0x51,0x12,0xcb,0x88,0xfd,0x5e,0x7f,0xa6,0xc6,0x00,0xd0,0x3a,0x3a,0x70,0x9e,0x56,0x28,0xa0,0x08,0x76,0x58,0x57,0x4a,0x0f,0xff,0x31,0x44,0x08,0x6c,0x23,0x79,0xad
+.byte 0x35,0x95,0xc5,0xc8,0x26,0x0f,0xb3,0x17,0x04,0x1d,0xde,0x16,0x5d,0xb8,0x71,0x76,0x89,0x0b,0xd6,0xd8,0x9d,0xa1,0xdf,0xcb,0xb5,0x1c,0x86,0xc3,0x15,0x8d,0xaa,0x25,0x82,0xbf,0x6b,0x06,0xfb,0x1b,0xf5,0x11,0xaa,0x14,0x0e,0x67,0x7f,0xbd,0x46,0x21,0x8f,0x6d,0xbd,0x63,0xe6,0x14,0x05,0xa2,0xee,0x56,0xee,0xe6,0x37,0xf9,0xc0,0x2f
+.byte 0xc9,0xe0,0x8e,0xdb,0xf7,0xf6,0xcb,0x83,0x79,0xcc,0xe3,0xf6,0x30,0x9d,0x56,0x31,0x40,0xd2,0x50,0x25,0xb6,0x89,0x16,0x97,0x65,0xd8,0x8d,0x1a,0xa5,0xf4,0x47,0xfc,0x4c,0x73,0x07,0x42,0x9c,0x8f,0x7f,0x10,0xb4,0x96,0x33,0x1e,0xe2,0xff,0x0c,0x33,0x35,0xbc,0x37,0x01,0x2b,0x67,0xda,0xca,0xcf,0x87,0xa2,0x38,0x71,0x6b,0xf4,0xcf
+.byte 0xa6,0xc6,0x6a,0x90,0x5c,0xa0,0x8b,0x66,0x44,0xc7,0xc2,0x05,0x24,0xee,0x53,0x99,0xf3,0x07,0x78,0xb0,0x17,0xf8,0x11,0xf9,0x52,0x20,0x41,0xc5,0xdb,0x4e,0x92,0xd3,0xeb,0xd2,0x86,0xea,0x9b,0xc3,0x4c,0x1b,0x75,0xcd,0x15,0x0c,0xe0,0x28,0xe9,0xe1,0x99,0x98,0x96,0x33,0x06,0xea,0xa8,0x4e,0xde,0xc1,0x1c,0xfe,0x6c,0xca,0xac,0x6d
+.byte 0xc4,0x3a,0x7d,0xd2,0x41,0xf5,0xb3,0x7d,0x1c,0x28,0x93,0x72,0xf8,0x08,0xc1,0x71,0x72,0x4c,0x41,0x68,0x38,0x80,0x2e,0x4b,0xa6,0xc5,0xc7,0xb4,0x24,0x29,0xd0,0xce,0xb2,0x3d,0xc4,0x60,0x5b,0xeb,0x2d,0x80,0x13,0xee,0x95,0x41,0xfe,0x49,0x6d,0x89,0xc0,0x7a,0x61,0x51,0x3f,0xbb,0x24,0x7c,0x64,0x5e,0x9f,0xf7,0x60,0x88,0x95,0xe8
+.byte 0x60,0xc5,0xf6,0xc3,0xc3,0xd4,0x43,0xce,0xf9,0x4e,0x35,0xf2,0xfa,0xb0,0x2b,0xe3,0xfe,0xb8,0x88,0x19,0xf2,0x89,0xc0,0xb5,0x00,0x61,0xc8,0xe5,0xaa,0xde,0x18,0xb4,0xd4,0x21,0xbe,0xcc,0x61,0xc7,0xc9,0xfe,0x22,0xcc,0x65,0xf6,0x79,0xe8,0x4d,0x1c,0x30,0x31,0x7a,0xd4,0xbc,0x98,0x2d,0x72,0x5e,0x5c,0x4f,0x7e,0x52,0x9c,0x95,0x20
+.byte 0x29,0xa4,0x0b,0xf7,0xb2,0x7d,0xcc,0xc3,0x8c,0x94,0xb0,0x09,0xf4,0x6f,0x59,0x63,0x91,0x2a,0x06,0x80,0x09,0x01,0x3c,0x73,0x83,0x42,0xa1,0x5c,0x0f,0x42,0xf4,0x74,0x3c,0x24,0x8c,0xbe,0x91,0x73,0xdf,0xf1,0xea,0x21,0xbd,0xc9,0x36,0x17,0xca,0x81,0x28,0xd9,0x4a,0xc4,0x2e,0xdf,0x4c,0x4f,0xbd,0x1e,0xbc,0xe9,0x32,0x12,0xd3,0x8f
+.byte 0x48,0x9b,0x4f,0x49,0x23,0x54,0x15,0x15,0x14,0x8b,0x18,0x64,0x7d,0x08,0x7f,0xc4,0x56,0x01,0x94,0x4e,0x50,0xe8,0xf2,0x4a,0xb5,0x3c,0xa0,0xb5,0xaf,0x55,0x70,0x44,0x41,0x5c,0xe6,0x61,0x5a,0xbb,0xf2,0xe6,0xc9,0x05,0x33,0x45,0x8f,0xbc,0xe5,0x59,0x7f,0x66,0xc5,0x61,0x4d,0x1b,0xc7,0xee,0x45,0x7d,0x57,0x8f,0x6c,0x9d,0x8b,0x87
+.byte 0x98,0xa8,0x58,0xac,0x4a,0x31,0x79,0xd6,0x26,0x08,0x2f,0x28,0x3f,0x31,0x77,0xad,0xff,0xe1,0x9d,0xa8,0xf7,0xe0,0x76,0x66,0x48,0x00,0x52,0xe8,0x9a,0xb2,0x47,0x5e,0x0a,0x87,0x86,0xaf,0xf6,0x7d,0x46,0x78,0x66,0x68,0xf7,0x68,0x0c,0x6f,0x5c,0xd7,0x09,0xc0,0xd7,0x90,0x98,0xe2,0x5c,0x07,0xe9,0xd1,0x58,0x48,0x57,0x9f,0x48,0x99
+.byte 0x87,0xdf,0x06,0xc1,0x35,0x0f,0xd8,0xb0,0xa9,0xfa,0xdc,0x31,0x76,0xd1,0xad,0x47,0x80,0xe4,0x74,0xe0,0xda,0x4b,0x77,0x8b,0x71,0xab,0x9a,0x8e,0xd7,0x6b,0x91,0xb1,0xdb,0x78,0xd2,0x86,0xf7,0x61,0x1b,0xdc,0x34,0x57,0x32,0x51,0xee,0xd3,0xff,0xb2,0x6c,0x6a,0x79,0x90,0x9c,0x1f,0x6b,0xe7,0x43,0x20,0x05,0x4f,0x66,0x83,0xd0,0x56
+.byte 0xe1,0x21,0x63,0xf4,0xd6,0x96,0x91,0xcb,0x51,0x3c,0x13,0x88,0x97,0x26,0x88,0xda,0x7c,0xd4,0x0d,0xcb,0xdf,0xc2,0x7d,0xcd,0x2c,0x0e,0x28,0x23,0x21,0x5f,0xbe,0x5d,0x62,0x58,0x6c,0xa7,0x45,0xae,0x1f,0xac,0x35,0x53,0xdb,0x2c,0xa6,0x71,0xe4,0x11,0x5e,0x59,0xbe,0xd5,0x20,0x2a,0xc4,0xcd,0x4c,0x1b,0xe0,0x38,0xef,0x02,0x0c,0x5f
+.byte 0x5a,0x1b,0xf9,0x1e,0x32,0x63,0xd7,0xa6,0x0f,0x1d,0x98,0xd5,0x3a,0x0f,0xf6,0xcc,0xfc,0xd6,0xb4,0x87,0xc5,0x76,0xd8,0x3e,0x72,0xb0,0x20,0xfe,0xb3,0xfc,0x48,0x4c,0xd1,0x71,0xcd,0x13,0xef,0xe8,0x40,0xd9,0x0d,0xf6,0x1d,0x5b,0xa4,0x26,0x56,0x8c,0x66,0xcb,0x18,0x5a,0x5f,0x86,0x43,0x2c,0xa4,0x1e,0x00,0x3f,0x09,0xbf,0x8e,0x61
+.byte 0xad,0x2a,0x44,0x97,0x35,0xb2,0xf3,0x50,0x5f,0xfa,0x01,0x74,0xbf,0x70,0x46,0x38,0xf1,0x15,0xaa,0x04,0xfe,0xe9,0x3f,0x43,0x2f,0x53,0xcb,0xea,0x5c,0x04,0x8e,0xe6,0x43,0xeb,0xc0,0xd9,0xbf,0x4a,0xc1,0xbc,0xf9,0x11,0xd5,0x33,0xdc,0x41,0x8e,0xfe,0x5e,0xf3,0x8c,0x80,0x47,0x46,0x01,0x9e,0xa9,0x2c,0x2d,0xd2,0x90,0x7f,0xce,0x7c
+.byte 0x59,0x78,0xaa,0xbb,0x96,0x52,0x0a,0xf3,0x18,0x1f,0x0b,0x41,0xc1,0xd5,0x12,0x14,0x1a,0xe1,0x4e,0xac,0xf8,0x2a,0x56,0xfe,0x66,0x34,0x21,0xdf,0x1f,0x6a,0x02,0x85,0xd2,0x38,0xc0,0x39,0x5c,0xa7,0x3f,0xcc,0x2b,0x6f,0x69,0xe7,0xa7,0x0a,0x36,0xf1,0xa9,0x77,0x59,0x2c,0x44,0x8b,0x72,0xc9,0xc2,0x74,0x32,0x48,0x76,0x19,0x1e,0x49
+.byte 0x10,0xe6,0x46,0xdf,0x82,0x9b,0xad,0x4e,0x40,0x20,0xd7,0xd3,0xf5,0x5c,0xbc,0x25,0x94,0xd1,0x68,0xaf,0x29,0xc5,0xcd,0x1b,0x86,0x4b,0x88,0x21,0x6e,0xeb,0x06,0x14,0xb5,0x15,0xe7,0x26,0x01,0x05,0x4e,0x3a,0x2a,0x24,0xbe,0xf2,0x64,0x6e,0xf4,0x9c,0x60,0xf8,0xd4,0xfd,0x4b,0xc0,0x0e,0x68,0x0d,0x19,0x26,0x87,0xa5,0xbf,0xe1,0x16
+.byte 0xf0,0x27,0x58,0xa8,0x3a,0xed,0x27,0x5b,0x73,0x4f,0x19,0x40,0x58,0x36,0xf6,0xfd,0x60,0x37,0x09,0x74,0x3c,0xb9,0x76,0x9a,0x32,0xfd,0x98,0x79,0x53,0xb3,0xea,0x3a,0x98,0x21,0xf9,0xb2,0x97,0xe4,0x00,0xb6,0xed,0x67,0xc4,0x76,0x8f,0x1e,0x4d,0xc8,0x2e,0xf4,0x54,0xd9,0x09,0xd7,0xcb,0xa0,0x91,0x1e,0x5a,0x60,0x53,0xbc,0x3e,0x35
+.byte 0x69,0xa6,0xca,0xf3,0xce,0x41,0x84,0x71,0xee,0xf3,0x75,0xd4,0x7a,0x71,0x36,0x62,0xe3,0x08,0xae,0x40,0x05,0xde,0x01,0x34,0x92,0x5f,0x71,0xa9,0x08,0xb3,0x43,0xcd,0xe7,0x2f,0x42,0x7e,0x9c,0x1e,0xfe,0x9a,0x40,0x99,0x58,0x31,0xd9,0x8d,0x5d,0xda,0x75,0x14,0x3f,0xae,0x45,0x27,0x85,0x47,0x7d,0x41,0x0e,0x94,0x20,0xee,0x11,0xd0
+.byte 0x1e,0xcd,0x00,0x56,0xb7,0x59,0xe6,0x58,0xab,0x2c,0xa6,0x44,0x14,0x8c,0xff,0x49,0x7b,0xe5,0xf7,0x93,0xd5,0x78,0x1a,0xe0,0x16,0xd8,0x24,0x08,0x1e,0x70,0xce,0x1a,0x84,0x87,0x6b,0xe5,0xf2,0x43,0x5f,0xb3,0x34,0xaa,0x85,0x3e,0x9e,0x2e,0x86,0x22,0x74,0xe2,0x1a,0x87,0xfb,0x1b,0x6c,0x08,0x8c,0x43,0xb4,0x85,0x75,0x2c,0x13,0xc2
+.byte 0x18,0x94,0xe8,0x0d,0x09,0xd5,0x8f,0xd4,0xca,0x50,0x93,0x9f,0xa3,0x9f,0x3b,0x3c,0x54,0x68,0xa9,0xb1,0xdd,0x0a,0x0b,0xe2,0x15,0x92,0x9c,0x6f,0xfa,0x45,0x6f,0x0a,0xb4,0x6b,0xcb,0xdc,0xa4,0xf3,0xf0,0xa6,0x1c,0x8a,0x60,0x42,0x35,0xa8,0xe3,0xdf,0xc8,0xdc,0xbb,0xbe,0x95,0xa7,0xac,0x08,0x08,0xbc,0x56,0x1a,0xa4,0xc2,0xd2,0x53
+.byte 0xfa,0xb2,0x89,0x4f,0xb8,0xe4,0xb9,0x90,0x95,0x91,0x2f,0x0f,0x93,0xa9,0x8c,0xc6,0xf8,0x01,0x34,0x08,0xe6,0x8c,0x58,0x43,0x57,0x40,0xf9,0x78,0x83,0xea,0x92,0x70,0xa8,0xa5,0xc8,0x9e,0xf8,0xc6,0x39,0x4c,0xb4,0xe9,0xbb,0xdf,0xd2,0x52,0x43,0x6b,0x6c,0x8b,0x2c,0x47,0xd7,0x11,0x42,0x3d,0xc7,0x3f,0xce,0xd1,0xd9,0x28,0x5b,0xce
+.byte 0xec,0xb6,0x31,0x3a,0xc9,0xad,0x0c,0x93,0x82,0x2b,0xf6,0xdc,0xd4,0xcd,0x80,0xe1,0x75,0x45,0xeb,0x3b,0xbf,0x12,0x42,0xeb,0x71,0xc1,0x8b,0x27,0xd5,0xcb,0xd9,0xb6,0xe8,0xe9,0xc6,0x79,0xff,0x38,0x88,0x87,0x72,0xf2,0x71,0x4a,0x44,0x55,0x0f,0x9c,0x93,0xcf,0x15,0x18,0x44,0x62,0x2a,0xc5,0x0a,0x80,0x69,0x91,0x6e,0x4b,0x30,0x4e
+.byte 0x3f,0x2f,0xb5,0x65,0x9e,0x65,0x07,0x36,0x9b,0xba,0x5f,0x81,0xd9,0x60,0xbe,0x1f,0xf5,0x98,0x20,0xf9,0x9e,0x53,0xf7,0x5d,0x57,0x7f,0x22,0xaf,0x8e,0x82,0x9e,0x0f,0x33,0x74,0x37,0x26,0x61,0x67,0xf6,0xfd,0x2c,0xab,0xd8,0x18,0x1d,0x10,0x48,0x7a,0x1d,0xed,0xbb,0x57,0x83,0xf9,0x82,0xf5,0xe3,0xf9,0x98,0x5c,0xc0,0x3e,0xee,0x38
+.byte 0x0a,0x57,0x10,0x22,0xc4,0xe8,0x1d,0xe3,0x46,0xa3,0x81,0x5e,0x92,0xba,0xcc,0x53,0x48,0x85,0x33,0x58,0xa2,0x3e,0xea,0x0a,0xfb,0x72,0x5c,0xcd,0xd9,0xa4,0x3f,0x56,0x99,0x35,0x92,0x6c,0xe8,0xf2,0x59,0x0f,0xc8,0x6a,0x21,0xb2,0x9f,0xa2,0xf6,0xf3,0x1b,0xec,0x38,0x95,0xed,0xef,0x00,0x09,0x16,0x6e,0xf7,0xf8,0x1a,0xef,0x0d,0x2b
+.byte 0xef,0x83,0x8a,0xc2,0x22,0x3d,0x50,0xa3,0x70,0x52,0xe8,0xad,0x11,0x44,0x83,0x80,0xfe,0x88,0x7e,0x40,0x02,0x8f,0x4a,0x5d,0xd3,0x28,0x66,0x75,0x5a,0xf2,0x38,0xb5,0xdc,0x54,0xa8,0xb3,0xaa,0x76,0xdb,0x73,0xe0,0xd1,0xd7,0x51,0x20,0x8c,0x38,0x18,0x46,0x25,0x2e,0x0d,0x5b,0x61,0x9d,0x36,0x9a,0x14,0xfb,0xc8,0x4e,0x5a,0xba,0xa1
+.byte 0x98,0x34,0xfd,0x05,0x2c,0x87,0x58,0x8d,0xe3,0x5d,0x79,0x5a,0x45,0xff,0x75,0x25,0x98,0xbd,0xe4,0x9d,0x1a,0x70,0x79,0xaa,0x44,0x1a,0x10,0x7f,0xfb,0xe9,0x30,0x81,0xc7,0xa2,0x81,0x41,0x49,0x41,0x4e,0x42,0x5f,0x8a,0x9b,0x10,0xe2,0xdc,0xd9,0xdf,0xbd,0x61,0x29,0x72,0xa5,0x39,0xb7,0xf6,0x9f,0x4e,0x98,0xb8,0x04,0xae,0xd7,0xda
+.byte 0x9a,0x9f,0x08,0xb8,0x2c,0x40,0x14,0x6d,0x01,0xb7,0x86,0x58,0x55,0x42,0xe5,0xdb,0x5f,0x4a,0xef,0xd8,0xed,0xdf,0x3b,0x24,0x1c,0xe4,0xb1,0x73,0xd1,0xce,0x29,0x96,0xde,0x8e,0xf3,0x1d,0x8d,0x75,0x57,0xd3,0x9a,0xf8,0xff,0x1a,0x4c,0x0c,0x47,0x82,0x83,0x73,0x34,0x43,0x55,0xfa,0xf2,0xd4,0x38,0xed,0xde,0x6d,0x24,0x55,0x90,0x06
+.byte 0xd6,0x03,0x52,0x28,0xc7,0x38,0x4a,0x16,0x95,0x4d,0xf4,0x46,0x56,0xf7,0x63,0x1f,0xe4,0xa9,0x51,0xc6,0x0b,0x85,0x42,0x40,0x8e,0x49,0x1e,0xc2,0xab,0xeb,0xda,0x99,0x26,0xf6,0x6e,0x00,0x8f,0x26,0x82,0xef,0x03,0xb0,0xd4,0xdb,0x54,0x46,0xdf,0xdc,0x23,0xaf,0xa8,0x6a,0x9f,0xb7,0xf9,0x41,0x07,0x5e,0x2d,0xcf,0x85,0xfd,0x9c,0x46
+.byte 0x30,0xb9,0x14,0xca,0xe2,0x30,0x12,0x06,0x88,0x08,0x05,0x2c,0x9a,0x4b,0x52,0x98,0xa9,0x99,0xd7,0xca,0xb5,0x1e,0x60,0x44,0xd9,0x5c,0x19,0x42,0xbe,0xa5,0x04,0xfd,0x7a,0xfc,0xb9,0xdf,0xd6,0xe3,0x6d,0x02,0xe3,0x96,0xf6,0xae,0xf3,0x78,0x1d,0x90,0x6d,0x86,0x17,0xf7,0xb7,0x6b,0x1d,0x52,0x32,0x5b,0xc0,0x31,0xaf,0x09,0x90,0x5e
+.byte 0x81,0x75,0x17,0x47,0x6b,0x5e,0x9a,0x40,0xa5,0xa8,0x84,0x60,0xdc,0xdb,0xd2,0x89,0xcd,0xb2,0x72,0xf4,0x74,0xda,0x5d,0x34,0xf8,0xc6,0x1b,0x26,0x3e,0x8b,0xc7,0x73,0xf9,0x0c,0x93,0xf4,0x40,0x02,0xe0,0xed,0xe5,0xa0,0xae,0x91,0x03,0x85,0xa8,0x2f,0xe2,0x72,0xfe,0x17,0x7d,0x2b,0xa6,0x39,0x10,0x80,0x4c,0x58,0xaa,0xd8,0x22,0x7d
+.byte 0x2f,0xbf,0x0c,0x40,0x48,0xfa,0xbe,0x40,0x4c,0x32,0x96,0x69,0xa5,0xab,0x0b,0x1e,0x33,0x9b,0xcf,0xe6,0x4e,0x2b,0x41,0x5a,0x21,0x23,0xa1,0xbb,0xd3,0xd6,0xd1,0xfd,0xbd,0x55,0xfc,0x92,0x92,0xcb,0x4b,0x72,0x39,0x8b,0xeb,0x72,0xdd,0xf7,0x77,0x43,0x52,0x2f,0x99,0x14,0x6e,0x41,0xce,0x1d,0x57,0x2c,0x09,0xd2,0x18,0xec,0x1b,0x89
+.byte 0xa0,0xe9,0xfe,0x1e,0x41,0xda,0x0f,0x76,0x02,0x38,0xec,0x9a,0x30,0xb7,0x5a,0x54,0x70,0xbc,0xe8,0xfa,0x06,0xd0,0x80,0xfb,0x27,0xd2,0xd8,0x00,0x80,0x65,0x9d,0x23,0xfd,0xad,0x26,0xb8,0xdc,0x09,0x4f,0xfb,0x52,0xcd,0xe4,0x41,0x68,0xca,0xdd,0xbc,0x2a,0x62,0xeb,0xa6,0x32,0x71,0xb0,0x08,0xb6,0x9f,0x3e,0x74,0xfe,0xb0,0xd4,0x9d
+.byte 0x9e,0x6c,0x50,0x96,0x8a,0xde,0xd6,0xe9,0xde,0x2c,0xa6,0xf0,0x9f,0x67,0x00,0x50,0x0a,0x8c,0xe5,0xc2,0x37,0xcc,0xf0,0x53,0xeb,0x72,0xf2,0x87,0x77,0xee,0x80,0xe8,0xb2,0xa1,0x13,0x52,0x70,0xe6,0x8f,0x70,0x17,0x90,0x60,0xcb,0xac,0xb2,0x72,0xef,0xd9,0xb5,0xc3,0x68,0x57,0xdf,0x2d,0xcb,0x5a,0x35,0xf9,0x2e,0xfb,0xef,0x6e,0x77
+.byte 0x5d,0x21,0x37,0x4b,0x36,0x9b,0x3f,0x03,0x65,0xc9,0x84,0xb1,0x12,0x99,0xd1,0x6b,0x00,0x71,0x37,0xc7,0x57,0x82,0x44,0x7f,0xe1,0x81,0x24,0x70,0x96,0xd5,0x27,0xba,0x36,0xf7,0x25,0xc6,0x1c,0x7c,0x1b,0xdb,0xa3,0x6a,0x3e,0xb9,0x69,0x78,0xf7,0x51,0x46,0xe2,0x74,0xd3,0xfc,0xef,0x58,0x63,0x53,0x1d,0xd7,0xd0,0x8a,0x6a,0xd3,0xb0
+.byte 0xb9,0xbb,0xba,0x43,0xbf,0x8b,0x6b,0x04,0xd2,0xb1,0xe8,0xd1,0x72,0x3f,0xdc,0x2b,0x01,0xa6,0x2f,0x9c,0x7d,0x65,0xa1,0x9f,0x9b,0x4d,0x70,0x26,0x11,0x4c,0xb2,0xe1,0x01,0x0e,0x78,0xf2,0x32,0x87,0x2d,0x8e,0x95,0x02,0x76,0xca,0xe5,0x71,0x5f,0x36,0x35,0xb9,0xbb,0xc3,0xdf,0xf3,0x1e,0x1a,0x7a,0xe4,0x2c,0xdf,0x64,0x5d,0x96,0x12
+.byte 0xea,0x5c,0x14,0x73,0xa0,0xf1,0xbc,0xa9,0x6e,0x30,0x8a,0x47,0xf0,0x4b,0x9b,0x4c,0xc5,0xb0,0xbe,0x15,0x32,0x1b,0xde,0x0c,0x39,0x6a,0x6d,0x4e,0x3b,0x69,0x4c,0xb4,0x1f,0x56,0xf0,0xa1,0xb1,0x8c,0x29,0x5c,0x87,0x54,0xf2,0x5b,0x51,0x03,0x20,0x70,0x90,0x38,0x66,0x07,0xcc,0xd7,0xde,0x96,0x40,0x82,0xee,0xb5,0x87,0x2a,0x86,0xec
+.byte 0x66,0x09,0xb7,0x4a,0xfe,0x4e,0x92,0x89,0x07,0xde,0x35,0xc4,0x6e,0x91,0x25,0xfd,0x18,0xfa,0xd9,0x8f,0xa7,0xa6,0xa7,0x6b,0x32,0xba,0xd3,0x1c,0x90,0xb9,0x8a,0x6c,0x9f,0x3f,0xb5,0x16,0x81,0x81,0xee,0xd7,0x55,0xc1,0x41,0x62,0xfd,0xe9,0x4c,0x5d,0xd7,0x70,0xdd,0xc6,0x4a,0x2b,0x42,0x77,0xe7,0x74,0xed,0x02,0x80,0x0d,0x7c,0x73
+.byte 0x8e,0xf0,0xd3,0xb0,0x20,0xbb,0xc8,0x82,0x06,0xdd,0x56,0x64,0xcb,0x9c,0xda,0xa1,0xa9,0x92,0xbc,0x8c,0x65,0x03,0xcd,0x68,0x87,0xa2,0x94,0x41,0x3c,0x36,0x96,0x1f,0xa4,0xd2,0x6d,0x5d,0x9f,0x2d,0x0c,0xf9,0x8a,0x82,0x19,0x93,0x47,0x62,0x71,0x8e,0x59,0xaa,0xf1,0x87,0xe0,0xb8,0xab,0x10,0x7f,0x4e,0xa8,0xa3,0xe2,0x32,0x58,0xb0
+.byte 0xcf,0x12,0xc0,0xf8,0x94,0x4a,0x61,0x36,0xdc,0x2d,0xb5,0x91,0xf9,0x0f,0x7d,0x91,0xd3,0xc7,0x03,0x8a,0xae,0x5c,0x22,0x8c,0x60,0x30,0xf4,0x71,0x51,0x00,0xf5,0x5d,0xe9,0x37,0x6c,0xae,0x64,0xff,0x45,0x35,0x4b,0x47,0x08,0xca,0xda,0x7b,0xe9,0xef,0xcb,0x27,0xcb,0x7e,0x3c,0xa6,0xd2,0x38,0x54,0x74,0xc3,0x7c,0xf8,0x71,0xb7,0x47
+.byte 0xe9,0xe0,0x43,0x03,0x3b,0x41,0x57,0xc3,0xda,0xa1,0xcb,0x64,0xb1,0x31,0x0d,0x12,0x45,0x3a,0xa0,0xad,0x6b,0xc7,0x26,0x62,0x50,0xcf,0x94,0x5a,0x30,0x8d,0xf6,0x91,0x49,0x9e,0xd5,0x84,0x0e,0x0c,0xe3,0x47,0x08,0x7f,0xa1,0x54,0x78,0x1b,0xa8,0x2c,0xbc,0x12,0x4f,0x7e,0x53,0x1b,0xca,0xfb,0x09,0x35,0xe0,0x9c,0x15,0xea,0xf6,0x3e
+.byte 0xb2,0x20,0x9e,0x2c,0x81,0x6f,0xa4,0xb5,0x6b,0x04,0x6d,0xd1,0x90,0x66,0x46,0xdc,0x4b,0x71,0x7e,0x4b,0x3f,0xd6,0xe1,0xa8,0xc0,0xa7,0x45,0x85,0xe3,0x98,0x30,0xda,0x23,0x68,0x55,0xd8,0x96,0xb1,0xcc,0xeb,0xe1,0x95,0x0b,0x20,0xf3,0x4c,0xf2,0xc5,0xfa,0x0e,0xca,0xf5,0xc9,0xb3,0xd7,0xb4,0x1b,0x9f,0xef,0x82,0x56,0x4c,0xc5,0xa5
+.byte 0x21,0xda,0xcc,0x19,0x69,0x68,0xcb,0x37,0xb2,0x0c,0x73,0xb1,0x13,0x61,0x6b,0xca,0xda,0xfc,0xf7,0x1c,0xbc,0xd1,0x72,0x56,0xb8,0x7d,0xa1,0xef,0xc4,0x32,0x38,0xa3,0xdb,0x8b,0x2d,0x0a,0xce,0xcb,0x86,0x51,0x60,0xd2,0x47,0xf0,0x97,0x58,0xd8,0xa5,0x12,0x77,0xfc,0x32,0x04,0x29,0x61,0xfc,0xab,0xc2,0x42,0x86,0xd9,0x57,0x80,0xad
+.byte 0x00,0xf0,0x9a,0x2a,0xac,0x52,0x27,0xd6,0xf8,0xd6,0x38,0xc8,0xfc,0xc1,0xab,0x4f,0x41,0xbf,0x8e,0x60,0x20,0xeb,0x24,0x36,0xd8,0xd8,0x25,0x6f,0xc8,0x5d,0x6b,0x00,0xdd,0x7a,0xe2,0x37,0xe4,0x13,0xd0,0xaa,0x5c,0x56,0x32,0x98,0x00,0x4b,0x8a,0x81,0xb1,0xfa,0xe8,0xf3,0xfa,0x0d,0xbb,0x66,0x6e,0x24,0xfd,0x3c,0x50,0x63,0x3a,0xf1
+.byte 0x72,0x63,0x18,0x71,0x6d,0xee,0x6f,0xf1,0x0e,0x1f,0x9e,0x9d,0x87,0x12,0x5c,0xdf,0x1d,0x9e,0xc0,0x0b,0x39,0x0e,0xd6,0x56,0x79,0x30,0xcb,0x07,0x7b,0x88,0xa5,0xbe,0xfd,0xd4,0x49,0xcc,0x92,0x6a,0xcc,0x78,0x1e,0xaf,0xee,0x89,0xc8,0x51,0x08,0x98,0x14,0x20,0xe5,0x52,0x93,0x18,0x6f,0xbb,0xdc,0xb2,0x68,0x14,0xd1,0xdb,0xe8,0x56
+.byte 0x24,0xd0,0x34,0xab,0xa6,0xfa,0xfe,0x72,0x5a,0xe3,0xe1,0x87,0x0d,0xf4,0xfa,0xa6,0xa6,0x6c,0xb6,0xcb,0xf8,0xfc,0x59,0xac,0xd9,0xb0,0xcd,0x15,0xa4,0x37,0x73,0x6e,0x70,0xc9,0x74,0xef,0x87,0x78,0x61,0xc2,0xd0,0x52,0x51,0xa9,0x2c,0xdb,0x9d,0xd9,0x3d,0xac,0xcd,0x52,0x39,0x69,0x2d,0x2a,0x4f,0xf3,0xb2,0x69,0xb9,0x01,0x3c,0x57
+.byte 0xeb,0x1b,0x0e,0x87,0xe9,0x42,0x58,0x83,0x6b,0xbc,0x72,0xc8,0x46,0x32,0x42,0x17,0x6a,0x19,0xa0,0xb3,0xf1,0x1c,0x96,0x9c,0x11,0x09,0x8b,0xc1,0x9e,0xe9,0x7f,0x18,0x8e,0xca,0xea,0x24,0x1b,0xce,0x12,0x57,0x1d,0x34,0xbe,0x60,0x60,0x2c,0xd8,0xa0,0x61,0x73,0xd6,0xf8,0xaf,0x15,0x26,0x84,0xd7,0xec,0xc0,0xbe,0x7e,0xa1,0xa8,0xba
+.byte 0x2b,0xcc,0x20,0x67,0x6e,0xea,0x48,0x79,0x23,0xea,0x14,0x36,0x85,0x0a,0x56,0x3a,0xcd,0x5b,0x51,0xa4,0xf5,0x92,0x49,0xc2,0x55,0x62,0xed,0x88,0xde,0xd0,0x0c,0x01,0x36,0xb9,0x2e,0x94,0x80,0x75,0x8a,0x21,0x0a,0x07,0x45,0x68,0xd8,0x9d,0x49,0x7b,0xa7,0xb2,0x84,0xfa,0x3c,0xc4,0xd5,0x59,0xf9,0xc3,0xff,0xcf,0xe4,0x5f,0xea,0xbb
+.byte 0x0f,0xae,0x7d,0x96,0xd3,0xe9,0x38,0xd1,0xb1,0x02,0xf6,0x4b,0x95,0x43,0x1c,0x69,0xa6,0x99,0xf5,0xdb,0x46,0x62,0xea,0x69,0x5a,0x08,0x2d,0x01,0x11,0xed,0x70,0x03,0x60,0x54,0xba,0x32,0x2c,0x0e,0x44,0x1f,0x8d,0xee,0x2e,0x39,0xab,0xc0,0xd4,0x88,0x11,0xef,0x07,0x3a,0x47,0xb9,0x6e,0x0c,0x22,0x9a,0xf3,0x89,0x01,0xfb,0xb8,0x2d
+.byte 0x52,0xa0,0x42,0x4c,0xb3,0x9e,0xf5,0x4b,0x0c,0x78,0x0a,0x3b,0x29,0xae,0x4a,0xc0,0xb2,0xa3,0xc0,0x0d,0x38,0x07,0x49,0x9c,0xda,0x7c,0x48,0x81,0xba,0x53,0x0d,0x0d,0x78,0x8c,0xac,0x9b,0x3d,0x1f,0xaa,0xc1,0x32,0x54,0xca,0x54,0xe1,0xef,0x46,0x82,0x61,0xd0,0x88,0x04,0x53,0xb0,0x34,0xc2,0x23,0x9a,0x90,0xe3,0x73,0x9c,0x0d,0x46
+.byte 0x61,0xe5,0xc0,0x42,0x87,0x4a,0x3b,0x3a,0xf9,0xab,0xbe,0x4c,0xba,0x2f,0x88,0x03,0x6b,0x52,0x25,0x8c,0x9b,0xc0,0x13,0xb6,0x80,0x09,0x85,0x97,0x64,0x6d,0x65,0xcd,0x18,0x42,0x00,0xdf,0x76,0x4d,0x67,0xbf,0x04,0x7a,0x5f,0x7e,0x3a,0x5c,0x6f,0x1d,0x12,0x5b,0xbe,0xd2,0xc8,0xe5,0x09,0x45,0x4d,0xae,0xed,0xd8,0x77,0xc5,0x6f,0xb6
+.byte 0x43,0x09,0xe2,0xee,0xc9,0x5a,0x76,0xc5,0xeb,0xdd,0x96,0x23,0xb9,0xe5,0xfc,0xf2,0x3c,0xe1,0x67,0x5f,0x1b,0x10,0x39,0x47,0x67,0x8b,0x48,0x32,0xd0,0xbc,0xa0,0xa8,0x3e,0xc3,0x30,0x21,0x18,0x54,0x49,0xfe,0x8a,0x14,0x7a,0xe5,0x6e,0xbe,0x70,0xec,0xf6,0x97,0xa0,0xa4,0xf4,0xdd,0xaf,0xf2,0xde,0x50,0x1a,0x68,0xb9,0x1a,0x4b,0x37
+.byte 0xf8,0x29,0x16,0x4f,0x8c,0xa5,0x9e,0xd2,0x72,0x7f,0xf6,0x6b,0x7d,0xac,0xe4,0x17,0x93,0x39,0x8f,0xd9,0xdf,0x50,0x1f,0xce,0xf5,0x58,0xdd,0xcd,0xc2,0xb9,0x64,0xfc,0xad,0x8a,0x3c,0x2e,0x52,0x58,0x91,0x3b,0x78,0xb4,0xfd,0x4a,0x3b,0x13,0x5d,0x20,0xd5,0xdf,0xe7,0x52,0x3d,0x4c,0x2f,0x02,0x30,0xfc,0x24,0x17,0x99,0x6e,0x4b,0xfe
+.byte 0x1d,0xf0,0xe6,0x86,0x32,0x37,0xb5,0xd5,0x09,0xa3,0xa5,0x3b,0xc1,0x88,0x9f,0x01,0x57,0x12,0x03,0x1d,0x60,0xd8,0x57,0xba,0xc6,0xfc,0xda,0xab,0x02,0xbe,0xab,0x89,0xf9,0x08,0x63,0xbd,0x42,0x11,0xf7,0xbf,0xd3,0x45,0x2b,0xa5,0x34,0x91,0x18,0xb9,0xb3,0x79,0xb4,0x15,0xa1,0x01,0x1a,0xf9,0x74,0x91,0x08,0x94,0xb2,0xf3,0xb2,0xca
+.byte 0x0a,0x3a,0x4f,0x42,0x8a,0x16,0xf7,0x9e,0xbf,0x27,0x72,0x7b,0xff,0xd3,0xb9,0x4e,0xf5,0x8e,0x68,0xb5,0x91,0x23,0xef,0xeb,0x5d,0x7d,0xd8,0xc9,0xda,0x07,0x33,0xc9,0x1c,0x4a,0x7a,0xf2,0x72,0x64,0xb3,0x35,0x2e,0x54,0xec,0xc4,0xd9,0xee,0xea,0xda,0xfe,0x8b,0x1c,0x21,0x93,0x52,0x95,0x7c,0x2d,0xfe,0x56,0x05,0xdd,0x57,0x37,0xf2
+.byte 0x54,0x1c,0xe2,0x6c,0xc0,0xaa,0x71,0x67,0xdd,0x73,0x43,0x17,0x3e,0x76,0xdb,0x60,0xb4,0x66,0x62,0xc7,0x74,0x08,0x91,0x1f,0xd5,0x4c,0xa9,0xd0,0x34,0x33,0xea,0xb0,0x2c,0x0a,0x88,0xda,0xf7,0xca,0x91,0xf6,0x5f,0x9e,0x72,0xf6,0x18,0xf9,0x19,0x9d,0x84,0xf8,0x4c,0xe1,0xeb,0x45,0x29,0xaa,0xf2,0xa6,0xfd,0x64,0xf9,0x0b,0xfe,0x09
+.byte 0x1c,0xc2,0xde,0x19,0xdd,0x0f,0x02,0x16,0x65,0x70,0x33,0xd4,0x32,0x67,0x7b,0xc4,0xbb,0x11,0x60,0x4f,0xc3,0x4d,0x29,0x23,0x7e,0x84,0x58,0x51,0x43,0x7e,0x25,0x4f,0x3d,0xd4,0xe0,0x20,0x79,0xfd,0xce,0x59,0x49,0xf8,0xd1,0x53,0xca,0x2d,0x66,0xec,0xe5,0x7f,0xc8,0x14,0x06,0xc1,0x96,0x40,0xf2,0x61,0xa7,0x1b,0xf9,0x5e,0x97,0xfe
+.byte 0x62,0x57,0x05,0xcc,0x6f,0x26,0x4b,0xa6,0x40,0x33,0x72,0x20,0xd3,0x1e,0x2b,0xb2,0x60,0xe7,0x56,0xda,0x87,0xd3,0xb4,0x5a,0x73,0x04,0xc9,0xc2,0x68,0xe3,0x18,0x74,0xd9,0x46,0x74,0x31,0xf4,0xf4,0xab,0xc4,0x0a,0xbc,0x66,0x4e,0x23,0x5f,0x92,0x7c,0x0a,0x81,0xdd,0xcc,0x79,0xee,0xb3,0x3d,0xc0,0x91,0x81,0xd0,0x79,0x39,0xd2,0x69
+.byte 0x5d,0xdc,0xc1,0x5c,0x61,0xb9,0x5e,0x87,0x32,0x73,0x70,0xd0,0xa8,0x7d,0xb5,0xd0,0xfc,0xf4,0xb6,0x55,0x9f,0x1f,0x8a,0xec,0xf4,0xb0,0x47,0xeb,0x3b,0x68,0x80,0x0b,0x79,0xd0,0x71,0x99,0xb1,0xd0,0xed,0x1f,0x9f,0x6c,0x2d,0x9d,0xae,0x1c,0x62,0x3b,0xec,0x3e,0x2f,0xb4,0x6f,0xbb,0x2e,0x1e,0xa9,0x7c,0xe8,0x5d,0x14,0x7d,0x0d,0x17
+.byte 0x6d,0x9c,0x54,0xce,0x64,0x93,0x8e,0x3b,0xa4,0xa9,0xfb,0xd9,0x44,0x06,0xbb,0xb8,0x7f,0xdf,0xd3,0xc2,0xa2,0xcf,0x5a,0xa2,0xa7,0xbb,0xb5,0x08,0xe2,0x67,0xdf,0x0e,0x4e,0xc6,0xcf,0x0a,0x79,0x1e,0xa5,0x60,0x1a,0x81,0xb1,0x8e,0x1b,0x27,0x7f,0x8d,0x28,0x50,0xa7,0x4a,0xe4,0x4b,0x61,0x6b,0xa9,0xfa,0xaf,0x82,0x83,0xfb,0x1f,0x2e
+.byte 0xfa,0xce,0x18,0x0e,0x32,0x5f,0x5a,0xcf,0xac,0xaf,0x22,0x30,0x16,0xd7,0x97,0x99,0x0d,0xb8,0x92,0xa5,0x1d,0x44,0xb2,0xa5,0xc7,0x74,0xd2,0x81,0x8d,0x5c,0x38,0xda,0x9f,0x76,0xcb,0x47,0x6c,0xb7,0x08,0xd9,0xc1,0x52,0xd0,0x64,0x0a,0xf9,0xdd,0x3e,0xe8,0x99,0x15,0x4d,0xcb,0x7b,0x25,0x53,0x8c,0x13,0xb1,0xbf,0xb7,0xca,0x2d,0xce
+.byte 0x71,0x48,0xee,0x5b,0x3a,0x01,0x5b,0xfd,0x22,0xfa,0x6f,0x17,0xcb,0x52,0xcc,0x0a,0x2b,0xbb,0x6d,0xce,0x2d,0x00,0xf5,0x9e,0x0d,0x58,0xf1,0xf4,0xa4,0x9f,0x13,0xf9,0x68,0x15,0xd7,0x02,0x41,0x6c,0x19,0x6b,0x66,0x9a,0x74,0xee,0xb4,0xb3,0xc7,0xec,0x60,0x19,0xbd,0xbb,0x97,0x22,0x7c,0x4e,0xe6,0xc6,0x00,0x03,0xa5,0x36,0x52,0xec
+.byte 0x21,0xcf,0xc8,0xda,0x2c,0x14,0xa9,0xd8,0x75,0xab,0xea,0x05,0x8c,0x24,0x28,0x63,0xbd,0x58,0x35,0xd7,0x95,0xcb,0x14,0x89,0x04,0x99,0x7e,0x67,0x0d,0x07,0x35,0xdb,0x17,0x7c,0x72,0x2d,0xbc,0x89,0x9b,0xb4,0x16,0x21,0x2f,0x90,0xe8,0x8f,0xeb,0xc3,0x8d,0x86,0x0d,0x92,0xf6,0x4b,0x80,0x36,0x96,0x6b,0xd8,0x95,0x7b,0xad,0xe8,0xbf
+.byte 0x77,0x9e,0xf4,0x93,0xcd,0xa5,0x06,0xbc,0x38,0xf2,0x57,0x25,0x54,0xfa,0x8e,0x19,0x8e,0x25,0x8e,0x3c,0x28,0xaa,0xf2,0x02,0x30,0xd4,0x47,0x89,0x36,0xb9,0xb7,0x01,0x5f,0x0c,0xd1,0x8d,0x93,0x7e,0xf0,0xf0,0xff,0x2f,0x8f,0xb5,0x97,0xa7,0x02,0xe8,0x9b,0xf2,0x51,0xe6,0x51,0x62,0xa5,0x27,0x26,0xc6,0x7a,0x39,0x7a,0xa9,0xaf,0x1e
+.byte 0x03,0xd5,0x25,0xbe,0x3b,0x19,0x46,0xc4,0xdd,0xd6,0x5e,0x6a,0x18,0xc0,0x41,0x5f,0x53,0x89,0xd3,0x16,0xfb,0x3a,0x10,0xce,0x0d,0x8c,0x04,0x4c,0xcf,0xab,0xb9,0x0d,0x6c,0x45,0x6c,0x29,0xed,0x77,0x37,0x1f,0xd8,0x10,0x8a,0xfe,0x07,0xbd,0x7e,0xd7,0xa6,0x6b,0x80,0xde,0x3e,0x2c,0xa8,0xb1,0x38,0xcc,0xab,0x10,0x69,0x8f,0x58,0x3d
+.byte 0x12,0xc7,0x9c,0xc1,0x0a,0xeb,0x3d,0x5e,0xf1,0x65,0xc6,0x09,0xcb,0x4b,0x09,0x24,0xa7,0x56,0x1d,0x1d,0x4c,0xd7,0x06,0xbd,0xe2,0x72,0x70,0xae,0x7e,0xe9,0xaa,0x97,0x6d,0xec,0xcb,0x55,0x0b,0x5d,0x45,0x3a,0x25,0x3d,0x52,0x0f,0x48,0x2f,0xe4,0xd0,0x5e,0x85,0x87,0xb6,0xa7,0x70,0x2f,0x9c,0x19,0x89,0x95,0x45,0x76,0x00,0xfe,0x27
+.byte 0xff,0xf8,0x73,0x59,0xba,0x98,0x92,0x4e,0x76,0x1a,0x90,0x1d,0xbc,0x1b,0xae,0x44,0xb6,0x63,0x86,0x4c,0x3c,0x8a,0x8f,0x3e,0x03,0x95,0x50,0x30,0xd8,0x0f,0x7f,0x6f,0xb6,0xe9,0xbe,0x2e,0xc9,0x55,0xe7,0x73,0xd6,0x77,0xdc,0xbc,0x67,0x54,0x31,0x47,0x30,0x46,0xe1,0xa4,0xf8,0xf3,0x90,0x4f,0x68,0x5a,0x52,0xe2,0xe7,0xdb,0xd9,0xfd
+.byte 0xf6,0x36,0x2a,0xc1,0xdb,0x35,0x82,0x69,0xff,0xf9,0xea,0x53,0xff,0xcd,0x21,0x2c,0x26,0x79,0xd6,0x8c,0x74,0xe7,0x9e,0x85,0x1a,0x04,0xf5,0xed,0x89,0x16,0xf5,0xd7,0xf1,0x89,0xf1,0xb3,0x5b,0x47,0x42,0xcb,0x92,0x2e,0x70,0xf6,0x3e,0xfc,0x20,0x87,0x70,0xec,0x30,0x16,0xcc,0x88,0x64,0x13,0x58,0xf1,0x0d,0x17,0x90,0xc4,0xdb,0x07
+.byte 0xf5,0xe3,0x34,0x31,0x10,0x9c,0xa4,0x6a,0x4a,0xe6,0x6c,0x80,0x49,0x07,0x23,0x21,0xd6,0xf1,0xcb,0x4a,0xd1,0xb5,0xb7,0x63,0x94,0x4c,0x0a,0xce,0x90,0xf2,0x63,0x31,0x4f,0x96,0x6c,0x5d,0x3e,0xaa,0x10,0x20,0xd6,0xb6,0xbe,0xfa,0x3f,0x83,0xbc,0xa8,0x08,0x38,0xec,0x38,0xe4,0xe9,0xf5,0xb3,0x8e,0x32,0x31,0xcd,0x7c,0x08,0x98,0xf6
+.byte 0x0f,0x8a,0x8f,0xc1,0xd8,0x9e,0x05,0xb6,0x74,0x11,0x94,0xef,0x4f,0x8f,0xa1,0xc6,0x8c,0xdb,0xc3,0x27,0x4e,0xa3,0x30,0x94,0xf5,0xe8,0x2a,0x18,0x0a,0x51,0x9b,0x79,0xb2,0x1f,0xc3,0xa0,0x26,0xa9,0xf5,0xc4,0x9e,0x39,0xda,0x6a,0x53,0x8f,0x8c,0x4c,0x54,0x50,0x81,0xa0,0x0a,0xd3,0x7c,0x99,0x91,0xc7,0x3e,0x56,0x7d,0x53,0x8c,0x3c
+.byte 0x51,0x44,0xa5,0x22,0x9d,0xd2,0x9b,0x13,0xcf,0xb8,0x0c,0xb8,0xd4,0xaa,0xb4,0xaa,0x8d,0xab,0x7c,0x06,0xca,0xbb,0x85,0xac,0x01,0xee,0xef,0xe7,0x74,0xd5,0x0d,0x64,0x91,0x1c,0xde,0x6c,0x05,0x37,0x1e,0x23,0x05,0x7e,0x38,0xdc,0x17,0xaf,0xa7,0x95,0x85,0x1f,0xaf,0xc8,0xe1,0xc2,0xda,0xda,0xf1,0x14,0x56,0x66,0x68,0x70,0x36,0x38
+.byte 0x7b,0xb8,0x22,0x9f,0xc4,0xeb,0x5d,0x76,0x97,0xc5,0xa3,0xb9,0x06,0x86,0x4f,0x20,0xab,0x7d,0xce,0x7d,0x78,0x59,0xc5,0x1f,0x73,0x81,0xf6,0x6d,0xb4,0xcc,0x10,0xc5,0x4d,0xe3,0x81,0xaf,0xbc,0x37,0x42,0x28,0x5f,0x51,0x1e,0xaa,0xc7,0x81,0x20,0xc3,0x89,0x35,0xf1,0x74,0x3a,0xe8,0x04,0x24,0xef,0x8b,0x70,0xe1,0x74,0xdf,0x87,0xd5
+.byte 0x3c,0x32,0x32,0x7d,0x03,0xd7,0xda,0x6d,0x8b,0x25,0x8d,0x11,0xa3,0xc2,0x27,0xdc,0xa3,0xfc,0xdf,0x70,0xa4,0x41,0xad,0xda,0xce,0x12,0x45,0x14,0xa1,0x96,0x16,0xd8,0x54,0x89,0x9e,0x78,0x7f,0x23,0x12,0xd1,0x15,0x08,0x7f,0xbd,0xf0,0x9a,0xf1,0x5b,0x07,0xd5,0xbc,0xab,0xab,0x15,0xae,0xda,0xf1,0x26,0x12,0x4e,0xd6,0x6c,0x35,0xc1
+.byte 0x6e,0x27,0x4d,0xa8,0x71,0x51,0x1e,0xae,0xa8,0x35,0x26,0x06,0x18,0x03,0xd8,0xae,0x9e,0x8b,0x07,0x30,0x10,0xfb,0x47,0x05,0x02,0xcc,0x0a,0xbd,0x57,0x43,0x15,0x0a,0x7a,0xb5,0x30,0x0b,0xa6,0x3c,0xa8,0xc9,0xf5,0x68,0xe1,0xfb,0xd1,0xe0,0xe7,0x44,0x6c,0xb4,0x44,0xb6,0xd1,0x2b,0x30,0x5e,0x17,0x89,0x40,0xcc,0x10,0x8f,0x97,0x8a
+.byte 0xf3,0xf4,0x52,0x55,0xc4,0x8e,0x46,0xe5,0x24,0x0b,0x2a,0x5d,0x84,0xc1,0x4e,0xa8,0x5a,0x53,0xa8,0xce,0xc6,0x3f,0xa2,0xaa,0x3a,0x8f,0x51,0xed,0x4c,0xa6,0x34,0x6a,0x8c,0x18,0x9b,0x36,0x49,0x40,0x34,0xa3,0xe4,0xd8,0x3c,0x8a,0xfc,0x41,0xc9,0x35,0xfe,0x6e,0x3e,0x29,0xbc,0x04,0x61,0xaf,0x04,0x03,0x43,0x79,0xb5,0x77,0x27,0x25
+.byte 0xbe,0x85,0xc9,0x56,0xa4,0x17,0xc4,0x27,0x3d,0x53,0x1b,0x49,0x86,0xb2,0xb6,0x52,0x62,0x12,0x5d,0xe9,0x47,0x6f,0x65,0x78,0xf8,0x95,0x63,0xbc,0x73,0x6d,0xa6,0xb9,0xcd,0x17,0x39,0x56,0xb0,0xab,0x3a,0x15,0x5f,0x9a,0x98,0xfb,0xcd,0x51,0x4a,0x35,0x21,0xaf,0x07,0x4a,0x3d,0xfd,0x39,0x11,0x42,0xed,0xfc,0x7e,0x10,0x24,0xa5,0x0c
+.byte 0xb2,0x4f,0x27,0xe4,0x78,0x32,0xfe,0xfc,0x8e,0x46,0x68,0xbb,0x2e,0x85,0x87,0x0f,0x01,0xde,0x1c,0x02,0xdd,0x82,0xa0,0x9e,0x30,0x31,0x8d,0x86,0x36,0x33,0xa6,0x59,0x16,0x78,0xae,0x1f,0x1d,0x27,0x0b,0x29,0x42,0x16,0x93,0x3b,0xe6,0xfb,0x8d,0xd5,0x48,0x42,0x61,0x39,0x5b,0xf7,0xea,0xd0,0x6f,0x67,0xd9,0x03,0x72,0xed,0x54,0xe1
+.byte 0xab,0x3f,0xa0,0xdc,0x4b,0x19,0xe6,0xe3,0xfe,0x5f,0x65,0x64,0x4c,0xa9,0x5c,0x52,0x36,0xb3,0x65,0x28,0x3e,0xe5,0x07,0x50,0xed,0xec,0x2f,0xc9,0xff,0x47,0x27,0xf6,0xfe,0xb8,0x60,0x60,0x52,0xe5,0xec,0x3c,0x4f,0x69,0x9f,0xaa,0x06,0x8a,0x99,0x9f,0xac,0xfc,0x0a,0x6f,0x8a,0xa4,0x0e,0x5c,0x58,0xb4,0x09,0xba,0x93,0x95,0x94,0x12
+.byte 0x9b,0x23,0x4f,0x93,0x28,0x6d,0xd0,0x76,0xfd,0xc9,0x87,0x3b,0xf1,0x8c,0x7d,0x56,0x84,0x5a,0x04,0x08,0x30,0xf7,0xf6,0x52,0x15,0xba,0xd6,0x7a,0x39,0x8c,0x5a,0xbf,0xeb,0x02,0x6d,0x31,0x30,0x92,0xbc,0xe2,0x07,0x21,0x16,0x96,0x70,0x66,0x00,0xe0,0x04,0xc5,0xa8,0xe4,0x08,0x6d,0x08,0x69,0x35,0xe2,0xb1,0x83,0x03,0x37,0xca,0xff
+.byte 0x06,0x37,0x80,0xd5,0x1a,0xc5,0x31,0xfc,0x9a,0xb0,0x8a,0x4b,0x58,0xf3,0x00,0x4e,0xa4,0xfe,0x9e,0xe0,0x60,0xc7,0x3d,0x2c,0x52,0xb5,0x39,0xf0,0xa4,0x88,0x39,0x37,0xa5,0x26,0x8a,0xa3,0xe6,0x31,0xce,0xf3,0xa1,0x54,0x73,0xe7,0x69,0x38,0xef,0xa2,0xab,0x52,0x50,0x1a,0x45,0xcc,0x29,0x9c,0xb6,0xf4,0xde,0xc2,0xfe,0x7a,0x26,0xf7
+.byte 0x7a,0x6e,0x07,0xb6,0xd8,0x3f,0x77,0x60,0x35,0xae,0x6a,0x90,0xd6,0xb8,0x37,0xed,0x73,0x59,0x54,0xd9,0x0c,0x87,0x0e,0x81,0xef,0x69,0xc7,0xd4,0x8f,0x00,0x74,0x57,0x12,0xcf,0xa1,0x76,0xe8,0x45,0xf5,0x9a,0x4f,0xe2,0x5d,0x8a,0x89,0xb1,0x8b,0xea,0x9c,0x0a,0x1e,0x00,0x61,0x3b,0x66,0xbd,0xb5,0xd6,0xff,0xa3,0xff,0x52,0xc2,0x35
+.byte 0x81,0x05,0x08,0x2b,0xf9,0x52,0xda,0x74,0xd1,0x76,0x13,0xba,0x28,0x4c,0xb1,0xb1,0x82,0x5b,0x4e,0x79,0x39,0x22,0xf9,0x96,0x91,0x07,0x4f,0xf9,0xf2,0x25,0x25,0xb1,0x3e,0xda,0x07,0x5c,0x01,0x7b,0xfa,0x3e,0x95,0x92,0x1d,0xf8,0x44,0x06,0xc1,0xed,0x64,0x74,0x14,0x84,0x25,0xee,0x75,0xaf,0xe3,0x7c,0xd3,0xbe,0x7a,0x51,0x6b,0x80
+.byte 0x20,0x43,0x20,0x10,0x5f,0xf5,0xfc,0xd5,0xe8,0x06,0x43,0xad,0x10,0x6b,0x67,0x48,0xca,0xca,0x6e,0x3e,0x1c,0xdf,0x8f,0x7a,0x65,0xc8,0x5d,0xba,0x3b,0x67,0xeb,0x1f,0xc4,0x37,0xad,0xef,0x73,0x9e,0x18,0x8e,0xc1,0x99,0xaf,0x75,0xd3,0x91,0x73,0xc3,0x3a,0xb2,0xfe,0xff,0x30,0x81,0xc4,0x4f,0x37,0x37,0x23,0x96,0x17,0xf1,0xa2,0x9b
+.byte 0x55,0x6e,0xd6,0xb3,0xc4,0x98,0xa3,0x32,0xb6,0xff,0x86,0x87,0x77,0xf4,0xad,0x16,0x3e,0xf0,0x24,0x01,0xb4,0x8e,0x1e,0x0f,0x10,0xa4,0x2e,0xe4,0x79,0xe6,0x88,0xe7,0x09,0x58,0x5e,0x97,0xad,0x0d,0x72,0x05,0xbf,0x2f,0x3f,0x99,0xee,0x8a,0x84,0xc3,0x62,0x43,0x52,0x6d,0xab,0x66,0xcf,0x9f,0x4e,0xf2,0x0d,0x13,0x15,0x49,0x84,0x5e
+.byte 0x6c,0x8d,0x2d,0xef,0x53,0x16,0xa0,0x63,0xbe,0x05,0xb8,0x9b,0x23,0xca,0xca,0xb8,0xdd,0xbc,0x96,0x68,0x35,0x43,0x63,0x30,0x8e,0xaf,0x53,0x98,0xe2,0x76,0xe8,0x89,0x00,0x29,0x11,0x70,0xd5,0x94,0xbd,0x78,0xff,0xf6,0x88,0x4a,0x3d,0x99,0xd9,0x7e,0xdf,0xa8,0x33,0x92,0xa2,0xc0,0x32,0x42,0x73,0x08,0xd4,0x55,0x5d,0x18,0x93,0xca
+.byte 0x7e,0x33,0xe3,0x51,0xc7,0xb7,0x24,0x62,0x69,0xf4,0xab,0x36,0xe3,0x22,0x10,0x9b,0xe0,0xbd,0x48,0x65,0x30,0x9c,0xfe,0xeb,0x3f,0x7f,0x22,0x67,0xcc,0x87,0x5a,0x71,0xb0,0xd1,0x19,0x82,0x1c,0xb2,0xf1,0x73,0xd2,0xd6,0x3f,0xef,0xe3,0x2f,0x25,0xf3,0x8b,0x21,0x4e,0xbf,0x0e,0xc1,0xd2,0x8a,0xbb,0x04,0xde,0xcf,0xd1,0x77,0xba,0xaa
+.byte 0xc7,0x41,0x68,0xce,0xc4,0x64,0xf9,0x3a,0x2f,0x1c,0x0b,0x22,0xf8,0x60,0x09,0x76,0x31,0x88,0x62,0x3a,0xf3,0x49,0xe6,0xda,0x4b,0xd3,0xf3,0x35,0xaa,0x56,0x4c,0x2f,0x7f,0x03,0x3e,0xf8,0xcb,0x5e,0xed,0x37,0xa1,0x29,0xe8,0x20,0xf5,0x4a,0x32,0x73,0x30,0xfd,0xd1,0xf6,0xb4,0xa1,0x30,0x87,0xcb,0x21,0x63,0xf5,0x3a,0xad,0x05,0x1a
+.byte 0x34,0xf5,0x32,0xf6,0x02,0xf3,0x10,0x52,0xfd,0x86,0x37,0x1f,0x5d,0xe4,0x2e,0x31,0xcb,0xb8,0x4c,0xeb,0xdd,0xea,0x01,0x0d,0x94,0x13,0xa8,0x8f,0xf0,0x52,0x4e,0x0d,0x4f,0xd1,0x24,0xeb,0x0f,0x2b,0xb1,0xaa,0xc5,0xc8,0x52,0xb9,0xbe,0x21,0x48,0x2a,0x53,0x98,0xe4,0x00,0x72,0x64,0xdb,0x44,0x48,0x36,0x60,0xe7,0x81,0xdc,0x25,0x85
+.byte 0x4d,0xaf,0xa8,0x0d,0xfb,0x07,0x76,0x4f,0x6a,0x30,0x3c,0x7c,0x3b,0x36,0xa9,0xf8,0xae,0x81,0x03,0xe9,0x19,0xdf,0xdb,0xd9,0x7f,0x59,0xe0,0xd7,0x50,0x14,0x9f,0x67,0x3d,0xc7,0xdf,0xa8,0x44,0x86,0x29,0x81,0x65,0x44,0x9e,0x37,0x27,0xdd,0x2f,0x33,0x59,0xf7,0xaa,0x17,0x34,0x8c,0x1c,0xa7,0x8e,0x06,0x46,0xf1,0x43,0x87,0xa9,0xb7
+.byte 0x85,0xec,0x92,0x0d,0xdd,0x78,0x55,0x99,0xfb,0x1c,0x66,0x85,0x0d,0x59,0x31,0x00,0xbc,0xd9,0x9b,0xbb,0xfb,0xfc,0xb2,0x36,0x3c,0x34,0x8f,0x4a,0xb6,0x74,0x9c,0x32,0x6f,0x69,0x6c,0x3e,0x68,0x7e,0xec,0xeb,0x58,0x6a,0xf5,0xa2,0xbb,0x04,0x68,0xdb,0x8c,0xf0,0x04,0xba,0xf7,0xf7,0x50,0xd0,0x60,0xba,0x45,0x73,0x0f,0x2c,0x2f,0x97
+.byte 0x58,0xcc,0xa2,0xbe,0xfe,0x5e,0xf9,0x44,0x03,0x8b,0x99,0x56,0xb0,0x4f,0xe1,0xd0,0xa5,0x9f,0xd1,0xfc,0x95,0x44,0x4b,0x01,0x24,0xc0,0x4c,0x91,0xc1,0xb5,0x99,0xe7,0x5f,0x2f,0xcf,0x5d,0x4f,0x64,0x6e,0x54,0x51,0x0c,0x35,0x5f,0xa8,0x7b,0x27,0xa0,0x7d,0xb1,0x90,0xc2,0xdd,0x50,0xef,0x09,0x6f,0xed,0x25,0x6b,0xf5,0x6f,0xc1,0x97
+.byte 0xea,0xd5,0x49,0xf5,0x40,0x60,0xc3,0xbb,0x0d,0x82,0x15,0xa5,0xf7,0xfe,0xa1,0x20,0x13,0x9e,0xbb,0x43,0x58,0xba,0xd2,0xe8,0x89,0xaa,0xfc,0xe0,0x47,0x6b,0xac,0x91,0x8b,0xeb,0x4f,0xf5,0xda,0xf5,0xc8,0x11,0x64,0x7c,0x8d,0x43,0x92,0xf2,0x84,0xeb,0xfb,0x5c,0x1b,0x6b,0x68,0x8e,0x3c,0x66,0xb2,0xd1,0x8e,0x67,0x44,0xbf,0x69,0x3b
+.byte 0xb9,0x41,0x78,0x8d,0xc8,0x7b,0x81,0x61,0x70,0x6e,0xe2,0xfc,0xd2,0x96,0x31,0x31,0x2f,0x27,0x90,0xf2,0xc4,0xed,0xbd,0xb5,0x0e,0x91,0x7d,0xd0,0xec,0x3c,0xe9,0xcf,0xf2,0x07,0xac,0x54,0x44,0x9a,0x24,0x41,0xcb,0x2a,0x86,0x30,0x18,0xba,0x65,0x59,0x41,0x00,0x59,0xbf,0x3d,0x01,0x8a,0x51,0xe5,0xd2,0x90,0x8c,0x7d,0xd7,0xad,0x71
+.byte 0xdc,0x45,0x62,0x95,0xf9,0x9f,0xe8,0x55,0x6d,0x48,0x22,0x32,0xcb,0x9a,0x55,0x65,0xe5,0xdf,0xee,0x22,0x99,0x91,0xd7,0xed,0x33,0x04,0x72,0xc7,0xc5,0xb2,0x56,0x5e,0x8f,0x38,0x4b,0xd0,0x61,0x4b,0x4b,0x04,0x4c,0x4c,0x2b,0x23,0x00,0xd4,0x5c,0xdd,0x84,0x8d,0x73,0xf4,0xf7,0xef,0xd5,0xdb,0x2b,0xec,0x54,0x86,0x37,0x01,0x64,0x56
+.byte 0xef,0x73,0x9f,0xb4,0xb6,0xd2,0xf4,0x33,0x93,0xbd,0xd7,0xd9,0x6e,0x8f,0x60,0x85,0xbc,0xa6,0x16,0x3f,0x3f,0xc3,0xd7,0xfc,0xb6,0x82,0xf0,0xe5,0x1e,0x2c,0x51,0x48,0x27,0x50,0x3e,0xdb,0xe6,0x86,0x3b,0xa1,0xfa,0x09,0x39,0x04,0x6f,0xb1,0x85,0xbd,0xda,0x4d,0x2f,0xd1,0x40,0x6f,0x2e,0x2b,0xf2,0x9a,0x4d,0x8e,0xb2,0xc5,0x6e,0x21
+.byte 0xf9,0xdd,0xc9,0x2e,0x81,0x18,0x7b,0x88,0xb9,0x86,0x36,0xe5,0xb2,0xdd,0x19,0xb4,0x7f,0x5d,0xc0,0x20,0x34,0xdc,0x63,0x7d,0x8c,0x80,0x0f,0xe6,0x85,0x14,0xbb,0x87,0x6c,0x3e,0x39,0x53,0x60,0x3d,0xc5,0x46,0x11,0xa3,0x96,0x60,0x6f,0xe9,0xfe,0x59,0xcc,0xed,0x4d,0xdb,0xa3,0xa1,0xf1,0x71,0x0b,0xb0,0x1f,0x89,0x4c,0x32,0x59,0xa5
+.byte 0x7d,0xf7,0x3e,0x5b,0xca,0xa4,0xe1,0xc3,0x50,0xac,0xdf,0x00,0xad,0x45,0x59,0x9e,0x23,0x5f,0x52,0xbd,0x36,0x78,0x55,0xcf,0x90,0x91,0x41,0x14,0xdb,0x76,0x3a,0x43,0x39,0x89,0xe1,0x93,0xc8,0x66,0x91,0xc7,0x42,0x06,0x6f,0xbb,0x35,0x1e,0x07,0x52,0x5a,0xe4,0x41,0x9f,0x65,0xe0,0xdc,0x49,0x8c,0xd3,0x5f,0x16,0x21,0xc9,0xb8,0x8a
+.byte 0xc2,0x56,0x91,0xcb,0x18,0x6b,0x38,0x7b,0x3a,0xeb,0x91,0x3c,0x0d,0x6a,0x1f,0xd6,0xc6,0xd7,0x56,0x8d,0xd3,0x76,0x1c,0x9d,0xed,0x3d,0xb6,0x92,0x71,0x6e,0x73,0xc6,0xb8,0xa2,0x1c,0x25,0xb9,0x3c,0xd4,0x41,0xf7,0x8f,0x39,0x60,0xe6,0x27,0xf2,0xc6,0x5f,0x56,0x08,0x7c,0xd3,0x16,0x9d,0x06,0xc0,0xca,0x3d,0xc6,0x61,0xb0,0x21,0x51
+.byte 0x6d,0xca,0x82,0x59,0xe6,0xbb,0x99,0xa2,0x4f,0xfc,0x71,0x66,0x2b,0x4e,0x40,0x62,0x97,0x34,0x73,0x4a,0xe5,0xf0,0x4f,0x4c,0x36,0x4c,0xdb,0x03,0xa9,0x87,0x29,0x21,0x5d,0x91,0x5b,0x89,0xb8,0x3d,0x65,0xc7,0x58,0x0a,0x81,0xb5,0x3e,0x22,0xa1,0x57,0x95,0xbe,0x60,0xf5,0xeb,0xb3,0x49,0xdf,0xd9,0xa2,0x31,0x36,0x5f,0xb2,0xa6,0xf6
+.byte 0x66,0x88,0x88,0x8e,0xa3,0x2c,0xac,0x5e,0xa1,0x33,0x16,0x64,0x08,0x47,0xc8,0xbc,0xc2,0xe9,0xdb,0x73,0x57,0x50,0xd4,0x24,0x01,0x26,0x26,0x04,0x4f,0x8a,0xc0,0x7a,0x97,0x14,0xf2,0xd0,0xbe,0x03,0xea,0x8a,0x25,0xcb,0x98,0xe7,0xbd,0x67,0xff,0x32,0xfd,0x8a,0x7d,0x11,0xe1,0xb2,0x91,0xb5,0xa0,0xb6,0x3c,0x2c,0xb3,0x6e,0x35,0x61
+.byte 0x86,0xbc,0x37,0x15,0xf8,0x3b,0x0d,0x84,0x83,0x69,0x76,0xb0,0xaa,0x8f,0x4f,0xca,0xba,0x54,0xfe,0x42,0xc8,0xba,0x9a,0xd5,0x53,0x69,0x67,0x29,0x23,0x3a,0x6a,0x75,0x97,0xb4,0x29,0x2e,0x62,0xe3,0x95,0x82,0xb3,0xa0,0xa1,0xb7,0xdf,0xc2,0x66,0x4d,0xdd,0x0d,0xda,0xda,0xc2,0x42,0xe0,0x69,0xb1,0xab,0x3c,0x44,0x39,0x11,0x3b,0x0a
+.byte 0xd6,0x96,0x2c,0x36,0xb0,0xa0,0xed,0x3d,0x0c,0x63,0x8b,0x90,0xe4,0xb9,0x5f,0x4c,0x27,0x70,0x87,0xb3,0x54,0xe2,0x36,0x74,0x6f,0x3e,0x22,0xb1,0x3b,0x1b,0xba,0xdb,0x1c,0xbd,0x9c,0x6d,0x84,0xbd,0x33,0xfb,0xc0,0x98,0x4c,0xcf,0x7a,0xe8,0x41,0xdb,0x32,0x1f,0xb7,0x64,0x19,0xdb,0x87,0xe7,0xf9,0x52,0x40,0x8c,0xc6,0x89,0x98,0x15
+.byte 0x69,0xde,0xfa,0x29,0x9a,0x0f,0xaf,0xb0,0xad,0x71,0x35,0xab,0xab,0x34,0xe0,0xf4,0x03,0x24,0x6f,0x94,0x38,0x87,0xba,0x68,0xd5,0x1f,0x58,0x88,0x3e,0x12,0x20,0x57,0x43,0xde,0xd0,0xbc,0xaa,0x31,0x8f,0xbc,0x88,0xa0,0xdf,0x5a,0xcc,0xd1,0xba,0x9c,0x18,0x80,0x4e,0x8f,0x68,0x91,0x9c,0x57,0x3b,0x5a,0x62,0xc7,0x29,0x3e,0x49,0xc7
+.byte 0x23,0x26,0xfd,0x9e,0xd0,0xb0,0x4f,0xd4,0xb2,0xa9,0xa8,0x4c,0x66,0x54,0x52,0x75,0x6b,0xbf,0x63,0x76,0x49,0x3b,0xa3,0xb2,0x8f,0x87,0x9d,0xb4,0x8f,0x07,0x3c,0x8e,0xae,0xe1,0x0e,0x9a,0x86,0x90,0x58,0x73,0x8a,0xb3,0xa9,0xab,0xe6,0x27,0xd7,0x70,0x94,0x77,0x12,0xdc,0x71,0xdf,0xcf,0xba,0xdd,0x85,0xfe,0x28,0xaa,0xcd,0xcc,0xe8
+.byte 0x5f,0xd4,0xd8,0x45,0x6f,0x20,0xa8,0x5e,0x40,0x91,0x3b,0xd7,0x59,0x92,0xb8,0x7d,0x2b,0x8b,0x38,0xbd,0xfe,0x7b,0xae,0x5c,0xee,0x47,0x9b,0x20,0xb7,0xf3,0xad,0x75,0xa9,0xe1,0x96,0xc8,0xb2,0x30,0xfe,0x0c,0x36,0xa2,0x02,0xf4,0x3b,0x30,0xfd,0x91,0xfa,0x5f,0xd6,0x18,0x1a,0xcb,0xd2,0x26,0xbb,0x67,0xbe,0x1c,0x99,0xa5,0x4f,0x57
+.byte 0x40,0xb5,0xed,0xd6,0x84,0xfd,0x6b,0x00,0xc8,0xe7,0x18,0x1a,0x9f,0xf7,0x3b,0xd1,0xcc,0x12,0xeb,0x9d,0x61,0xf0,0x8d,0x64,0x08,0x93,0x61,0xc4,0x3e,0xdb,0xda,0x15,0xb1,0xd6,0x2c,0x84,0x2a,0xd8,0xd2,0xa1,0x66,0x4e,0xc9,0xd6,0xbf,0x7e,0xb6,0x22,0xfa,0x35,0x5e,0xdc,0xc0,0x31,0x02,0xb8,0x17,0x46,0x9e,0x67,0xd3,0x6a,0x8f,0x33
+.byte 0x85,0xc3,0xfe,0x36,0xbc,0x6f,0x18,0x8a,0xef,0x47,0xf1,0xf2,0x6e,0x15,0x6c,0xb1,0x4a,0x4b,0x13,0x84,0xd5,0x1b,0xf9,0xa2,0x69,0xcd,0xc7,0x49,0xce,0x36,0x8e,0xe5,0xd5,0x35,0x05,0x7c,0x7f,0xc6,0x15,0x29,0x2e,0x64,0xa6,0x91,0x9d,0xe5,0x9d,0x90,0xe7,0x26,0xec,0x75,0x19,0x58,0x57,0xf2,0x19,0x7b,0x24,0x7d,0x19,0xd3,0x72,0x69
+.byte 0xaa,0xa2,0x8c,0xe3,0x3d,0x38,0xb9,0xf0,0x5b,0xe9,0x3b,0xaa,0x96,0xef,0x2c,0xfc,0xf5,0x13,0xa6,0xa9,0x57,0x8c,0xa9,0x3a,0xc1,0xf0,0x2d,0x57,0x06,0x08,0xe3,0x9c,0xfe,0x82,0x8a,0x6a,0x79,0x5b,0xef,0x2b,0x81,0x83,0x01,0x53,0xac,0xdc,0x79,0x93,0x9b,0x23,0xd4,0xae,0x17,0x6f,0x62,0xaa,0x33,0x41,0xa6,0x31,0x1c,0x7b,0x46,0x2b
+.byte 0x17,0xd3,0x6f,0x66,0x73,0x54,0xee,0xa1,0x08,0xee,0x8f,0x0f,0x0e,0x53,0xa7,0x49,0x17,0xdb,0x35,0xaf,0x4e,0x94,0x87,0x8e,0xff,0xf4,0x2b,0x29,0x01,0x45,0xa3,0x0a,0xd9,0x13,0x38,0x09,0x46,0x2c,0x56,0x97,0xd7,0xee,0x24,0x43,0xd1,0x20,0xed,0x38,0xde,0x52,0x13,0x38,0x06,0xd3,0x97,0xc7,0x48,0x8b,0x72,0x0a,0xc5,0xca,0x75,0x2c
+.byte 0x04,0x9e,0xee,0x14,0xe7,0xda,0x59,0xc2,0x54,0x7a,0x72,0x55,0x35,0x00,0x93,0xb7,0xb9,0x81,0x01,0x46,0xae,0x43,0x81,0x34,0xd7,0xb4,0x7a,0xfc,0xfc,0x98,0x2b,0x29,0xe5,0x5e,0x9d,0x8e,0xef,0xd4,0x44,0x9d,0x9a,0xbe,0xdb,0x83,0x33,0x18,0x9e,0xbd,0x0f,0x34,0x4d,0xd9,0x34,0xe0,0x2c,0x1f,0x10,0xaa,0x06,0x5e,0x54,0x51,0x72,0xec
+.byte 0xbf,0x6b,0x3e,0xb9,0xdd,0x37,0xc3,0xe1,0xbe,0xbe,0x1d,0x86,0xde,0x12,0xca,0x82,0xc5,0xe5,0x47,0xf8,0xbe,0xef,0xb6,0x79,0xd5,0x3c,0x69,0x0a,0x35,0x3e,0xd3,0xf8,0xaf,0x5b,0x8e,0x69,0xff,0xb2,0xf7,0x91,0xc2,0x70,0x22,0x97,0x1c,0x5c,0x56,0x25,0x5a,0xcf,0x31,0x7a,0x37,0xce,0xc7,0xf2,0x98,0xdc,0xb5,0x58,0x71,0x5a,0x60,0xe2
+.byte 0xfe,0x4f,0xf3,0xe2,0x2a,0xca,0x22,0x3e,0x07,0xc2,0xea,0x23,0xc8,0x04,0x97,0x7f,0xca,0xf6,0xf8,0x12,0x06,0x88,0x81,0xee,0xb7,0xdd,0x56,0x9e,0x0f,0x36,0xd3,0x09,0xa8,0x74,0x4d,0x8b,0x8f,0x31,0x64,0xbe,0x9d,0x7b,0x68,0x50,0xc8,0x64,0x40,0x3b,0x0c,0x04,0xb9,0x4b,0x9e,0xff,0x7e,0x5d,0xd8,0x57,0xa0,0xe5,0x6d,0xc2,0x37,0xe7
+.byte 0xd1,0xd9,0x96,0xaa,0x16,0x3e,0xa2,0x9d,0x32,0xe7,0x1e,0x11,0x6e,0x41,0xe2,0xa0,0xe1,0x6f,0x32,0x6d,0xd5,0x38,0x0c,0x27,0x27,0xa9,0xc2,0x04,0xc6,0xe7,0x8d,0x7d,0x7b,0x30,0xbe,0x54,0x6b,0x82,0x37,0x39,0x53,0x54,0xc9,0xac,0xcb,0xd1,0x31,0x79,0xd4,0x7b,0x85,0x07,0xf4,0xf4,0x5d,0x33,0xc7,0x91,0x4e,0xe5,0x13,0x78,0x09,0x42
+.byte 0x29,0x48,0xaf,0x82,0xb1,0x88,0xd4,0xd3,0x57,0x50,0x38,0xa7,0x66,0x41,0x63,0x34,0x2a,0x3c,0x5e,0x8f,0xc4,0xc1,0x00,0xa1,0x22,0xbe,0x5e,0x64,0xb0,0x60,0x9b,0x42,0x9d,0xc6,0x59,0x5c,0xcc,0x29,0x6f,0x64,0x5b,0x5c,0x0f,0xb2,0xae,0x21,0x0c,0x9a,0x6a,0x19,0xb9,0xa6,0x32,0xf8,0xdc,0x82,0xea,0xba,0x27,0xcf,0x42,0xd3,0xde,0x78
+.byte 0xfe,0x9c,0xa5,0x36,0xb6,0x24,0xb6,0x0d,0x5b,0x67,0x6c,0xf5,0x16,0xbf,0x67,0x54,0x4f,0xe4,0x83,0x29,0x75,0x42,0x9a,0xbb,0xd5,0xe7,0x01,0x1f,0xbd,0x80,0x1a,0x7a,0xb6,0xe1,0x2b,0x5d,0x71,0x93,0x00,0xad,0xf6,0x11,0x8d,0x67,0xdc,0x9c,0x8f,0xf0,0x09,0x3f,0xf9,0xa4,0xd6,0xe0,0xdd,0x95,0xea,0xfb,0x71,0x76,0x21,0x31,0x6d,0x48
+.byte 0x0a,0x27,0xa8,0xa6,0x3a,0x7f,0x42,0x6b,0x7e,0xd7,0x6e,0xd5,0x42,0x97,0xad,0x55,0xae,0x26,0x3c,0xde,0x3f,0xaf,0xfd,0x1d,0x6d,0xd3,0xeb,0x84,0xad,0x6d,0xd1,0x4a,0x85,0x1a,0xf7,0x99,0xa4,0xd0,0x48,0xfb,0xf6,0xfe,0xc6,0xea,0x61,0x77,0xe2,0x56,0x87,0xc1,0x36,0x44,0xb4,0xe3,0xd7,0xd9,0x6d,0x3e,0x1b,0xf4,0x72,0x3e,0xfe,0xa5
+.byte 0x47,0xf8,0x3f,0x1a,0x6e,0x43,0xf5,0x67,0xfe,0x90,0x96,0x9b,0x52,0xde,0xab,0xfb,0x45,0x7d,0x93,0xea,0xc3,0x40,0xe1,0x5f,0xcd,0xad,0x3b,0xe9,0x4e,0x36,0xc5,0x38,0xf4,0x66,0xde,0x4b,0xc8,0x2a,0xc3,0xa2,0x3a,0x2a,0xf1,0xd1,0xe8,0x01,0x07,0x37,0xca,0x42,0xbf,0x4f,0xd8,0xc5,0x50,0x93,0x1a,0x01,0x1d,0x51,0x41,0x6e,0xbf,0x68
+.byte 0x93,0x2e,0xdc,0x41,0x23,0xf3,0x13,0xe7,0x09,0xfa,0x39,0x6d,0xee,0x41,0x49,0xbb,0x78,0x04,0xcf,0xc9,0xbb,0x11,0xaa,0x57,0xb5,0x3e,0x4c,0x3a,0x77,0xb7,0x0b,0x38,0x34,0x48,0xd0,0x99,0x20,0x55,0xcd,0x43,0x2f,0x68,0x66,0xb0,0xe6,0x75,0x41,0xe4,0xae,0xfd,0x96,0xe8,0x01,0x4c,0x0b,0x5c,0xbc,0x4f,0x45,0x70,0x08,0x9e,0xf7,0x68
+.byte 0x9e,0xbb,0xe5,0x39,0x20,0x3f,0xbe,0xd3,0xe3,0x95,0xba,0x98,0xd5,0x12,0x2e,0x87,0xd4,0xf4,0x12,0xa2,0xcb,0xd4,0x51,0x53,0x93,0x67,0x06,0xf1,0x21,0x0e,0x92,0x8f,0x9f,0x9e,0x6c,0x16,0xa4,0x2c,0x6d,0xb0,0xd0,0xe1,0x87,0x2f,0x09,0x2c,0x8f,0x4b,0x89,0x1f,0xab,0x66,0xf1,0xcd,0x6e,0x67,0xaf,0x07,0x99,0x18,0x1b,0xda,0xc8,0x65
+.byte 0x81,0xa3,0x37,0x8a,0xad,0xe4,0x1d,0xfd,0x82,0xa0,0xf1,0xe1,0x1e,0x8d,0x0b,0xf7,0x07,0x7c,0xb3,0x10,0xc8,0x5a,0xa9,0xcc,0xc8,0xd0,0x2e,0x5a,0x71,0x45,0x4c,0x30,0xf0,0x10,0xe0,0xf6,0x0d,0x0d,0x11,0xb4,0x83,0x40,0x75,0xee,0xb9,0x24,0x04,0xe3,0xba,0xb3,0xd3,0x00,0x57,0x71,0x98,0xf0,0x4b,0x35,0x8d,0xd8,0x71,0xa0,0xcc,0xaf
+.byte 0x46,0x54,0x67,0x65,0x70,0x0b,0x9c,0x61,0xf8,0xd4,0xb2,0x35,0xfd,0xcf,0x2b,0x3a,0x48,0x5b,0x03,0x86,0xd8,0x13,0x48,0x8a,0x55,0xa5,0x4d,0xef,0x42,0x41,0xbb,0x6a,0x8c,0x92,0x46,0x87,0x82,0x09,0x43,0xf3,0x94,0x1d,0x23,0x36,0xfe,0x6f,0xb8,0x9f,0xfa,0xf9,0x92,0x27,0x3c,0xcc,0x47,0x89,0x5c,0x7f,0x81,0x42,0x74,0x12,0x14,0xff
+.byte 0x98,0x63,0xc0,0xfb,0x70,0xff,0xc7,0x65,0x5a,0xc3,0xb9,0x74,0x1b,0x71,0x3c,0x2c,0x47,0x79,0x07,0xb9,0x3c,0xc2,0x5f,0x48,0x4f,0xbd,0xaf,0x03,0x05,0x57,0xa9,0x84,0x33,0xc8,0x0d,0xd5,0xac,0x42,0xdb,0x4b,0x57,0x46,0x41,0xf0,0xe4,0x08,0x0d,0xf3,0x43,0x41,0xa5,0x14,0xb7,0xcd,0x64,0x23,0xc9,0xfe,0xff,0x12,0x97,0xc6,0x2f,0x8d
+.byte 0x9e,0xf2,0x1d,0x33,0x26,0x3c,0x57,0x17,0xe1,0x7b,0x92,0x3f,0xb6,0xf4,0xd9,0xf8,0xe0,0x37,0xe6,0x18,0x7d,0xa7,0x8a,0x1e,0xe8,0xd8,0x56,0xa6,0x63,0xdf,0xa3,0x99,0x16,0x74,0x48,0x01,0xaf,0x95,0x55,0x40,0xce,0xa8,0x0d,0x30,0x01,0x09,0x40,0xc9,0x9d,0x3d,0xdf,0x4e,0x00,0xe0,0x2a,0xe6,0xdb,0xa2,0x79,0x42,0x57,0xd0,0x3d,0x81
+.byte 0x7f,0x67,0x3a,0xa9,0x63,0xb3,0xd4,0x60,0xa7,0xab,0x54,0x46,0xb0,0xbe,0xb0,0x83,0x72,0xec,0x47,0x0f,0xc7,0xd1,0xed,0x16,0x96,0xbc,0xa5,0x62,0x38,0xdb,0x88,0x2b,0x25,0x26,0x27,0x56,0x7f,0x46,0x39,0xe8,0x4e,0xc0,0x6c,0x62,0xf8,0x80,0x68,0x56,0x8a,0x93,0x51,0x95,0x77,0xe3,0x11,0x7b,0xaf,0xc4,0xcf,0x34,0x5a,0xd5,0x26,0xfc
+.byte 0xa2,0x18,0xb0,0xc0,0xa5,0x8b,0x25,0x70,0x40,0x70,0x29,0xc3,0xda,0x80,0x3d,0xe2,0x59,0x49,0x7f,0xdd,0x62,0x6e,0x5a,0xe6,0x27,0x73,0xce,0xb6,0x32,0x37,0x5f,0x73,0x12,0x2b,0x34,0x84,0xff,0x85,0xe3,0xb5,0x93,0x41,0x47,0xc5,0xf5,0x0e,0x21,0xfb,0x24,0x0f,0xdf,0x7b,0xb4,0x29,0x7f,0x67,0x2a,0x38,0x79,0xf0,0x54,0x8a,0x94,0x68
+.byte 0xe2,0x0b,0xb0,0xd4,0xb2,0xa4,0xe4,0xfb,0x3b,0xe6,0xe7,0x59,0x41,0xbd,0xed,0x62,0xce,0x50,0x1a,0x47,0x92,0x92,0x8d,0x80,0xa6,0x05,0x7a,0xb0,0xce,0x48,0x9c,0xb0,0x64,0xea,0xe0,0xa5,0x77,0xff,0xc1,0x82,0x99,0x7b,0xfb,0x74,0x53,0xfa,0x41,0x9a,0x2c,0xb4,0xbb,0xd2,0x26,0xa1,0x80,0x68,0x17,0xaa,0x8f,0x14,0x52,0xb6,0x5d,0xe0
+.byte 0x69,0x5b,0x31,0xc5,0xf5,0x32,0x0d,0xff,0xa4,0x7b,0x28,0x38,0x9b,0x61,0xfc,0xd0,0x92,0xb8,0x6e,0x23,0x8a,0xf3,0xc7,0x85,0x11,0xb8,0xd0,0x19,0xaf,0xca,0xa7,0xb4,0xcc,0xeb,0x5d,0xf6,0xa1,0x1c,0x56,0xdf,0x78,0x7a,0xe3,0x6a,0xa4,0x07,0x71,0xce,0xf1,0xb2,0xd5,0x38,0x3c,0xfa,0xf7,0x7a,0xbf,0x4b,0x43,0xa6,0xb3,0x4d,0xff,0x82
+.byte 0x96,0x46,0xb5,0xec,0xda,0xb4,0x5e,0x35,0x78,0xeb,0x4a,0x7e,0xc5,0x7b,0x05,0xd4,0xdd,0xf7,0xb7,0xf3,0xf0,0x04,0x26,0x7e,0x5e,0xc1,0x23,0xca,0x7f,0x14,0x27,0xac,0xda,0xe7,0xdb,0x31,0x05,0x9d,0xd4,0xda,0x20,0xc7,0x6d,0x9a,0x47,0x14,0x38,0xbd,0x7c,0xfe,0xbe,0x8d,0x42,0x7c,0xba,0x36,0xe2,0x2c,0x26,0xd2,0x46,0xa5,0x6b,0xbd
+.byte 0x6a,0x75,0x6b,0x52,0x8c,0x10,0xc6,0x0e,0x76,0x60,0x46,0xcc,0x93,0x54,0xc4,0x6e,0xc7,0x70,0x5b,0xb4,0x81,0x51,0x56,0x03,0x22,0x33,0x21,0xe4,0x36,0xee,0x01,0xc3,0x0d,0x17,0x23,0x15,0xae,0x79,0xbc,0xe6,0x13,0x0f,0xfc,0x77,0xa2,0x06,0xed,0x76,0x4a,0xf7,0x2d,0x99,0xc8,0x5c,0xfd,0xac,0xd0,0x11,0xe8,0xfa,0x55,0x17,0x56,0x63
+.byte 0x3e,0xd5,0x23,0x71,0xf8,0xe9,0x1f,0x62,0x95,0xae,0x7c,0x2d,0xcd,0xb8,0x6e,0xb0,0xfe,0xf3,0xd0,0xba,0x72,0x8e,0xe3,0x95,0x82,0x00,0x85,0xdb,0x25,0xe4,0xf2,0xaa,0xbc,0x8d,0xb9,0x4d,0x69,0xa4,0xcd,0x39,0x52,0x9e,0x10,0xae,0x90,0xf0,0x74,0x2f,0xc6,0x5e,0x01,0x99,0x03,0xd5,0x88,0x59,0xfd,0x1b,0x80,0x56,0x0a,0x04,0x27,0xd9
+.byte 0x04,0x51,0xb0,0xb7,0x7a,0x65,0x79,0xa8,0xe2,0x6d,0x7f,0xb2,0xba,0x37,0x40,0xa0,0xbb,0xaf,0x15,0x46,0x23,0x5f,0x22,0xd0,0x2c,0x6c,0x7a,0x58,0x76,0x6f,0xb8,0x19,0xfe,0xb5,0x3d,0xf0,0x77,0x00,0x6b,0x4c,0x83,0x36,0x90,0xe6,0x57,0x29,0x6e,0x27,0x76,0xd4,0x7d,0x9a,0x6a,0xf1,0xf6,0x1b,0x1a,0x45,0xf5,0xf6,0x2d,0xb8,0x30,0x33
+.byte 0x65,0x51,0x37,0x26,0xbc,0xf7,0xb7,0xf9,0x56,0x05,0x6b,0xd4,0xd6,0x00,0x1d,0x13,0x15,0x45,0x24,0x0d,0x28,0x69,0xc6,0x50,0xe1,0x48,0x48,0x34,0x69,0x31,0x3c,0x58,0x71,0xd6,0x4a,0xd9,0xda,0x0d,0x28,0xbd,0xe9,0x5d,0x5d,0x8a,0x6e,0x71,0xc0,0x8b,0x7a,0xba,0x17,0x8e,0x82,0xcb,0xe9,0x95,0xc4,0x43,0x37,0xd0,0x58,0xed,0xec,0x77
+.byte 0x1e,0x22,0xf0,0xf0,0x7c,0x9d,0xeb,0x64,0x30,0x7b,0xb2,0x7b,0x86,0xdb,0xef,0x92,0x79,0xd9,0x9c,0x1c,0x1a,0xf6,0x98,0x26,0x18,0xa2,0x83,0x45,0x08,0xd4,0x1d,0x84,0xd4,0x28,0x6d,0x1f,0xb5,0x1f,0xab,0x97,0xc9,0x0d,0x1f,0x83,0x34,0x18,0xa3,0x20,0x63,0x60,0x6c,0xf3,0xd8,0xb2,0x0a,0xd9,0x35,0xa6,0xce,0x44,0x50,0xc6,0xf3,0x91
+.byte 0xe3,0x95,0x89,0x49,0x99,0x32,0x1d,0xf2,0x54,0x39,0x09,0xca,0xd1,0xc4,0x7f,0xa1,0x1d,0xce,0x94,0x67,0xf1,0x88,0x04,0x29,0xcb,0x5d,0xf7,0xfa,0xcd,0x69,0x16,0x17,0x05,0xc3,0x93,0x45,0xbf,0xd3,0x74,0x63,0xdc,0xe2,0x84,0xab,0x27,0x60,0x56,0x61,0x72,0x5d,0xdf,0xb4,0xa4,0x0f,0xb0,0x21,0x82,0x9b,0x73,0x0a,0x11,0x22,0x2d,0x65
+.byte 0xa2,0xff,0x29,0x8a,0x19,0x28,0x4f,0x4f,0xdd,0x64,0x0a,0x48,0x35,0x70,0x30,0x9f,0x41,0x4d,0x0c,0x7b,0xa6,0xcb,0x63,0x83,0xd1,0x79,0xfa,0x5f,0xc9,0x9b,0x6e,0x09,0x12,0x87,0xcd,0x1e,0x39,0xd6,0x40,0x08,0x0f,0xfd,0x79,0xc8,0xcb,0x77,0x8f,0x7a,0x52,0x42,0xc0,0xb2,0xc8,0xa0,0x2a,0xff,0xbc,0x60,0x13,0xbc,0x41,0x4a,0xc6,0x8b
+.byte 0x08,0xb0,0x9f,0x75,0x87,0xa1,0x75,0x42,0x4b,0x3a,0xf7,0xf7,0x84,0x39,0xa5,0x88,0x25,0x2d,0x4f,0x73,0x4e,0x30,0x27,0x92,0xea,0x93,0x70,0x5c,0xb5,0xeb,0xb0,0x10,0xda,0x0f,0xaa,0xb3,0x3f,0xb5,0x55,0x64,0x65,0xae,0xb5,0xf8,0x0a,0xe4,0x9f,0x86,0x02,0x6f,0x63,0x8a,0x0b,0x6b,0x82,0x85,0x3c,0x6a,0xdf,0x68,0x4c,0x1e,0xe9,0x5c
+.byte 0xd0,0x99,0xe5,0x0c,0xfc,0x63,0xfb,0xce,0x2d,0x63,0xd5,0x7d,0x8a,0x7d,0x14,0x22,0xbd,0x71,0x5e,0x79,0x3f,0x44,0x95,0xe5,0x6c,0x58,0x94,0x84,0x41,0x65,0x52,0x94,0x50,0xec,0xd3,0x2a,0x16,0x88,0xdb,0x71,0xb9,0xe4,0xb6,0xbf,0xc5,0x3c,0x48,0x37,0x62,0x32,0x79,0xbe,0x1d,0xdb,0xc9,0x79,0x37,0x40,0x65,0x20,0x62,0x45,0xb4,0xda
+.byte 0x24,0xef,0x33,0xf1,0x05,0x49,0xef,0x36,0x17,0x17,0x0f,0xdc,0x65,0xb4,0xdc,0x57,0xc3,0xc6,0x82,0x57,0x08,0xf2,0x20,0x57,0x5c,0x25,0x0e,0x46,0x75,0xa7,0x4f,0x9e,0xa4,0x00,0xf7,0x79,0xb9,0x0a,0xef,0x4f,0x50,0x79,0xf8,0x59,0x01,0xf2,0x74,0x9f,0x16,0x27,0xa5,0xc1,0x32,0xcc,0x58,0xa7,0x40,0xa1,0xa1,0x26,0x80,0x00,0xb5,0x64
+.byte 0x0a,0xd8,0x53,0x1f,0x72,0xf7,0x60,0xf7,0x0a,0xaa,0xdf,0x31,0x95,0xff,0xfc,0xb4,0xca,0xbc,0xf8,0x2a,0x33,0x20,0x04,0x16,0x1a,0xe7,0xeb,0x22,0xd1,0x25,0xa6,0x03,0xc9,0x9e,0x9e,0xca,0x7a,0x46,0x7c,0xcb,0x8a,0x63,0x4a,0xf0,0x1b,0xd0,0x34,0xc3,0xbb,0x89,0xcf,0x16,0x38,0xcb,0xe0,0xce,0xd5,0x0b,0xfd,0x4e,0xbc,0xce,0xba,0x28
+.byte 0x68,0x00,0x2a,0x31,0x52,0xe6,0xaf,0x81,0x3c,0x12,0x09,0x2f,0x11,0x0d,0x96,0xc7,0x07,0x42,0xd6,0xa4,0x2e,0xc1,0xa5,0x82,0xa5,0xbe,0xb3,0x67,0x7a,0x38,0xf0,0x5e,0xd8,0xff,0x09,0xf6,0xab,0x6b,0x5d,0xec,0x2b,0x9f,0xf4,0xe6,0xcc,0x9b,0x71,0x72,0xd1,0xcf,0x29,0x10,0xe6,0xe3,0x27,0x1c,0x41,0xc8,0x21,0xdf,0x55,0x27,0xa6,0x73
+.byte 0xb7,0x45,0xa1,0x09,0x66,0x2f,0x08,0x26,0xf1,0x50,0xe0,0xec,0x9d,0xf2,0x08,0xf3,0x49,0x56,0x50,0xe0,0xba,0x73,0x3a,0x93,0xf5,0xab,0x64,0xb6,0x50,0xf4,0xfa,0xce,0x8d,0x79,0x0b,0xad,0x73,0xf2,0x8c,0x1e,0xe4,0xdd,0x24,0x38,0x1a,0xde,0x77,0x99,0xb8,0x92,0xca,0xc0,0xc0,0xbc,0x3d,0x01,0x6f,0x93,0x3a,0x6e,0xc5,0x28,0x6e,0x24
+.byte 0x9c,0xf9,0xd9,0xcb,0x4b,0xbe,0x9e,0xda,0x0d,0x10,0xfb,0x9d,0x15,0xfe,0x28,0xdc,0xd9,0x09,0x72,0xd3,0x9f,0x6d,0x77,0x14,0x84,0x86,0x56,0x10,0xdc,0x8e,0x6a,0xa7,0x62,0xf0,0x0b,0x65,0x2c,0xa2,0xd1,0x7f,0xae,0x32,0xfa,0x9b,0x46,0x0f,0x12,0x08,0x22,0x8c,0x87,0x15,0x4b,0xc4,0x6d,0x85,0xfb,0x69,0xfe,0xce,0xfb,0xb4,0x3e,0x7b
+.byte 0xcf,0x88,0xa7,0x97,0x52,0x56,0xd0,0x9f,0xb4,0x33,0xf9,0x08,0xd2,0x28,0x46,0x5e,0xc4,0xec,0x22,0xc6,0x1e,0x7b,0x34,0x99,0x0c,0x5b,0x04,0x19,0xe2,0xca,0x09,0x11,0x50,0x45,0xcc,0xb2,0x90,0x25,0x51,0x68,0xc9,0x20,0x6c,0x99,0x2e,0xdb,0x5b,0x07,0x91,0xb2,0x69,0xbf,0x3c,0x05,0x50,0xfb,0x21,0x33,0x4f,0x6e,0x18,0x19,0xd5,0xff
+.byte 0xce,0x9d,0xb5,0x7f,0xd4,0xd5,0x8f,0x41,0x26,0x1f,0xa1,0x4c,0x34,0xd3,0x98,0x08,0x5d,0xb5,0x56,0xa7,0x04,0x63,0x76,0x7d,0xae,0xee,0xea,0xbf,0x69,0x8d,0xff,0xa1,0x62,0x86,0x19,0x7b,0xe5,0x08,0x7a,0xe5,0x9e,0xe5,0x44,0xca,0x24,0xde,0x00,0x43,0xc7,0xcd,0xc8,0x5b,0x21,0x00,0xb9,0x56,0x3f,0xba,0xef,0xcd,0xc4,0xe0,0xd7,0x90
+.byte 0xa7,0xe1,0xf9,0x83,0x2c,0x1d,0x8d,0xc3,0x1b,0xa2,0xab,0xcd,0x7d,0xbc,0xd1,0x2b,0xf8,0x30,0x9e,0xb6,0x95,0xe0,0xd1,0xe6,0x81,0x89,0xa7,0xda,0xf0,0x54,0xc1,0xcb,0x3a,0x85,0x85,0xb5,0x03,0xb4,0x8c,0x7d,0x98,0x16,0xa8,0x83,0x29,0xbb,0x1c,0x1d,0xe1,0x7e,0x0e,0xb5,0x04,0xba,0xbf,0x89,0x30,0x3c,0x44,0xa2,0xc5,0xbf,0xf1,0x70
+.byte 0xdb,0xf3,0x13,0xf4,0x44,0xac,0x63,0xc4,0x9c,0x93,0xa9,0x13,0x1b,0xf1,0xcc,0x16,0x66,0xdf,0x56,0x10,0x88,0x0c,0x76,0xab,0x43,0xcb,0x75,0xf8,0x4f,0x04,0x26,0x95,0x4c,0x6d,0x55,0xc8,0xbd,0xf8,0x94,0x0f,0xca,0x29,0x2b,0xcd,0xce,0x05,0x1e,0xea,0xae,0x02,0x01,0x8b,0x60,0x6a,0x6a,0x03,0x14,0xe5,0xa7,0xdf,0x9e,0x9f,0x94,0x92
+.byte 0x41,0x2c,0xf0,0x1a,0xa7,0xc2,0xc1,0xfc,0x11,0xf3,0x00,0xe1,0xfc,0x7a,0x97,0xc0,0xe1,0x81,0x90,0x3f,0xea,0x1e,0x7f,0xf8,0xb0,0xd8,0x4c,0x2d,0xdc,0x83,0xfa,0x27,0x8b,0xf2,0xef,0x3b,0x3a,0x44,0xdc,0xa5,0xa9,0xd5,0x24,0x5f,0xb1,0xdd,0x1d,0x3f,0x03,0x76,0x3b,0x92,0x0d,0xb4,0x84,0xa4,0x5b,0xef,0x9f,0x89,0x9d,0xef,0xff,0xcf
+.byte 0xc2,0x28,0x3b,0x9d,0xd2,0x28,0x75,0x3e,0xdc,0x14,0x79,0x7c,0x0c,0xaa,0x6c,0xf2,0x05,0x9d,0x27,0x01,0x15,0x19,0x60,0x48,0x5a,0x7d,0x04,0x27,0x2d,0x82,0x92,0x3e,0x0b,0x62,0xd7,0x5a,0xfb,0x72,0xfb,0xdd,0x43,0xfa,0xf4,0x6f,0x16,0xd2,0x8f,0x8f,0x21,0xdc,0x81,0x48,0x7a,0xe8,0x39,0xd5,0xdf,0x54,0x0f,0xe1,0xbe,0x65,0xc9,0x49
+.byte 0x98,0xb1,0xff,0x8d,0x52,0x31,0x6a,0xcd,0x5e,0x83,0x17,0x41,0x93,0xcd,0x23,0x76,0x18,0xe9,0x82,0x71,0x15,0xb7,0xd8,0xde,0x0d,0x57,0x8b,0x90,0xe6,0xf4,0x57,0xc1,0xfd,0x3d,0x0d,0x6a,0xae,0xd1,0xd6,0x02,0x3e,0xb9,0x82,0xb2,0x82,0x80,0x48,0xa4,0x14,0x29,0x80,0x55,0x1d,0xaf,0x3e,0xf8,0x7e,0x36,0x5f,0x77,0x4c,0x73,0x6c,0x35
+.byte 0xd2,0x7c,0x36,0xca,0x2f,0xec,0x1e,0x3f,0x74,0xee,0xa5,0xe7,0x7d,0xce,0x81,0xf1,0xd5,0xc1,0xb3,0xaf,0x90,0x2c,0xc6,0x5b,0x81,0x37,0x85,0x98,0x78,0x3c,0x4f,0x2a,0x55,0xea,0x06,0x30,0x77,0x73,0x97,0x39,0x75,0xcf,0x4a,0x9b,0x55,0xb8,0x64,0x5c,0x86,0xfd,0x26,0x3e,0x8d,0x68,0xd2,0x70,0xe8,0xd7,0x99,0x57,0x6f,0x96,0x47,0x6d
+.byte 0xa7,0x1a,0x0e,0x85,0xcd,0x00,0xa5,0x3e,0x11,0xec,0x76,0xd2,0x47,0x26,0x71,0xda,0x5c,0xf4,0xb1,0xd5,0x23,0xe1,0x62,0x71,0x43,0x30,0xa7,0x95,0xf6,0xc1,0xcf,0x8a,0x1b,0x75,0x53,0x39,0x6d,0x9d,0x18,0x7c,0xe3,0x48,0x27,0x33,0x1c,0x38,0x45,0xdf,0x75,0x22,0x05,0x6d,0x81,0x5d,0xfc,0xeb,0x0e,0x05,0x26,0x45,0x81,0x9f,0xce,0x0f
+.byte 0xc9,0xdd,0x95,0x11,0x04,0x47,0x40,0xa4,0x07,0x3b,0x52,0x92,0xe0,0x91,0xdb,0xdd,0x3c,0x9f,0xd3,0xa1,0xb7,0xf9,0xeb,0xd6,0x6d,0x64,0x88,0xe9,0xf5,0x4e,0x98,0x8e,0x7b,0xd3,0xec,0xc0,0x22,0xe0,0xf2,0x14,0xf2,0x20,0xa2,0xa3,0xb3,0x0d,0x75,0x1a,0xbb,0xde,0x4a,0x41,0x04,0x43,0x0d,0xd9,0xd0,0x1d,0x73,0xc8,0x67,0x8e,0x58,0xe5
+.byte 0x4b,0x28,0x4d,0x8f,0x2f,0xab,0x1a,0x4a,0xfc,0x7c,0xd1,0x27,0x3e,0x4a,0x10,0x6a,0x5f,0x55,0x3a,0xf7,0x63,0x14,0xe9,0xad,0xb4,0x95,0xef,0x3d,0x5c,0xc3,0x7d,0xe4,0xb7,0x15,0xd7,0x0b,0x68,0xf0,0x23,0xa8,0xd4,0x8e,0x27,0xf6,0x55,0x11,0xbc,0xc0,0xff,0x3e,0x2c,0x24,0x59,0xb7,0xb7,0xb5,0x0b,0xd2,0x99,0xa5,0xd5,0xe2,0x24,0x33
+.byte 0x21,0xb8,0x96,0x48,0x18,0x94,0xb5,0xb2,0x50,0x5e,0x04,0x24,0x86,0x17,0x62,0x1e,0xc9,0xf8,0x22,0x6a,0xd0,0xec,0xc5,0xbc,0x90,0xf7,0x55,0xcf,0x3f,0x4c,0x7c,0xf7,0x51,0x19,0x95,0xa4,0x81,0x38,0x0c,0xa5,0x58,0x22,0xf3,0x10,0x05,0x05,0x44,0xbf,0x7e,0x2a,0xbd,0x5f,0x79,0x56,0x08,0xd5,0x68,0xea,0x85,0xa1,0xeb,0x0b,0xe1,0xd4
+.byte 0xfd,0x3a,0x38,0xd2,0x5a,0x49,0x17,0x9a,0x58,0x8f,0x52,0xf5,0xf4,0x7b,0x1f,0x58,0xa8,0xc0,0x1c,0x46,0x38,0xa6,0xe4,0x7d,0xcc,0x88,0x97,0x10,0x2b,0x5e,0x61,0xf5,0x73,0x7d,0x79,0x1b,0x53,0xf1,0xac,0xb4,0x3f,0xbd,0x9d,0xb6,0xc2,0x57,0xd5,0x84,0x4d,0x60,0xd6,0x45,0x56,0xa1,0x36,0x28,0xf5,0x74,0xc6,0x29,0xd7,0xc9,0x63,0x5e
+.byte 0x7c,0x97,0x46,0xde,0x56,0x3f,0xd8,0x8e,0x75,0x29,0x87,0xe7,0xd1,0x24,0x78,0x26,0xdc,0x17,0x97,0xc9,0xf0,0x8e,0x95,0xbc,0xe5,0xfe,0xe3,0x3a,0x75,0x70,0x52,0xa9,0x31,0x97,0x79,0x3a,0xc2,0x53,0x6a,0x73,0xe2,0x76,0xf8,0x85,0xe6,0x0d,0x85,0x9b,0xfc,0x72,0x08,0x2a,0xa5,0x8e,0x42,0xb2,0x7c,0x8d,0x8b,0x28,0x4b,0xf5,0xcb,0x66
+.byte 0x80,0x46,0xb3,0x87,0xdf,0x38,0xa7,0x08,0xc8,0xea,0x85,0x0e,0x6f,0x13,0xe0,0x57,0x99,0xc6,0xb8,0xed,0x9c,0xb0,0xa9,0x89,0xd7,0xc5,0xa9,0x71,0xfd,0x8a,0x21,0xb1,0xec,0xc8,0x65,0x78,0x72,0xc6,0x77,0x69,0xd4,0x0b,0x47,0x4d,0x79,0x93,0xcf,0x2a,0x34,0xf1,0x1b,0x0e,0x6f,0x0d,0xd1,0xbb,0xe7,0xd7,0xb5,0x6f,0x57,0x01,0xd4,0xcd
+.byte 0x56,0xbe,0xf0,0xd9,0xe2,0x8e,0x0e,0xb8,0x3d,0xdb,0xf6,0x97,0x39,0x0b,0x3e,0xe2,0xb2,0xa3,0x93,0x0b,0x74,0xe5,0x6a,0x21,0x04,0x29,0x5a,0x3e,0x07,0x9c,0x11,0x4e,0xfe,0x01,0x6e,0x96,0x1e,0x8f,0xe0,0xfe,0x24,0x24,0x7e,0x04,0x2f,0x65,0xf4,0xe2,0x1f,0x36,0x56,0x43,0x3a,0x6c,0xeb,0xd7,0x20,0x13,0x71,0x45,0x6a,0xe8,0xc6,0xfa
+.byte 0xba,0x26,0x6f,0x7d,0x9a,0x62,0x76,0x34,0x7d,0xed,0x47,0x71,0xd1,0x0e,0x5b,0x04,0x39,0xd6,0xc0,0xe5,0xa5,0xd8,0xf5,0x73,0xf9,0xf4,0xc2,0x2a,0x54,0x25,0x67,0xdf,0x83,0xa3,0xcd,0xfd,0x1e,0x46,0x87,0x06,0x17,0x6d,0x78,0x8e,0x0c,0x7b,0x08,0x06,0x1b,0xd9,0x5d,0x3d,0x03,0x40,0xbc,0xe7,0x02,0xc4,0xe0,0xe0,0x49,0xb2,0x6c,0x6f
+.byte 0x97,0x76,0x0f,0xc7,0x14,0xd8,0x7c,0xc0,0xad,0x8a,0xbb,0xbc,0x2a,0x7e,0x68,0x46,0xcd,0xa7,0x26,0x16,0x77,0x1b,0x89,0x38,0xd8,0x2a,0x69,0x43,0xc4,0xaa,0x0d,0xf6,0xd1,0x65,0xda,0x41,0x75,0x77,0xcd,0xf7,0xd2,0x38,0x9c,0xdb,0x81,0x17,0x27,0x2f,0xba,0x2e,0xa5,0xb5,0xbe,0x05,0xe8,0xdd,0x5f,0xa9,0xad,0xbe,0xb2,0x0e,0x0b,0x69
+.byte 0xb6,0x8d,0xd2,0xf2,0xde,0x76,0x32,0x26,0xd9,0x06,0x1d,0x42,0x26,0x8c,0xf7,0xca,0x4c,0xe1,0x59,0x82,0x6c,0xea,0x96,0x70,0x39,0xb8,0x0d,0xf3,0x67,0x9d,0x5e,0x94,0x99,0x77,0xf2,0x0a,0x9a,0xde,0xa5,0xd2,0xe1,0xaa,0x91,0x85,0xc7,0x0f,0x92,0x35,0x04,0xd3,0x7a,0x13,0xfa,0xf2,0x86,0x5a,0x38,0xd1,0x7f,0x10,0xd8,0x30,0x0e,0x33
+.byte 0xe3,0xa0,0x8a,0xad,0x4f,0x6c,0x24,0xdd,0x9d,0x1c,0x4e,0xff,0x4c,0xfc,0x74,0x01,0xab,0x08,0x6c,0xe6,0x4c,0x78,0x75,0xc9,0x67,0x83,0x1f,0x75,0x22,0xb0,0x7c,0x44,0xa0,0xa1,0xee,0x4e,0xf6,0x3e,0xd3,0x35,0x70,0xbe,0x36,0x1e,0x90,0xa6,0xaa,0x64,0x67,0x7f,0x52,0x84,0xd9,0x27,0xab,0x37,0x30,0x68,0x46,0xcc,0x0e,0x57,0x58,0x6f
+.byte 0xdb,0xb2,0x5f,0x24,0xf7,0xeb,0x97,0xea,0x64,0xec,0x6c,0x1e,0xe1,0xc4,0x72,0xfb,0x00,0xa7,0x62,0xa0,0x59,0xb9,0x17,0x8a,0x33,0x32,0x59,0xb8,0xbe,0x84,0xd4,0x62,0xb7,0xf6,0x35,0xd4,0xf1,0x1c,0xdb,0x7e,0xa6,0xbc,0x2c,0x54,0x3c,0xf5,0x63,0x4a,0x22,0x26,0x58,0xa0,0x35,0x98,0xa7,0x32,0xb2,0xa0,0x2b,0xd5,0xfa,0x2f,0x9b,0xb4
+.byte 0xea,0xd6,0x58,0x61,0xb2,0x24,0x45,0x46,0x1e,0xac,0x79,0xa4,0xf7,0xc1,0x13,0x2f,0xf5,0x6b,0xfa,0x70,0x50,0x2b,0x83,0xee,0x7c,0xc1,0x55,0x27,0x7b,0x4f,0xa6,0x0a,0x72,0x26,0x82,0xcd,0x4d,0xe2,0xe8,0x45,0xe6,0xd7,0x39,0x7e,0xed,0x35,0xdf,0x9e,0xb1,0x41,0x55,0xa2,0x5d,0x68,0x4b,0x0b,0xd1,0x73,0x5a,0x2b,0x81,0x35,0x28,0xfc
+.byte 0x64,0x08,0xd7,0xc4,0x9f,0x30,0x77,0x3d,0x9d,0x80,0x15,0x67,0x9a,0x84,0xe4,0x34,0xea,0x8c,0xf7,0x73,0x9e,0x33,0xb4,0x09,0x33,0xbd,0xd8,0x82,0x43,0x7d,0xc5,0x1f,0x0e,0x7b,0xa0,0x53,0x59,0x20,0x12,0x57,0xed,0xda,0xc7,0x19,0x8e,0x62,0xe4,0x09,0xc1,0x4b,0x20,0x32,0x9e,0x18,0x11,0x1c,0x42,0x49,0x62,0x76,0xa8,0x83,0x72,0x11
+.byte 0x45,0xe7,0xb5,0x60,0xa7,0xc0,0x07,0xbd,0xb4,0x7c,0xc6,0x5c,0x03,0x34,0xa3,0x85,0x47,0x24,0x75,0xd2,0xab,0x46,0xbb,0xc7,0x0d,0xcd,0x40,0xe2,0x5e,0x5b,0xa7,0x98,0x67,0xe4,0xe2,0x02,0xe9,0xdc,0xd7,0xc2,0xaf,0x90,0x43,0x94,0xfe,0xf3,0x53,0xc1,0x10,0x28,0xa7,0x90,0xba,0x73,0x57,0x0c,0x4d,0x6d,0xbd,0xda,0x81,0xd5,0x90,0xce
+.byte 0x02,0x40,0xb3,0xf0,0xec,0x50,0x82,0xc9,0xfb,0xf1,0x22,0x6d,0xc8,0xd2,0x7b,0xed,0x0b,0x43,0x7e,0x0b,0x60,0x9b,0x69,0x9e,0x58,0x26,0xc3,0x9f,0x6b,0xd0,0x31,0xeb,0xb7,0x0a,0xf3,0x9a,0x9a,0xf5,0x72,0xcf,0x29,0xc8,0x19,0x08,0x4d,0x67,0xd5,0xa1,0x8f,0x68,0x0e,0xee,0x59,0x14,0xf8,0x86,0xc0,0x08,0x5a,0x56,0xfe,0x6a,0xb7,0xac
+.byte 0x78,0x8d,0x77,0x39,0x5e,0xb1,0x01,0x4d,0x31,0x81,0x56,0xdc,0x5b,0x10,0xda,0x4d,0xd2,0xfd,0xfc,0xa3,0xe3,0xaa,0x46,0x29,0x1a,0xea,0x9c,0x47,0x1b,0xd0,0xa6,0x84,0x1f,0x71,0x1a,0xd3,0x35,0x59,0x7f,0xef,0xf7,0x81,0x39,0x7a,0x9f,0x4a,0x01,0x4d,0x46,0xcf,0xa4,0x6a,0x9c,0x7e,0x07,0x8b,0x98,0x17,0x49,0x5c,0x46,0xac,0xc8,0xfd
+.byte 0x1c,0xaf,0x91,0x30,0x0c,0x36,0x63,0xef,0x69,0xd3,0x47,0xf4,0x76,0xc1,0xf7,0x40,0x03,0x98,0x9e,0xcb,0x61,0x65,0x46,0x45,0x1c,0x1b,0xfd,0x13,0x36,0xe9,0x19,0xbf,0x2b,0x59,0x51,0xe8,0x04,0x44,0xe3,0xc2,0x4b,0x66,0x78,0x69,0x66,0xa3,0x1a,0xe5,0x2a,0xad,0xf8,0xc5,0x0f,0xb7,0x3e,0xe8,0xab,0xe0,0xe4,0xd9,0xc2,0xb8,0x61,0x5b
+.byte 0xef,0x6b,0x4d,0x5f,0xb8,0xdc,0x06,0xa5,0xce,0x08,0x5b,0x1f,0xf4,0x29,0x4d,0x0a,0x3e,0xb3,0x60,0xf4,0x63,0x3c,0x70,0x5d,0x02,0x9c,0x55,0x5e,0x5e,0xd1,0x9b,0xed,0x20,0x75,0x54,0xa1,0x8e,0xae,0xce,0x5a,0xb2,0x2d,0xe4,0xc3,0x9b,0x7d,0x72,0xce,0x7c,0x0c,0xa9,0x99,0xa4,0x12,0xaa,0x31,0xe9,0x61,0x47,0x8a,0x41,0x93,0xd5,0x69
+.byte 0xc5,0xf3,0x9f,0xf4,0x97,0x69,0x64,0x6f,0xf9,0x5b,0xbf,0x58,0xf6,0x3b,0x3e,0xd6,0x93,0x94,0x89,0xcc,0xc0,0x25,0x7d,0xf8,0x40,0x9e,0xb2,0xc8,0x75,0x9d,0x4d,0xf0,0x5f,0xa5,0x3d,0x38,0x67,0xea,0x8d,0x1b,0x60,0x5e,0xfe,0xa8,0x26,0xb9,0xed,0xc0,0xe9,0xc8,0xec,0xb1,0x77,0x0f,0xf2,0xaa,0x77,0x2a,0xcd,0xa8,0x70,0xb7,0xda,0x60
+.byte 0x49,0xb3,0x01,0x95,0xc8,0xac,0x71,0x6a,0xd0,0x49,0x67,0x2a,0x04,0xfc,0x55,0x38,0x08,0x37,0xd9,0x21,0x37,0xce,0x41,0xaf,0x7c,0x33,0xdd,0xcd,0xe0,0x92,0x27,0x38,0x63,0x77,0xea,0x86,0x04,0x99,0x4e,0x61,0x8b,0x8f,0xfe,0x4e,0xc1,0x16,0x6c,0x89,0xac,0x1f,0x0b,0x67,0x75,0x49,0xf4,0xdb,0x6d,0xd3,0xb8,0x1d,0x9c,0xb2,0xe6,0x98
+.byte 0x81,0xae,0x3f,0xe0,0xdd,0xda,0xfa,0x4c,0x8b,0x30,0x18,0x88,0xa1,0x1d,0xa1,0x18,0xb8,0x28,0xc2,0x04,0x6a,0x80,0x02,0x5a,0xe6,0x04,0x85,0xfa,0x54,0x38,0x45,0x64,0xe1,0x50,0x4a,0x38,0x4c,0x85,0xf7,0x00,0x0c,0xd3,0x16,0xcb,0xfa,0x38,0xb4,0x1b,0x6a,0x95,0x3d,0xc3,0x24,0x79,0x0e,0x3e,0x81,0xe6,0xc3,0xd9,0xdb,0x05,0x19,0x7c
+.byte 0xb4,0x4d,0xef,0x71,0x22,0x53,0x97,0x8a,0xc9,0xe3,0x69,0x20,0x5b,0x83,0xb1,0x44,0xd7,0xd1,0x1e,0x87,0xa7,0xbf,0xe4,0x84,0x68,0x9c,0x77,0xfe,0x83,0xdb,0x7a,0x53,0xa8,0x53,0x1f,0xc7,0xd1,0x6a,0x26,0x87,0x71,0x06,0x23,0xa7,0xe0,0x18,0x5d,0xfa,0x8c,0xa7,0x24,0xee,0xf6,0x74,0xab,0x17,0xd3,0x46,0x33,0xe9,0xc3,0xcd,0xa6,0xaf
+.byte 0xcf,0xa1,0x60,0x75,0x7b,0x77,0xc3,0x58,0xa2,0xe8,0x87,0x7b,0x4b,0x57,0xb1,0x96,0xc1,0x91,0x6d,0xbf,0x71,0xb3,0xbf,0xe2,0x62,0x86,0x72,0xa9,0x01,0x64,0x62,0x32,0x33,0xc8,0xa4,0x26,0x7d,0xfa,0x0d,0xd4,0xd8,0xc3,0xaa,0xc0,0xc8,0x7c,0x51,0xe8,0x10,0x08,0x6f,0xf6,0xc1,0x46,0x89,0xc4,0xd2,0x00,0x1d,0x14,0x05,0x89,0x64,0x52
+.byte 0xcd,0x1f,0x97,0x0b,0x1d,0x94,0xbe,0x9d,0xa0,0x6b,0x03,0x9b,0x83,0x87,0x38,0x0f,0x65,0xdd,0x6a,0xaf,0xf1,0x22,0x74,0x7e,0x11,0xa0,0xdf,0x1e,0x95,0xef,0x1a,0xdc,0x8b,0x29,0x4a,0xbe,0xfd,0x2f,0xc7,0x48,0x94,0x3f,0xb9,0x8c,0x8e,0xe1,0x0c,0x54,0xa6,0x2f,0xa5,0x2b,0x71,0xdd,0x16,0x68,0x91,0x35,0xd0,0x22,0x48,0x1f,0xf2,0xe2
+.byte 0xe8,0x57,0x83,0xd7,0x49,0x43,0xfd,0xf9,0x77,0xb5,0xfa,0x70,0x19,0xeb,0xae,0xf6,0x31,0xfe,0xd6,0x81,0x6c,0xcc,0x14,0x28,0xa6,0x9f,0x74,0x56,0xc5,0xf6,0x51,0xba,0xc8,0xbd,0x32,0x80,0x5f,0xdb,0x28,0x3f,0x4a,0x55,0x01,0xe1,0x39,0xf5,0x9c,0xda,0xb3,0x42,0xee,0x43,0x17,0xc3,0xc7,0xf5,0xd1,0xda,0xd2,0x2e,0x56,0xcf,0x77,0x0e
+.byte 0xdd,0x72,0xcf,0xe5,0xab,0xfb,0xd6,0xa2,0x6c,0x03,0xa6,0x77,0x25,0xf8,0x2a,0x8c,0xfa,0x6f,0x45,0x79,0x59,0x84,0x92,0xd1,0x00,0x58,0xc7,0xb8,0x95,0x4d,0xc8,0x49,0xad,0xe0,0x1e,0x64,0x47,0x00,0xfb,0x93,0x7f,0x3e,0xf1,0x65,0x70,0x47,0x64,0xbb,0x36,0x63,0xe3,0x09,0xcb,0xdb,0x5a,0xd1,0x72,0x83,0xfd,0x15,0x91,0xa2,0x03,0x81
+.byte 0x04,0x98,0x45,0x0f,0x7f,0x23,0x48,0x6c,0xb1,0x2d,0xd0,0x2c,0x61,0x52,0x1b,0x4a,0x52,0x08,0x92,0xe1,0x7a,0xf1,0x8c,0x1f,0x1f,0xdf,0x1c,0xfd,0xd9,0x46,0x99,0x71,0x05,0x58,0x71,0x82,0x5c,0x05,0xa0,0xb2,0x6a,0x50,0xd2,0x6e,0x35,0xf4,0x6c,0xfb,0x50,0x99,0xb3,0xc1,0x2b,0x05,0xaf,0x02,0xe5,0x18,0xfa,0x74,0x09,0xcc,0xa5,0x2c
+.byte 0x26,0xfd,0xc5,0xe7,0x2c,0x96,0x0f,0xa4,0x7c,0x88,0xc6,0x7f,0xf9,0x74,0x9d,0x1c,0xe5,0xd2,0x27,0xf0,0xae,0x5b,0x4c,0xbf,0x0a,0x99,0x2e,0xaa,0x54,0xba,0x0d,0x75,0xd9,0x48,0x76,0xf3,0xe9,0xd9,0x01,0xbe,0xaa,0x97,0x09,0xfe,0xb2,0x4a,0xcb,0x55,0xd0,0xe1,0x58,0xec,0x31,0x0c,0xd9,0xdf,0xd9,0x01,0xf9,0x3c,0x28,0x40,0x91,0xbb
+.byte 0x4d,0x2d,0x88,0x60,0x31,0xc7,0xc9,0x1d,0xaf,0x22,0x44,0x21,0x05,0x06,0xdd,0x07,0x60,0x29,0x7d,0x49,0x30,0x9d,0x35,0x1d,0x9f,0x37,0xbd,0x32,0xb2,0x21,0xa6,0x4f,0x89,0xd8,0xe6,0x85,0x44,0xcf,0x13,0x12,0x4f,0x5f,0x50,0x71,0x01,0x39,0xff,0x6e,0xa0,0x07,0xff,0xf0,0xa6,0x3b,0x39,0x59,0x17,0xae,0x93,0xb2,0x86,0xcc,0xe5,0x59
+.byte 0x5a,0xf2,0x82,0x62,0xc6,0x8d,0x13,0x2f,0x6b,0x92,0x28,0xbe,0xd1,0xc0,0xf6,0xc9,0xe1,0xd6,0x98,0x94,0x65,0xd4,0x2a,0xdb,0x37,0xb1,0xd3,0x83,0xf2,0xaa,0xa5,0x00,0xf9,0x08,0xe6,0x22,0x38,0x30,0xb6,0x49,0x8d,0x9d,0x1c,0xa4,0xf7,0xdb,0x3c,0x6f,0x75,0x08,0xa0,0xda,0xe9,0xc0,0x01,0x54,0x09,0x68,0xc6,0x7c,0x5b,0x4d,0x88,0x71
+.byte 0xa7,0x2f,0xb3,0x50,0x18,0x4a,0xfb,0x55,0x29,0xf2,0x56,0x1d,0x4c,0x12,0x22,0x1c,0x54,0xd2,0x63,0x67,0xfa,0xe9,0x5b,0x74,0x3b,0x38,0xf6,0xa0,0x85,0x63,0x1c,0x41,0x6a,0x6d,0x71,0x1d,0xb1,0x39,0x28,0x88,0x96,0x9b,0x9c,0x50,0x9e,0x57,0x4e,0xf5,0xa7,0xf4,0x17,0xc6,0xca,0x42,0x84,0x83,0xca,0xa4,0x28,0x72,0x08,0x74,0x62,0xe1
+.byte 0xf0,0x73,0xc5,0x86,0x6c,0x76,0x9d,0xd3,0xa6,0xb8,0x5d,0x73,0x1b,0x02,0xe2,0x69,0x8b,0x59,0xd6,0x6a,0x53,0xe9,0x13,0x88,0x41,0x95,0xe9,0x97,0x5f,0x07,0x62,0xa5,0x21,0x97,0x7e,0x5e,0xc2,0x2c,0xc7,0xaf,0x0a,0xdb,0x9e,0x4f,0x44,0x4b,0xd6,0x3d,0xc0,0x24,0x38,0x50,0x47,0x98,0xa3,0xfc,0xda,0xfc,0xae,0x0e,0x2b,0x9b,0x53,0x0f
+.byte 0x6b,0xb1,0x2f,0xd5,0xd7,0x68,0xc9,0xab,0xb9,0xff,0x7f,0x54,0xd6,0x2f,0x88,0xbc,0x5e,0x6a,0x22,0x49,0x0f,0x98,0xbe,0x1f,0xef,0x3e,0xcc,0xa2,0x72,0x6b,0x16,0xbe,0xe8,0x5f,0x0e,0x36,0xa2,0x68,0xe0,0x65,0xd9,0x7c,0xdc,0x8c,0x6a,0x66,0xf0,0x6a,0xfc,0x2b,0x85,0x28,0x2a,0x1a,0xfc,0x92,0x64,0x3d,0x38,0x5b,0xc1,0x0c,0x68,0x45
+.byte 0x94,0x85,0x58,0x82,0x99,0xfc,0x20,0xdd,0x62,0xae,0xed,0x35,0x7c,0x02,0x16,0x9b,0x00,0x8a,0x44,0x02,0x80,0x00,0xca,0x7d,0x95,0x03,0x5d,0xa6,0xec,0xe1,0x0c,0x50,0x34,0x61,0x55,0xee,0xb5,0x11,0xff,0xc3,0xaa,0xf2,0xbc,0xa3,0xa9,0xc7,0x6b,0x16,0xab,0x56,0x7b,0x55,0x54,0x95,0x88,0x15,0x15,0x6a,0x2c,0x97,0xd7,0x7c,0x26,0x65
+.byte 0xaf,0x8d,0xd1,0x05,0x57,0xb2,0x63,0xd1,0x22,0xf7,0x7d,0x77,0x54,0x6c,0x87,0x03,0x1f,0x0e,0x2b,0xae,0xa6,0xa4,0xb5,0xd6,0x95,0x34,0xd0,0x62,0x4e,0xfb,0xcb,0xee,0x01,0xc1,0xf7,0x36,0x94,0xa6,0x54,0x94,0x90,0x0e,0x45,0x9c,0x95,0x89,0x96,0x88,0x32,0x90,0x27,0x48,0xc5,0x96,0xf0,0x7e,0x7f,0x69,0x99,0xdf,0x7b,0xfb,0x2b,0x7b
+.byte 0x38,0x10,0x6b,0xd1,0x1a,0xfb,0xf2,0xcd,0x2d,0x8b,0x47,0x21,0xca,0x92,0x64,0x28,0xd1,0x53,0x1d,0xed,0xa7,0x7d,0xa4,0x88,0xab,0xd0,0xfe,0x9b,0x2b,0xf8,0x48,0x94,0x8d,0xd5,0xfa,0x5c,0xef,0x12,0x43,0xdf,0xb6,0x5b,0x83,0x43,0xf3,0xf7,0x1d,0x6f,0x3e,0x44,0xe6,0x20,0xd8,0xbc,0x4a,0x9a,0xed,0xa0,0x79,0x66,0x8d,0x23,0xca,0x35
+.byte 0x15,0x87,0x11,0x50,0xa4,0x40,0x6e,0xfa,0xf7,0xaf,0xa2,0xb7,0x3b,0x9b,0x8b,0x44,0x19,0x90,0xb3,0x47,0x92,0x08,0x2f,0x0c,0xe2,0x95,0x5d,0x80,0xb5,0x93,0x5e,0x1c,0xb5,0xce,0x52,0x0b,0x12,0xc1,0x72,0x2e,0x66,0x8c,0xd1,0x13,0x94,0x36,0xf7,0x17,0xe3,0xad,0x69,0xc9,0x2d,0x21,0x64,0xcd,0x8f,0x2d,0x8f,0x0c,0x85,0xa5,0x23,0x8b
+.byte 0x6c,0x00,0x13,0xf7,0x6a,0xb4,0x68,0x1a,0xcc,0xc4,0x03,0x5b,0xd6,0x7b,0x5b,0x34,0x90,0x34,0x3e,0x0a,0x07,0x19,0x81,0x99,0xe9,0xd2,0xa8,0x73,0x2c,0xa2,0xcf,0xdf,0x29,0x69,0xbf,0xec,0xdd,0xa5,0xd3,0x16,0xb0,0xd2,0x9c,0x2f,0xeb,0x70,0x50,0x20,0x3c,0x22,0x1a,0x5b,0x55,0x79,0x76,0x0f,0x1f,0xd0,0x34,0xa9,0x55,0xad,0x75,0x75
+.byte 0x7f,0xa7,0x9b,0xa7,0x3d,0x5d,0x73,0xce,0x91,0xf6,0x9b,0xcd,0xa5,0xee,0x48,0x44,0xba,0xd5,0xad,0xbe,0x1e,0xc6,0xd2,0x8b,0x05,0x21,0x20,0xb5,0x7d,0x78,0x88,0x10,0x20,0x85,0x90,0x8f,0x47,0x74,0x68,0xe6,0x32,0x2a,0x13,0x7a,0xb3,0x5d,0xfe,0x24,0x97,0xd1,0x65,0x55,0x60,0xb3,0x88,0xfb,0x59,0xc9,0x29,0x70,0xf1,0x45,0xbd,0xbe
+.byte 0x4d,0x01,0x4e,0x5e,0x5f,0x99,0x52,0xf8,0x5f,0x38,0xcf,0xa8,0x5d,0x69,0x54,0x87,0x72,0x41,0xca,0xc4,0x63,0xc1,0x52,0x58,0x66,0x8b,0xda,0x8b,0x61,0xd1,0xab,0x7d,0x8d,0xfe,0x51,0x8d,0xf6,0xd0,0x21,0x4d,0x0b,0xc5,0xea,0x74,0xcd,0x21,0x93,0x4a,0x91,0xe5,0x3f,0xce,0x35,0x3b,0x3f,0xc0,0xab,0xa4,0x23,0x76,0xd1,0x8c,0xa7,0xbe
+.byte 0x15,0xab,0x8e,0xd7,0x0d,0x86,0xac,0xc3,0x06,0xff,0x33,0xf2,0x41,0x6f,0x69,0x58,0x49,0xd1,0x73,0xcf,0x5e,0x4e,0x1e,0x46,0x12,0xfa,0x30,0x0d,0x4b,0xb1,0xfb,0xc6,0xe6,0x0d,0xcd,0x8d,0xca,0x34,0x28,0x5a,0xed,0x85,0x55,0x31,0xee,0xba,0xbf,0xa4,0x6f,0x9c,0x7d,0xeb,0x4b,0x1b,0x73,0xea,0x4e,0xb9,0x62,0x5d,0xac,0xe3,0x53,0xdf
+.byte 0x27,0x87,0x2f,0x39,0xca,0x5b,0xd6,0x72,0xcf,0x95,0xc6,0x2a,0xa5,0x3f,0x57,0xfd,0xdc,0xa9,0x4a,0x86,0x0f,0xcd,0xd5,0xea,0xfe,0x85,0xeb,0x9b,0x84,0xc6,0xf7,0xba,0xc2,0x37,0xbc,0x18,0x85,0x49,0xa6,0x7f,0xd9,0x3e,0xfb,0xf0,0x0c,0x39,0xe3,0x1c,0x06,0xfe,0xb6,0x49,0xa3,0x8b,0x72,0x2b,0x39,0xa1,0x48,0xfd,0x1f,0xfe,0xa4,0xf7
+.byte 0xcc,0x7a,0xef,0x64,0xa0,0x0d,0xeb,0x78,0x71,0x8c,0xd6,0x59,0x7c,0xf4,0xaa,0x81,0x7a,0x89,0xe6,0x22,0xc9,0x57,0xe8,0x13,0x9c,0xca,0xc4,0x6f,0xb5,0xbf,0x08,0x31,0x93,0x56,0x2a,0x82,0x00,0x95,0xdc,0x4b,0xfd,0x9b,0xc7,0x8b,0x31,0x72,0xa0,0xff,0xbe,0xb4,0xd6,0x07,0x16,0x0a,0x4a,0x0a,0x96,0x02,0x83,0x53,0x2a,0x4d,0x33,0x72
+.byte 0x1f,0x20,0x20,0xc3,0x63,0xee,0x4e,0x05,0x90,0x7d,0x21,0xd0,0xf1,0xda,0xde,0x0d,0x4a,0x59,0xb9,0xca,0x81,0xe3,0x1f,0x83,0x19,0xdc,0x09,0x03,0x5f,0xaa,0xee,0xbc,0x5a,0xfa,0xc6,0x4d,0x3d,0xfe,0xfe,0xf3,0xdb,0xc3,0x77,0x31,0x74,0xb4,0x94,0xb5,0x09,0xb1,0xb5,0x13,0x47,0x2e,0x4f,0x3b,0x38,0x83,0xf5,0xfc,0xe9,0xcc,0x45,0xea
+.byte 0x5b,0x88,0x21,0xba,0x53,0xc5,0xf6,0xd4,0x63,0xc5,0x37,0x1d,0xa1,0x42,0x2e,0x9c,0x9a,0x50,0x2c,0xfe,0xdb,0xf6,0x31,0x36,0x5f,0x9d,0xed,0x63,0x42,0x20,0xdd,0x27,0xe5,0x34,0x3c,0x0f,0x06,0x8b,0x8f,0x32,0xb6,0x47,0xce,0x07,0xcb,0x27,0xc1,0xb7,0xfe,0xb2,0x69,0x81,0x79,0x20,0xd7,0x47,0xbb,0xab,0x61,0x5f,0x09,0x99,0xdf,0x9f
+.byte 0xde,0x59,0x33,0x75,0xd1,0xcc,0xfe,0x92,0x79,0x1f,0x2d,0x59,0x88,0xef,0x4b,0x80,0x0c,0x38,0xa3,0xb1,0xef,0xae,0x53,0x84,0x2f,0xbd,0xd3,0x0c,0xcf,0xd5,0xf7,0xb7,0x6f,0xa7,0x22,0x1f,0xf1,0x56,0x76,0x0c,0x78,0x52,0xa3,0xc0,0xd0,0x2f,0xbc,0xdf,0x29,0x0d,0xa8,0x54,0x0d,0x2b,0x65,0x1b,0x7f,0xeb,0x21,0x22,0xaf,0x10,0xc1,0xd6
+.byte 0x30,0xa8,0x2f,0xb1,0x25,0xbf,0xdc,0xee,0xe9,0x35,0x40,0x69,0xa0,0xa0,0x27,0x85,0x2e,0x18,0xc1,0x36,0x24,0xc5,0x96,0x9a,0x85,0x3f,0xbb,0xfd,0xf5,0x02,0xa2,0xa1,0x92,0x3c,0x16,0x48,0x9f,0xc5,0x00,0x7c,0x7b,0xaf,0x31,0xba,0x68,0x0e,0x58,0x88,0xf4,0x10,0xb9,0xa6,0xe0,0x46,0x2a,0xb8,0x8d,0xc7,0x8e,0xad,0x7c,0xec,0xd2,0x74
+.byte 0x92,0xfe,0x1b,0xd0,0x73,0x79,0x0b,0x4e,0xcc,0x2d,0x5c,0xe7,0x80,0x2d,0x21,0x1c,0x97,0xfc,0x2a,0xc9,0x9c,0x07,0x10,0x64,0x8b,0xf7,0xf5,0x1c,0x54,0xb6,0x6c,0x73,0x1c,0x50,0xd3,0x1a,0x2a,0x63,0xcb,0xba,0xd3,0x95,0xe2,0xa6,0xc3,0xca,0x45,0xfd,0x5e,0x1b,0xbb,0x6b,0x4d,0xb3,0xf7,0xfd,0xaa,0xf9,0x73,0xb8,0x74,0x4d,0x36,0x7e
+.byte 0xcc,0xaa,0x1e,0xf3,0x20,0x68,0xa5,0x0c,0x03,0xe3,0xbe,0xee,0x82,0x03,0x8d,0x10,0xa6,0xf6,0x6c,0x73,0xc2,0x9d,0x74,0xba,0x57,0x17,0xd7,0xfa,0x85,0xf5,0x1e,0x3d,0xf8,0xc7,0x80,0xef,0xcd,0xf0,0xf4,0x46,0xfc,0x07,0xb5,0xc4,0x5f,0xd2,0x04,0x6a,0x90,0xf5,0x76,0xb6,0xf9,0x73,0x22,0xa6,0x09,0x2f,0xbf,0xb5,0x93,0x9a,0x95,0x05
+.byte 0x95,0xaa,0xf9,0x8c,0x71,0xd6,0xc6,0xd9,0x72,0x50,0xf6,0x58,0x77,0x09,0x47,0x97,0x21,0x42,0xf0,0x30,0x5c,0x3c,0xec,0x60,0x67,0xdf,0x5e,0xd2,0xed,0x0f,0xab,0x25,0x11,0xbb,0xf8,0x34,0x1e,0xbd,0x7f,0xc6,0x52,0x19,0xf5,0x53,0x28,0x46,0x75,0x93,0xce,0xc2,0x0b,0xdf,0xfd,0xa5,0xf1,0xb0,0xa2,0x0b,0x97,0xb5,0x76,0xb4,0x8a,0x2b
+.byte 0x82,0x55,0x23,0x29,0xc2,0xd3,0x32,0x94,0x2f,0xf0,0xe6,0x77,0x2c,0xe4,0x6a,0x7f,0xd7,0xee,0x84,0xfb,0xba,0xb8,0x4b,0xae,0x13,0x34,0xbd,0xa8,0x12,0x7a,0x3c,0x28,0x40,0x74,0x5d,0x9a,0x11,0x1a,0xe9,0x74,0x31,0x28,0x3d,0x3d,0x64,0xb7,0x54,0xa0,0x51,0x0d,0xed,0x97,0x94,0x56,0x7a,0x48,0x8e,0x36,0xc9,0xae,0x5f,0xc6,0x79,0x45
+.byte 0x4f,0x07,0xdd,0x13,0x52,0x8b,0xfc,0x3b,0x73,0x44,0x68,0x64,0x51,0x0d,0x95,0x6f,0x0f,0x94,0xba,0xf8,0x40,0x64,0x51,0x43,0x49,0x63,0xc1,0xbd,0xf3,0x39,0x7f,0x6e,0x6f,0x45,0xeb,0xd2,0x33,0x44,0x2d,0x10,0xb4,0x68,0xcb,0xcb,0x8c,0x84,0xc5,0xd4,0x63,0x1d,0x23,0x85,0x30,0x4d,0x6c,0xfc,0xc9,0xa4,0x8c,0xd2,0x42,0x69,0x2f,0x17
+.byte 0x86,0xf0,0x17,0xd0,0xb2,0xaa,0xfd,0x62,0xcb,0xb4,0xfd,0xba,0x29,0xf8,0x85,0x45,0x84,0x9d,0xae,0xf8,0x9c,0x8f,0x64,0xd5,0xb8,0xb6,0xa9,0x64,0xf9,0x39,0x86,0x68,0x29,0xac,0x32,0x87,0x84,0x6c,0xb0,0x09,0xd2,0xdd,0xf2,0xec,0xa1,0x3a,0xfd,0x11,0x37,0x54,0x67,0x29,0x62,0x25,0x62,0xe8,0x6a,0x4b,0x5e,0xde,0x9a,0xf0,0x97,0x73
+.byte 0x66,0x69,0x2a,0x21,0xbe,0x95,0x86,0xca,0xf9,0x17,0xe9,0x4b,0x23,0x83,0x1e,0x8c,0x37,0x47,0x91,0x03,0x3f,0x9f,0xb8,0x60,0x2c,0xdd,0x82,0xbd,0x2a,0xc3,0xe7,0x30,0x8f,0x91,0x2b,0xa4,0x23,0x01,0x03,0xb2,0x8b,0xbd,0xd2,0x1d,0x16,0xf7,0x6a,0x86,0xa8,0xe4,0x54,0x6f,0x9c,0x47,0xa5,0x0f,0xbe,0x94,0x56,0xfa,0x18,0x69,0xbe,0x92
+.byte 0xe9,0xf8,0x24,0x4d,0x65,0x42,0x81,0x1f,0x85,0x52,0xb7,0xc9,0x49,0xde,0xa5,0x4c,0x8f,0x0d,0x5f,0x12,0x68,0x68,0x35,0xce,0x29,0x22,0x5c,0x55,0x3e,0xbd,0xce,0xf2,0x2a,0xec,0x7e,0xe1,0x29,0x0a,0x88,0xf3,0x5e,0xeb,0x27,0xe5,0x52,0xee,0x72,0x37,0xba,0xff,0x82,0x97,0xa9,0x5d,0x77,0x6f,0xb9,0xc3,0xa7,0x73,0xba,0x7f,0x2f,0x7a
+.byte 0x19,0x32,0x87,0x56,0xa2,0x89,0xb2,0xb4,0x48,0xbe,0x2e,0x30,0x89,0x0a,0x8f,0x75,0x25,0x25,0x5c,0x46,0xe8,0x02,0x45,0xcb,0x03,0xd1,0xa3,0xeb,0x70,0x71,0x08,0x1c,0x46,0xf1,0x2c,0x43,0xe2,0x44,0x30,0x6a,0x61,0x31,0x45,0x3e,0xbb,0x47,0x33,0x24,0x25,0x13,0xeb,0xf7,0x24,0x66,0x15,0x4c,0xf3,0x07,0x2f,0xff,0xdc,0x37,0x0f,0x71
+.byte 0x85,0xc8,0x56,0xa7,0x2a,0x22,0x87,0x8b,0xae,0x35,0x31,0x29,0x96,0xf0,0x81,0xfb,0x2c,0xbf,0x44,0x69,0x69,0x9a,0x77,0xfd,0xc0,0x2b,0x42,0x16,0x67,0xd6,0xbd,0xd0,0xf1,0xb9,0x40,0x8f,0xd2,0x9a,0x1b,0x2c,0x64,0x78,0x6b,0xda,0x37,0x26,0xae,0x4c,0xee,0x36,0xaf,0x84,0x61,0xe4,0x93,0x22,0x64,0xaf,0xee,0x6d,0x69,0x5c,0xe5,0x85
+.byte 0xd8,0xcc,0xcf,0xf3,0xe8,0x05,0xcd,0xd2,0x09,0x66,0xaf,0xbb,0xc4,0x79,0xb2,0xa7,0xa5,0x09,0xd9,0xf5,0xa2,0x83,0x4f,0xd5,0xf5,0xf3,0x7d,0x7a,0xab,0x94,0x83,0xb3,0x15,0xfb,0x0d,0x1a,0x1d,0x77,0xc5,0x63,0x0b,0x54,0xde,0xa8,0x0d,0xc4,0x16,0xe3,0x89,0xeb,0xa3,0x1b,0xd4,0x77,0x13,0xe3,0x55,0x98,0x15,0xab,0x3b,0x32,0xc8,0xd4
+.byte 0x0c,0x91,0x80,0x57,0xf7,0x1e,0x24,0xd0,0x56,0x78,0x29,0xd2,0x03,0xe7,0xc4,0xd2,0x09,0xca,0xee,0x9b,0x60,0x5f,0xa1,0xfd,0xaa,0x85,0x4b,0x68,0x35,0xa4,0x3b,0xef,0x29,0xb8,0x49,0x85,0xee,0xbb,0x39,0xc0,0xc6,0x99,0x97,0xc6,0x86,0x6c,0x27,0xf9,0x1a,0x19,0x6e,0x7c,0xae,0x75,0x41,0x0d,0x08,0x1e,0xf0,0xb4,0xc3,0x9e,0xdb,0x40
+.byte 0x86,0x94,0x9d,0x90,0x09,0x3f,0xdc,0xb9,0xfc,0x59,0x41,0xc5,0x5b,0x89,0x97,0x49,0x4a,0x1a,0x06,0x68,0x83,0xd8,0x7e,0x09,0x51,0xe1,0x86,0xd8,0x88,0xbe,0x8a,0x36,0x48,0xb3,0x83,0x7b,0x57,0xdd,0x8f,0x18,0x67,0x4a,0x7d,0x68,0xab,0xb9,0x05,0xf0,0xe4,0x27,0x4e,0x33,0x44,0xa7,0x13,0x04,0x94,0xc5,0x57,0xaf,0x36,0x03,0xe8,0x09
+.byte 0x36,0x5b,0xe8,0x92,0xad,0x0a,0x79,0x02,0x24,0x43,0x62,0xc7,0xa5,0xce,0x7c,0xac,0x6d,0x0a,0xf2,0x83,0x33,0x05,0x3b,0x6f,0x9d,0xda,0x96,0x9f,0x8b,0x79,0x3e,0x6c,0xd6,0xba,0x7f,0xea,0x84,0xd8,0x23,0xb6,0x92,0xc3,0x9c,0x7f,0x0d,0xcb,0x7b,0x9f,0xbd,0xc2,0xf5,0x6f,0x71,0x67,0x5f,0x0b,0xd1,0x73,0xb5,0x8c,0x46,0x07,0xcd,0xd8
+.byte 0xee,0x28,0xcf,0x8f,0x8e,0x5c,0xde,0x14,0x78,0xc7,0x60,0xd5,0xf4,0x49,0x97,0x46,0x5f,0x49,0x4a,0xb4,0x8f,0xc9,0xd1,0x52,0x34,0x01,0x29,0xa1,0x46,0x55,0xf8,0x29,0x53,0xbb,0x32,0x1e,0x4b,0x89,0x96,0x53,0x0b,0xf2,0x16,0xf9,0xa7,0x70,0x93,0x59,0x78,0xc0,0x77,0x78,0x9f,0x6c,0xb3,0x0e,0x3f,0x6f,0x40,0x09,0x1d,0xd6,0x66,0x4e
+.byte 0xe8,0xb0,0xa1,0x14,0x65,0xc8,0xc7,0x3f,0xd2,0xf0,0x1f,0xfd,0x51,0xe0,0x29,0xd6,0x39,0x26,0x60,0xfe,0x62,0xc2,0xe4,0x45,0x6d,0x01,0xdb,0xd3,0x7c,0xdf,0x48,0x10,0x2f,0xf2,0x8e,0x6c,0xc6,0x58,0xc3,0x7d,0x26,0xb1,0x9d,0x52,0x02,0x2a,0x5f,0x2b,0x57,0xca,0x84,0x9d,0x74,0x31,0x01,0x0f,0xda,0x3d,0x7c,0xbb,0xdc,0x71,0x82,0x8b
+.byte 0x42,0xaf,0x49,0x9e,0x2c,0xe8,0xdc,0xa1,0xfb,0x23,0x6d,0xdb,0xdc,0x36,0x01,0xc9,0xb3,0x93,0xd4,0x2e,0x8b,0xd1,0xe4,0xed,0x1b,0xd0,0x4c,0xeb,0xaf,0x96,0x57,0xde,0xee,0x90,0xf4,0xa7,0x58,0x46,0x8a,0xd4,0xa9,0x44,0xe0,0xb3,0x13,0x96,0xb2,0x8a,0xb0,0xd3,0xbe,0x71,0x38,0xb7,0x35,0xa9,0xa8,0x48,0x37,0xa3,0x11,0x0e,0x61,0x36
+.byte 0x6c,0xaf,0x6c,0xf2,0x3f,0xd6,0x55,0xb3,0xa5,0xe0,0xaf,0x18,0x6a,0xf5,0x78,0xb5,0x7c,0xc7,0x48,0x24,0x6c,0xea,0x1e,0x7f,0x52,0xb4,0xe8,0x72,0x46,0xd2,0xbd,0x1c,0x9e,0xe6,0x5b,0x3e,0x9c,0x6c,0x6c,0x6b,0x45,0x0c,0x3a,0xb7,0x67,0x3c,0x8e,0x77,0x77,0xbf,0x50,0xb6,0x30,0x6e,0xe1,0x28,0x0d,0x2a,0x85,0x44,0xf8,0xbb,0xf1,0x14
+.byte 0x89,0xaa,0xc2,0x27,0xf5,0x8e,0xa1,0xd3,0x07,0xba,0xe8,0x03,0xcf,0x27,0x1c,0xa6,0xc4,0x63,0x70,0x40,0xe7,0xca,0x1e,0x05,0xb7,0xb7,0xdc,0xc0,0x07,0x4c,0x0d,0x21,0x12,0x60,0x02,0xe3,0x86,0x65,0xe7,0x1c,0x42,0x86,0xdd,0xdb,0x7f,0x26,0x60,0x01,0x3d,0xd8,0x18,0xcd,0x7a,0x9f,0xf8,0xb2,0xf6,0x6d,0xd3,0xe0,0x57,0x1f,0x80,0x30
+.byte 0x2d,0x5e,0x71,0xdf,0x4d,0x7f,0xcd,0x63,0x77,0x19,0x5e,0x2d,0xd5,0xb5,0xfa,0xa9,0x26,0x02,0xb9,0x62,0x2b,0x57,0x80,0x0a,0xe9,0xbc,0xa4,0x3b,0xa7,0xf1,0xf3,0x77,0x2b,0x6b,0x41,0x5e,0xf7,0xe8,0x66,0x23,0x63,0xac,0xcd,0x58,0xfc,0xa9,0x97,0x6b,0x5a,0x1e,0xe5,0x7d,0xfd,0xb1,0x42,0x7f,0x99,0xdd,0x60,0xaf,0x39,0x46,0x36,0xdd
+.byte 0xc2,0x70,0x83,0x53,0xd1,0xc3,0x69,0xc8,0x90,0x0e,0x2b,0x34,0xb2,0x0c,0xb9,0x7a,0xb8,0x6b,0x7c,0xc2,0xf3,0xae,0x41,0x24,0xb8,0x94,0x5f,0xdd,0xce,0xda,0x95,0xda,0x49,0x81,0xb6,0xf8,0xa9,0x8e,0xb3,0x79,0xf8,0x55,0xf9,0xcf,0x8c,0x24,0x99,0xfc,0x6b,0x15,0x0f,0x39,0xac,0xd0,0x3e,0x89,0x9d,0xc2,0x46,0x8c,0x99,0x45,0xfd,0xce
+.byte 0x13,0x4c,0x9c,0xc8,0x80,0x87,0x8f,0x7b,0x28,0xe3,0x5e,0x2b,0xe3,0x89,0x7e,0x13,0x52,0x52,0xe9,0x3a,0xed,0x33,0xe7,0x28,0xc7,0x7a,0x48,0x8d,0x0e,0xee,0x24,0xc4,0x61,0x04,0x3c,0xd4,0x7e,0xf3,0x30,0x22,0x07,0x58,0xae,0x02,0xc5,0xd1,0x7d,0x04,0x18,0xca,0xd6,0x04,0xd4,0xc5,0xa4,0xff,0x8d,0x0d,0x68,0xd4,0x1a,0x3a,0x72,0x6f
+.byte 0x41,0x1e,0xda,0xc0,0x97,0x7c,0x55,0x2c,0x13,0x20,0x9a,0x07,0x35,0xcc,0xc5,0x83,0xee,0x41,0x77,0x51,0x28,0x07,0xe0,0x81,0xe3,0x9b,0x1f,0xdb,0x73,0x5c,0x8d,0x82,0xa2,0x8b,0xf4,0x92,0x4f,0x70,0xa8,0x6a,0xcf,0xbf,0xcf,0x0b,0x71,0xbc,0xeb,0x81,0xb4,0xc9,0x65,0xe7,0x43,0xef,0x25,0x45,0x27,0xea,0xcd,0x60,0x68,0xcd,0x2d,0x7a
+.byte 0xfd,0x88,0x6d,0x06,0xd5,0x92,0x32,0xc3,0x18,0x88,0x64,0xa7,0xde,0x39,0xeb,0x0b,0x5c,0x9c,0xf6,0xf6,0x93,0x90,0x24,0x0c,0x9e,0x0b,0x89,0x1c,0xcb,0xc8,0x96,0x72,0x17,0xae,0x46,0x61,0x69,0x6e,0xbe,0x6c,0xf1,0xa4,0xa4,0x50,0xa9,0x2a,0x47,0xd7,0x80,0xe4,0x72,0xd2,0x3f,0x1a,0xdd,0x82,0xdc,0x12,0x66,0x10,0x26,0x15,0x80,0x56
+.byte 0x4d,0xbe,0x02,0xae,0xe1,0x24,0x8a,0x41,0x52,0xc8,0x5d,0x8d,0x62,0x85,0xbe,0x7c,0x35,0xdd,0x88,0xd3,0xf5,0xf7,0x9b,0xf1,0x5a,0x4e,0x70,0x48,0x31,0x5a,0xaa,0x96,0x1e,0xf8,0x73,0xb4,0x0f,0xb2,0x82,0xf4,0x13,0xac,0xba,0x3b,0x12,0x36,0x1e,0x23,0xbf,0x09,0x8a,0x1c,0x96,0x47,0x56,0x2d,0x16,0x24,0xc3,0x23,0x65,0xe2,0x99,0xd0
+.byte 0xf0,0xa0,0x2c,0x64,0x35,0xad,0x16,0x34,0x67,0x52,0xbc,0x8f,0x17,0x90,0xf9,0xc7,0x4f,0x64,0x6c,0x75,0x3f,0xd7,0x48,0xa4,0x6b,0x43,0xe6,0x2e,0x7a,0xe3,0x79,0xe8,0x47,0x51,0xe9,0x52,0x36,0x30,0xa4,0x24,0x89,0x00,0xd5,0x77,0xbd,0x34,0x2e,0xa9,0x74,0x02,0x25,0xc0,0x0c,0x10,0x31,0xf0,0xa7,0xcb,0x01,0xed,0x43,0x70,0x15,0xe6
+.byte 0xda,0x01,0xb4,0x7a,0x13,0xbc,0xf1,0x57,0x34,0xb1,0xb7,0xb3,0x26,0x18,0x5f,0x42,0x6b,0xcb,0x78,0x25,0x48,0xe9,0xe6,0xe8,0xf5,0x45,0xa2,0x61,0x97,0x10,0xa5,0x7e,0x7a,0x48,0xf3,0x23,0xa5,0x88,0xc0,0xc4,0xc7,0x3b,0x5c,0x0c,0xfc,0xe0,0xf4,0x68,0x64,0xc6,0x9f,0xd9,0x17,0xcb,0xe5,0xba,0x4a,0xa4,0xe0,0x27,0xf8,0x2b,0x4e,0x67
+.byte 0x13,0xab,0xd2,0xce,0xbc,0x8d,0xdf,0x6e,0x49,0xaf,0x72,0x8a,0x51,0xa1,0x78,0x38,0x0a,0x58,0x2e,0x72,0xec,0x94,0x70,0x8d,0xdf,0x0b,0x5a,0x52,0x81,0xb1,0x9b,0xda,0x2c,0xd2,0x85,0xbb,0x8f,0xb0,0x99,0x64,0x24,0xbe,0x03,0xd9,0x92,0x8d,0x29,0xf3,0x41,0x9c,0xd6,0xef,0xef,0xb2,0x5c,0x22,0x90,0xff,0x27,0x4d,0xb3,0x91,0x72,0x9f
+.byte 0x42,0xca,0x66,0xc5,0x66,0xb7,0x50,0x3e,0x83,0x6f,0x2d,0xe3,0x7b,0x2a,0xc4,0x5a,0x93,0x92,0x80,0xdb,0x1a,0xdd,0xef,0xfd,0x96,0xcb,0x6a,0xd8,0x4a,0xc5,0x6e,0x36,0x4a,0xe4,0x10,0x15,0xb3,0x12,0xb4,0xd9,0x9e,0x37,0x48,0x96,0xcb,0xe5,0x3a,0x4f,0x57,0xa6,0x46,0x2f,0xd3,0x06,0xb8,0x61,0x1c,0x17,0x3a,0xb8,0xad,0x40,0x50,0x57
+.byte 0x10,0xd9,0xd0,0xe9,0x1b,0xe3,0x18,0x8c,0xc4,0xfa,0x08,0x8d,0x82,0x3c,0x22,0x22,0x1b,0x97,0x64,0xa6,0x8b,0x7c,0x70,0x2b,0xa0,0xd8,0x4c,0x64,0xcf,0xbc,0x49,0x78,0xcb,0x92,0x0f,0xe1,0x60,0x12,0x4e,0x92,0x0d,0xaf,0xa4,0x1f,0xe0,0x2a,0xa5,0x69,0xc6,0xa1,0x91,0x5c,0xdd,0xb8,0xae,0xfa,0xc5,0xb9,0x18,0x31,0x81,0x32,0x6e,0x97
+.byte 0x44,0x2a,0xda,0x58,0xcd,0x9e,0x0d,0x57,0xe0,0xe3,0x5f,0x7b,0x04,0xd8,0xc8,0x68,0xf5,0xa2,0xac,0x0c,0x29,0xf0,0x7e,0xff,0x32,0xfb,0x53,0x1a,0xc2,0xe3,0xae,0xa5,0xe4,0x9c,0x50,0xaf,0xf4,0xde,0x0b,0xdd,0x4d,0xfa,0x65,0x3c,0xbe,0x3c,0xb8,0xda,0x88,0xd9,0x6c,0x55,0x58,0xe1,0x4d,0x00,0xa8,0x1e,0xe2,0x3a,0x9c,0x53,0x9b,0xca
+.byte 0xb7,0x5d,0x3a,0x83,0xe0,0xbb,0x95,0xc4,0xd5,0x45,0x48,0xdc,0x12,0xab,0x24,0xfc,0x5d,0x91,0xe1,0xc8,0x0a,0x5c,0x10,0xc4,0xc9,0xaf,0xb6,0x54,0x80,0xfd,0xa0,0x70,0xb9,0xab,0xdf,0x34,0x9f,0x5c,0xff,0xde,0x8e,0xa0,0x0b,0x21,0xcf,0x28,0xc4,0xdf,0x67,0xb5,0xc0,0x20,0x49,0x0c,0x7e,0xe6,0xf7,0x41,0x6b,0x75,0xd9,0x1d,0x3b,0x49
+.byte 0xb7,0x4f,0x01,0xd1,0x20,0x62,0x15,0x1e,0x9f,0x16,0xb0,0xbd,0x30,0x09,0x05,0x00,0x0f,0x25,0x5a,0x37,0xe9,0xa6,0xc6,0xef,0xe5,0x39,0x2b,0xd7,0x6b,0xc5,0x96,0xd2,0xad,0x46,0xaf,0xd3,0xc0,0xfd,0xea,0xff,0x4c,0xaa,0x44,0x48,0x9a,0xdb,0x99,0x44,0x3f,0x4a,0xf0,0x3f,0x81,0x75,0xf2,0x79,0x31,0x3c,0xed,0x56,0xc6,0xf0,0xf1,0x8c
+.byte 0xdb,0x1d,0x6c,0x6c,0xcc,0xfb,0xc2,0x30,0xf6,0x24,0x14,0x69,0xc4,0x89,0x4d,0xd0,0x10,0x77,0x37,0x00,0xe8,0xc9,0xf2,0x32,0xf1,0x43,0x8b,0xe1,0x09,0xc4,0x59,0x17,0xf9,0x20,0x2b,0x01,0x76,0x20,0xb8,0x03,0x84,0xf6,0xd7,0x2e,0xef,0x20,0xa6,0xfa,0x8b,0x74,0x7f,0x4a,0x14,0x33,0xad,0xac,0x45,0x66,0x18,0x2b,0x6b,0xd2,0xb8,0x20
+.byte 0x1a,0xff,0xca,0x25,0x69,0xfd,0xba,0x4b,0x5b,0x9c,0x38,0x35,0x4c,0x30,0xa2,0x24,0x3d,0xbb,0xd4,0xf3,0x67,0x24,0xa5,0x93,0xc6,0xf5,0xb2,0xb4,0xa5,0x04,0x53,0xb6,0xe4,0xc7,0xdc,0xf1,0xe5,0x43,0xb7,0x73,0xaa,0xab,0x5c,0xea,0xcb,0xf1,0xeb,0x5b,0x04,0x7a,0xff,0x0f,0x5e,0xb4,0xd3,0x2a,0x39,0x50,0x1b,0x54,0x1f,0x32,0xd7,0x7c
+.byte 0xea,0x3f,0xee,0xa5,0xc8,0x46,0x48,0x7e,0x75,0x60,0x7a,0x42,0x42,0xd3,0x15,0x07,0x69,0x46,0x1c,0xe2,0x21,0x31,0x94,0x31,0x24,0x9e,0x39,0xab,0x7a,0xf9,0xc2,0x0b,0x2d,0x6b,0x55,0xa3,0x36,0xb2,0x65,0xf2,0x17,0x08,0xde,0x15,0x83,0x07,0x36,0x12,0x54,0x8f,0x0b,0x23,0xa8,0x7e,0xb5,0x57,0x1c,0x9e,0x29,0xd7,0xd4,0x9b,0xc1,0xf6
+.byte 0x94,0x23,0xf3,0x92,0xbf,0xba,0xc8,0xf5,0x78,0x3e,0x67,0x48,0x14,0x3b,0xd4,0xe9,0x8f,0x78,0xc1,0x4b,0x9a,0x59,0x08,0xaa,0x50,0xf4,0x9d,0xc4,0xc3,0x2c,0xbc,0x56,0x2c,0x13,0x30,0x75,0xfb,0xed,0x48,0xab,0x90,0xec,0x64,0x18,0xb5,0xd5,0xb5,0x7f,0xc1,0x7f,0x83,0xf2,0xdb,0xae,0xde,0xf5,0xb5,0x29,0x03,0xbe,0x80,0xb1,0x5d,0x97
+.byte 0xd3,0x7a,0xa4,0xd0,0xe0,0xce,0x04,0xda,0xaa,0x82,0x19,0xc9,0x02,0xb7,0x1c,0xe1,0x66,0xd9,0x3e,0x86,0x6d,0xb5,0xd1,0x35,0x63,0x8e,0x4b,0xc6,0x58,0x41,0xf9,0xb7,0xba,0xf3,0x06,0x91,0xb7,0xa2,0xfb,0xb5,0x5f,0x53,0xf3,0xe0,0xc1,0xf6,0x91,0x66,0xc7,0x93,0x3a,0x0a,0x72,0xb1,0xed,0x36,0x9d,0xde,0x21,0xdd,0x7d,0x0a,0x7b,0x35
+.byte 0x1f,0xc3,0x56,0xde,0xbb,0xcb,0xb2,0x0a,0xb6,0x84,0xce,0xa1,0xc6,0x1a,0x46,0x2f,0x9f,0x48,0xd5,0x98,0x73,0xa4,0xbd,0xbd,0xa3,0xe9,0xc9,0xc4,0x64,0x89,0xb7,0x9c,0x97,0x7c,0x2f,0x88,0x22,0xe4,0x4b,0x71,0x3d,0x2a,0x47,0xee,0xf8,0xfe,0xe0,0xf7,0x03,0x14,0xe6,0x7c,0x9e,0x57,0xbb,0x8e,0xf5,0xea,0x63,0xfc,0x5b,0x18,0x3b,0xa2
+.byte 0xa1,0x4a,0x28,0x82,0x37,0x77,0x5b,0xc4,0xd3,0xc1,0xf2,0x87,0x13,0x2b,0x2a,0xc8,0xac,0x70,0xe1,0x82,0x38,0x9c,0x12,0xa0,0xc4,0x9e,0x6b,0xac,0x33,0x8a,0xe9,0x31,0x6f,0xa1,0x76,0x94,0x48,0xcf,0xbc,0x78,0x22,0x82,0x6a,0xb0,0xb9,0x49,0x71,0xdb,0xde,0x8b,0x90,0x09,0x82,0x4d,0x79,0x17,0xe8,0xcf,0xd8,0x50,0xc3,0x08,0x07,0x81
+.byte 0x5f,0x9a,0x72,0xce,0x0a,0xe4,0x29,0xc9,0xdd,0x95,0x67,0x58,0xa1,0x14,0xec,0xcf,0x2f,0x29,0xcf,0xce,0xb3,0x35,0x54,0x77,0x67,0x56,0xec,0x95,0x68,0xee,0xbf,0x9c,0x9f,0x74,0x78,0x12,0xd5,0x30,0x83,0x28,0xd5,0x36,0x96,0x57,0xa0,0x8d,0x1c,0x99,0x19,0x04,0xaf,0x25,0xe5,0x71,0x83,0x88,0xb0,0x74,0x38,0xdd,0x8a,0xff,0x39,0x7a
+.byte 0xfd,0x34,0x8f,0x9c,0x67,0xa8,0xc8,0x6f,0x13,0x5d,0xf2,0x5b,0x22,0xd3,0x8e,0x63,0x51,0x58,0x9b,0xfc,0xaa,0x89,0x65,0x4e,0x36,0xc4,0xa7,0xef,0x98,0xf9,0xaf,0xcd,0x35,0x8c,0x16,0xbc,0x70,0x4f,0xcd,0x71,0x2a,0xf4,0x13,0xb3,0x3d,0xa3,0x92,0x71,0x45,0xe5,0x9a,0x45,0xbd,0xc5,0x1d,0x82,0x60,0x3a,0x97,0xf3,0x0f,0x96,0x21,0x3d
+.byte 0xe5,0x6e,0xfb,0x9d,0x9b,0xeb,0x15,0xc2,0xa6,0x73,0x76,0xf2,0xcd,0xec,0xfd,0x0f,0xf4,0x3f,0x46,0xc9,0x9c,0x73,0xa1,0x21,0x08,0xdc,0x31,0x00,0xaa,0x95,0x07,0xf0,0x3d,0x51,0x57,0xfa,0x6b,0xc3,0x8e,0xe9,0xa4,0x65,0xdc,0xff,0x57,0xb9,0x1f,0x4f,0xc6,0x6d,0x03,0x00,0xa7,0x19,0xb8,0x24,0xb5,0x3d,0x87,0xcb,0x84,0xb7,0xf5,0xfe
+.byte 0x51,0x16,0x5b,0xc7,0xed,0x4b,0xff,0xa3,0x66,0x17,0x93,0x60,0x69,0x84,0x8c,0x95,0x74,0xa7,0x30,0x2d,0x09,0xf7,0x4e,0x0e,0x2f,0x99,0xda,0x46,0x34,0x0f,0x93,0x90,0x97,0x4c,0xa6,0x25,0x15,0xb8,0x6f,0x1d,0xd5,0xe1,0xc1,0x39,0x50,0xfd,0xd5,0x79,0x4f,0x04,0x2f,0x76,0x50,0x3f,0x67,0x56,0xad,0x02,0x82,0x30,0x1a,0xaa,0x6e,0xe2
+.byte 0x05,0x6a,0x93,0xb7,0xbe,0xde,0x84,0xce,0xd8,0x53,0xed,0xad,0x95,0xab,0x45,0x1f,0x4c,0x3b,0x22,0x36,0x27,0x45,0x19,0xa4,0x7f,0x12,0x20,0x6c,0x9d,0xeb,0xd2,0xfe,0xd6,0x7d,0x25,0xf9,0xe3,0x64,0x77,0x56,0x89,0x12,0x57,0x80,0xd5,0x40,0xbb,0x2a,0xcc,0xac,0x34,0x8e,0x87,0xfd,0x58,0xc3,0xbd,0x92,0x48,0xd8,0x7f,0xc4,0x39,0x6a
+.byte 0x4e,0x1c,0x50,0x93,0xef,0xae,0x81,0x93,0x50,0x95,0x6e,0x46,0x7c,0xf5,0x27,0x44,0x6c,0x21,0x06,0x49,0x89,0x7e,0xf4,0xfa,0x08,0xa5,0xbc,0x0a,0xbd,0xb6,0x7b,0x55,0xac,0x87,0x19,0x33,0xfa,0xab,0xf3,0x15,0xc9,0x1b,0x83,0xf2,0x41,0xf1,0x26,0x6f,0xdf,0x15,0x60,0xdb,0xa6,0x03,0x43,0x3e,0x34,0x7a,0xa9,0xb1,0x38,0x57,0xe4,0x09
+.byte 0x1a,0x4a,0xd8,0x6e,0x28,0xee,0x7d,0x74,0x54,0x03,0xb3,0x29,0x24,0xb3,0xf0,0xc6,0x20,0x7c,0x47,0x01,0x66,0x36,0x7a,0x14,0x18,0x09,0xd6,0xaa,0xa6,0x82,0x5b,0xe4,0x0a,0xf9,0x41,0x52,0x3b,0x56,0xa2,0xf8,0xa2,0xa1,0x2b,0xe0,0x0d,0x1f,0x5b,0xe4,0x0e,0xe1,0x94,0x84,0x6f,0xed,0x2e,0x11,0xfa,0x4a,0xbd,0x41,0xf4,0x3c,0x8c,0x7e
+.byte 0x94,0x46,0xec,0x79,0x81,0xb0,0x36,0xfd,0x9c,0x73,0x0f,0x84,0x1a,0x59,0x4e,0x1b,0xd5,0xd1,0x0d,0xff,0xfd,0xb7,0xfb,0x73,0x35,0x8a,0x66,0xed,0xf3,0xee,0x6d,0xf7,0x86,0x0a,0xb9,0xc0,0xf1,0xa3,0xb7,0x32,0x49,0x01,0xe8,0xcd,0xfe,0x82,0x7b,0xf6,0x46,0xd8,0x73,0x47,0x8b,0x7b,0x6e,0x31,0x92,0x0f,0x4b,0x16,0x11,0x86,0x1d,0x02
+.byte 0x5d,0x12,0x79,0x59,0xdc,0x8c,0xaa,0x1b,0xc1,0x75,0x63,0xb2,0xd6,0xbf,0x19,0xb0,0x81,0x70,0x34,0x12,0xd2,0x09,0xbe,0x6d,0xa1,0x31,0x77,0xd2,0x9b,0x59,0xdc,0xcb,0x67,0xb5,0x14,0xcd,0x37,0x31,0x2c,0xa6,0x17,0x58,0x2b,0x24,0xfc,0x2a,0x9e,0x8f,0x38,0x38,0x7a,0x80,0xda,0x8b,0x54,0x1d,0xc9,0x99,0xc7,0x1f,0x98,0x7a,0x1f,0x32
+.byte 0x23,0x1c,0xb5,0x6e,0x53,0xd3,0x61,0xe7,0x78,0x19,0x6c,0xd5,0x2f,0x85,0xde,0xd1,0x67,0x6b,0x9b,0xa1,0x09,0x87,0x5e,0x89,0x5e,0x89,0x21,0x36,0xf2,0x94,0xc1,0xfd,0x6c,0x4e,0xd9,0x6b,0xd2,0xb1,0x1b,0x48,0x37,0x9a,0x7b,0xc9,0x52,0xfd,0xe2,0x6d,0x07,0x19,0xf2,0xa5,0x69,0xdc,0x0b,0x52,0x8f,0xb3,0x87,0x03,0x1a,0xd8,0x43,0x20
+.byte 0x68,0xcf,0x08,0xcc,0xce,0x37,0xf6,0x96,0x7f,0x03,0x62,0xb2,0xce,0x6a,0xfb,0x22,0x54,0xd6,0xfc,0x84,0x5c,0xf5,0x55,0x32,0x36,0x77,0x1d,0x15,0x6a,0x2c,0x3a,0x01,0x34,0xff,0x5b,0x7f,0x3f,0xab,0x97,0x8f,0xbd,0x1d,0x07,0xb9,0x47,0xb1,0xcc,0xc0,0xdf,0x17,0x38,0x54,0x07,0xc0,0x1b,0xb9,0xa2,0x29,0xa6,0x25,0x73,0x32,0x4d,0x5e
+.byte 0x51,0x60,0xb3,0x27,0xe5,0xb6,0xdb,0x56,0x81,0x95,0x03,0x7e,0xca,0xc6,0x15,0x8f,0x48,0xd4,0xac,0x71,0x41,0xdc,0x9c,0x86,0x5d,0xd8,0x90,0x90,0x54,0xdd,0x3d,0xf3,0xa8,0xbb,0xe5,0x55,0x69,0x26,0xdf,0xd1,0x8e,0x75,0x2a,0xe4,0xfe,0xe0,0x80,0x1d,0x6b,0xd2,0x8a,0x06,0x49,0x4e,0x60,0xf8,0xbd,0x3d,0x99,0x27,0x80,0x27,0x42,0x66
+.byte 0x01,0x32,0xe1,0x9e,0xa6,0xde,0x7b,0x14,0xa4,0x49,0x68,0x70,0xbe,0xa4,0xe1,0x44,0x2e,0xce,0xa3,0xe9,0x1d,0x7a,0xbd,0xf1,0xe4,0x25,0x11,0x47,0xd8,0xaa,0x32,0x34,0xf8,0xca,0x3d,0xec,0xf3,0x5d,0x8a,0x55,0xe7,0xd4,0x7c,0xfb,0xcf,0xe7,0xa6,0x13,0xaa,0x16,0x5f,0xaa,0x02,0x19,0xdd,0xf1,0xf8,0x5c,0xb2,0x1e,0x68,0x9a,0x21,0x93
+.byte 0xd1,0x38,0x31,0xbb,0x26,0x76,0x44,0xf8,0x84,0x3b,0xf5,0xd1,0x52,0xbe,0x1b,0x8e,0x4d,0xa0,0xb4,0x4a,0x5a,0x7e,0x89,0xe5,0x36,0xb0,0x76,0x77,0xc5,0xc2,0x22,0x73,0xc2,0x19,0x12,0x7f,0xdf,0x9c,0xb8,0xc0,0xf5,0x0e,0xd5,0xa3,0x55,0xae,0x61,0xf8,0xf1,0x6b,0x79,0xc8,0x2e,0xbc,0xa5,0xef,0xd4,0xb1,0x84,0x0c,0x15,0xc4,0xed,0xb3
+.byte 0x18,0x29,0xd6,0x31,0x83,0x79,0x30,0x1a,0x8f,0xf0,0x3b,0xe9,0xd1,0xf2,0x1d,0xec,0xcb,0xe8,0xc5,0x1c,0xb5,0xcb,0x8e,0x01,0xd1,0xb2,0x86,0x43,0x33,0x95,0x70,0x7e,0x75,0xa9,0xa1,0xe7,0xcb,0xd9,0xf4,0xd3,0xe1,0xe2,0xe9,0x46,0x21,0x20,0x3b,0xe9,0x48,0x1c,0x3f,0x93,0x57,0x31,0xeb,0x15,0x9c,0xa7,0xa6,0xcb,0xb5,0xb7,0xa7,0x24
+.byte 0xbe,0x66,0x4c,0x92,0x7c,0xe8,0x8e,0x3f,0x9c,0xa9,0xd7,0xad,0x73,0x68,0x19,0x19,0xd4,0xb5,0x57,0x82,0xdc,0x67,0x3c,0xec,0xac,0x06,0xec,0x86,0x9b,0x65,0xff,0xbb,0xc3,0x90,0x48,0xdb,0x52,0xcc,0xa4,0xf5,0xdf,0x2c,0xc5,0x5a,0xe3,0x30,0xed,0xad,0x37,0x40,0x8c,0xaa,0x32,0x4f,0x94,0x1e,0x14,0x59,0x48,0x1d,0xd3,0xaf,0x80,0xe7
+.byte 0xcf,0x6b,0xa7,0x70,0xe7,0x98,0x22,0x4b,0x40,0x02,0x0c,0x29,0x09,0x0a,0x53,0xf7,0xd4,0xeb,0xbb,0x75,0xb4,0x30,0x1c,0x67,0xea,0xd2,0xb5,0x40,0xfe,0x57,0x2c,0x3c,0x44,0x8d,0x8d,0x02,0x78,0xf0,0x76,0x8f,0x92,0xab,0xb4,0xc9,0xc0,0x2f,0xf5,0xde,0xa7,0x09,0x14,0xf1,0xe5,0x34,0xeb,0x86,0xfa,0xcf,0xcc,0x85,0x1c,0x9c,0xa6,0xe1
+.byte 0x72,0x9e,0xc1,0xe4,0x74,0xc4,0x96,0x5d,0xf4,0x4b,0x23,0x4f,0xa5,0x32,0xff,0x38,0x21,0x8f,0x43,0xe5,0x96,0x20,0x3c,0x78,0xb8,0xb4,0xcd,0x29,0x62,0x84,0x59,0xb5,0xb4,0x57,0x07,0xa8,0x79,0x77,0x21,0xf4,0x82,0xa7,0xb1,0x36,0xee,0x16,0x8e,0xb5,0x9a,0xf7,0x03,0xac,0x64,0x03,0x20,0x48,0x24,0xbc,0xbb,0xec,0x50,0xed,0xa1,0xf3
+.byte 0x67,0xd9,0x34,0xe1,0x0c,0x0b,0xc3,0xd0,0x46,0x0b,0x55,0x85,0x59,0x3c,0xb4,0x7d,0xd0,0xc2,0xe7,0x95,0x24,0x1f,0x53,0x76,0xf1,0x81,0x4a,0x61,0x6a,0x2e,0x3b,0x3f,0x92,0x14,0x7c,0xe0,0x33,0x7f,0xb4,0x85,0x92,0x78,0x0c,0x0b,0xe7,0xbd,0x7a,0x08,0x31,0x7d,0x47,0x3b,0xfa,0xdd,0x90,0x9e,0xf0,0xa9,0xd1,0xa7,0x7c,0x2a,0x37,0xb1
+.byte 0x23,0x71,0x34,0xa0,0x63,0xfb,0x9e,0x8f,0x39,0x00,0xa0,0x09,0xd4,0x1f,0xf4,0xba,0x2d,0xc1,0xac,0x6c,0x94,0x18,0x56,0x3e,0x89,0x92,0x63,0x10,0x5e,0xfe,0x76,0xec,0x4e,0xb6,0x5d,0x59,0xf9,0x94,0x46,0x4f,0xda,0xd5,0x3e,0x6c,0x48,0x49,0x7e,0x7c,0x77,0xe7,0x7e,0x22,0x31,0xb5,0x9d,0x15,0xd3,0x08,0x24,0xdb,0x67,0x98,0x6b,0xfc
+.byte 0x45,0x54,0x85,0x29,0x9a,0x47,0xa5,0x60,0xe2,0x46,0x36,0x45,0x16,0x54,0xd6,0xb1,0x5c,0x38,0x45,0xf8,0x43,0x28,0x58,0x81,0xc9,0x57,0x10,0xda,0x3b,0xfc,0x3e,0xe4,0xf4,0xb2,0x16,0xb6,0x16,0x1d,0xa4,0x68,0xa6,0xe0,0x36,0xdb,0xe2,0x19,0x1c,0xce,0x9f,0x94,0xa9,0x94,0xad,0x20,0xcb,0x17,0xd0,0x92,0x37,0x75,0x88,0x0d,0xaf,0xdf
+.byte 0x98,0x6d,0x19,0x9e,0x8e,0x61,0xe4,0x8c,0xfc,0x27,0x27,0x6a,0xa7,0xa4,0x66,0x7f,0x08,0x03,0xef,0x5c,0x4a,0xb7,0x89,0xa1,0xae,0xe8,0x70,0x3f,0x13,0x27,0x0a,0x7d,0x5d,0x5e,0x2b,0x69,0xb5,0x98,0x1f,0x25,0x1e,0x41,0xff,0x46,0x5a,0x25,0x1f,0xb4,0x90,0x8e,0x81,0x91,0x19,0x63,0x10,0xd4,0xa9,0xdf,0x3b,0xae,0xe6,0x63,0x1a,0xdc
+.byte 0x09,0x5f,0xac,0xaa,0xb8,0x6b,0xbd,0x6a,0x90,0x70,0xce,0x2c,0x63,0x6d,0x48,0x78,0xca,0xc1,0x59,0x94,0xe2,0xc7,0x89,0x17,0x73,0xfa,0x73,0x34,0xb7,0xd3,0x9c,0x4e,0xd8,0xac,0x18,0x80,0x25,0xbf,0xbe,0x75,0x0a,0x9a,0x05,0x5e,0x54,0xcb,0xba,0xab,0xca,0x7f,0x96,0xf7,0x26,0x8c,0x82,0xe0,0x23,0xa5,0x86,0xb5,0xdf,0x31,0xd0,0x2f
+.byte 0xe3,0x66,0x96,0x83,0xd2,0x04,0x43,0x8a,0x28,0x59,0x49,0xdc,0x11,0x38,0xd9,0x5f,0xc2,0x31,0xaa,0xa8,0x1a,0xff,0x57,0xf1,0x84,0x18,0x28,0xe8,0x04,0xae,0x98,0xa4,0x17,0xc4,0x35,0x75,0xf5,0x37,0xf5,0x27,0x3e,0x7e,0x32,0xa4,0xcb,0xd4,0x43,0x59,0x02,0x63,0x7b,0x7c,0x9d,0xa7,0x61,0x12,0xf7,0xdc,0x12,0xe0,0x07,0xac,0x96,0xf3
+.byte 0x71,0x43,0xe5,0x30,0xe0,0x4c,0x51,0x2a,0x19,0xf5,0x79,0x59,0x5a,0xc5,0x74,0xfa,0x54,0x18,0xb4,0xb1,0xfb,0x4b,0x9b,0xf8,0xe4,0xa4,0x63,0x25,0xc3,0x84,0xeb,0x2e,0xa1,0xf8,0xf8,0x7b,0x25,0x6a,0x7d,0x14,0x38,0x06,0xeb,0xae,0x9f,0xa5,0x80,0x9a,0x8a,0xb6,0x46,0x95,0xdf,0x52,0x11,0xd4,0x30,0xcc,0x11,0x8f,0x4a,0x5e,0x56,0x26
+.byte 0x60,0x3d,0x5f,0x0b,0x04,0x94,0xcd,0xca,0x1d,0x6b,0x83,0x51,0x83,0x8d,0xf8,0x33,0x4a,0x91,0x00,0xa4,0xf5,0x44,0x5b,0xad,0xa0,0x4a,0x72,0xaf,0xe6,0x4a,0x0d,0x1e,0x9f,0x18,0x6b,0xb4,0xdf,0x85,0x61,0x2a,0x3b,0xe1,0x4c,0xaa,0xc3,0x17,0xef,0x51,0x9f,0xae,0xb5,0xca,0xaa,0x6c,0xd9,0xa1,0xf5,0xa3,0x6f,0x1c,0xca,0xb3,0x37,0xda
+.byte 0x27,0xea,0xcb,0xb7,0x36,0xb2,0x11,0xda,0x9f,0x07,0x78,0xaa,0x6c,0xad,0x63,0x9b,0x49,0x6b,0xfe,0x1f,0x93,0x82,0x73,0xc9,0xc8,0xf6,0x68,0x54,0x50,0x77,0xba,0x78,0xc7,0x82,0xee,0xbd,0x97,0x66,0xb9,0x22,0x49,0x0d,0x7a,0x1f,0x0f,0x4e,0xe5,0x02,0x8b,0xa6,0x1b,0x11,0xfc,0xa6,0x37,0x2a,0x5c,0x66,0xaf,0xac,0xa5,0x9f,0xbf,0x26
+.byte 0x98,0x9b,0x25,0x44,0x48,0x09,0xe6,0x76,0xb9,0x08,0xf1,0x37,0xcf,0x86,0xc9,0xdf,0xa8,0xf3,0x88,0x2f,0xc1,0x33,0x15,0x95,0x59,0xf7,0x9b,0xf2,0x48,0x76,0xcb,0xd0,0x31,0xe4,0x27,0x74,0x2d,0x6e,0xd2,0xc3,0x29,0xea,0xef,0xff,0x4e,0x3d,0xda,0x3e,0xef,0x94,0x94,0x40,0xcd,0x93,0xcf,0xb8,0x56,0x29,0xf8,0x20,0x20,0xa3,0x66,0x83
+.byte 0xba,0xc8,0x4f,0xe6,0x22,0x96,0xb5,0xb2,0x44,0x75,0x55,0x98,0xed,0x11,0xd0,0x58,0x50,0x26,0xf1,0x4a,0xf6,0x80,0x5c,0x17,0x92,0xba,0xc2,0xd6,0x68,0xd4,0x7a,0x4f,0xdf,0x16,0x97,0xbd,0xad,0xd7,0x1b,0x0c,0xe5,0x23,0xa9,0xaa,0xf4,0x1c,0x8d,0xec,0xbf,0xf0,0xb5,0xaa,0x49,0xfd,0xf1,0x31,0x9b,0xf9,0xe9,0x21,0xa1,0x20,0xab,0xbe
+.byte 0x56,0x8c,0xf2,0x85,0xdc,0x1f,0xea,0x25,0xce,0xf5,0x6c,0x18,0x7d,0xc4,0x1a,0x01,0x08,0x01,0xed,0x02,0xa8,0xac,0x7f,0x74,0x2c,0xd7,0x28,0x25,0x6e,0x68,0x19,0x38,0x8d,0x20,0x51,0x8f,0x38,0x8b,0x03,0x36,0xae,0x50,0x35,0x28,0x65,0x7e,0x15,0x2a,0x80,0x2c,0xae,0xcd,0xb3,0xb6,0x91,0xf1,0x8c,0xf2,0x8c,0xc5,0xce,0x3e,0x3a,0x97
+.byte 0x5a,0xff,0xe1,0x37,0x13,0xf7,0x6b,0x07,0xb2,0xaa,0xaa,0x57,0x18,0xb7,0xb2,0x19,0x52,0xbf,0x59,0x0b,0x6f,0xba,0x56,0x54,0x14,0xac,0x21,0xfd,0x7d,0x03,0x4b,0x0b,0x39,0x54,0xba,0xf9,0xba,0x73,0xcd,0x67,0x13,0x30,0xca,0x19,0x80,0x4f,0x18,0xb4,0x75,0x2a,0xec,0x78,0xa7,0xd0,0x5c,0x53,0xe2,0x43,0x2c,0x08,0x5f,0x5c,0xe6,0x60
+.byte 0xde,0x04,0xf6,0x75,0xca,0x35,0x3b,0xf6,0x68,0x53,0x60,0xc0,0xed,0xb0,0x15,0xa1,0xa4,0x89,0x23,0x34,0x49,0x35,0xd2,0x78,0x4b,0x8f,0x7c,0x8d,0x59,0x22,0x9f,0xad,0x72,0x47,0x5b,0xde,0xf2,0x09,0x08,0xa0,0x8d,0x5f,0x4d,0xc3,0xd1,0x83,0x17,0xbc,0x39,0x8e,0xa5,0x53,0xaa,0xe3,0x31,0x03,0x93,0x14,0xb4,0x57,0xf0,0xdf,0x54,0x1d
+.byte 0x79,0x4d,0x21,0x1a,0x8f,0x3f,0x6e,0x07,0x41,0xcc,0x2d,0x94,0x55,0x4e,0x50,0xfd,0xac,0xe3,0xef,0xa7,0x50,0x3b,0x3c,0xda,0x32,0x25,0xee,0xd9,0x01,0x37,0x8e,0xb3,0x23,0xc5,0x5e,0x12,0x88,0x6d,0xd5,0x41,0xfd,0x3f,0xfa,0x75,0xb8,0xcb,0x82,0x10,0x81,0x38,0x1b,0x10,0x2d,0x2c,0x6b,0x62,0xa1,0x7c,0xd1,0x75,0xd8,0x8c,0x0c,0x2f
+.byte 0xe8,0x97,0xff,0x18,0xb3,0x12,0xa2,0xef,0x6c,0xc5,0x79,0x9f,0x64,0xf3,0xc7,0xdc,0xdb,0x54,0xa4,0x25,0xc7,0x30,0xfb,0x6c,0x5a,0x50,0x24,0xf9,0xb6,0xc9,0xe7,0xda,0x78,0xcc,0x1b,0x5e,0xf3,0xe7,0x32,0xd8,0x36,0x47,0x10,0xe5,0x2c,0xeb,0xea,0xf7,0x25,0x30,0x93,0x64,0x88,0xc8,0x59,0xf8,0x5c,0x02,0x43,0x4c,0x23,0x8e,0x1c,0x42
+.byte 0xe4,0x36,0x39,0xbf,0xba,0x8b,0xe3,0x53,0x01,0x32,0x0d,0x89,0xc2,0xea,0x35,0x94,0xf1,0x0d,0x29,0x45,0x08,0x07,0x15,0xcb,0xd7,0x3e,0x4d,0x9f,0x04,0xd8,0x18,0x8a,0x56,0xa3,0xb1,0x1c,0x46,0x19,0x8b,0xd0,0x51,0x30,0xf3,0xca,0x52,0x2a,0x16,0xc4,0x90,0xc1,0x00,0x50,0x87,0x8b,0x4c,0x71,0x61,0x48,0x69,0xb2,0xf1,0x33,0xaa,0x79
+.byte 0x81,0x8b,0x36,0x33,0x19,0x41,0x6b,0xc1,0x91,0x40,0xf2,0xcc,0x1d,0x83,0x09,0xab,0xcc,0x6f,0x6c,0x54,0x91,0x62,0x80,0xac,0xe6,0x1f,0xcd,0x5d,0x05,0x2b,0xe5,0xac,0xbc,0xd6,0x1b,0x8b,0xef,0x95,0xa0,0xf3,0xfe,0x8e,0x4d,0x32,0x77,0xe8,0x02,0x8f,0x44,0xad,0xc4,0x40,0xc3,0x99,0x68,0x81,0x47,0x15,0xbd,0x3b,0x8f,0x0b,0x9b,0x3a
+.byte 0xb3,0x9d,0x8f,0x3d,0x86,0xd1,0x89,0x5f,0x67,0x19,0x33,0x2d,0x18,0x64,0x0e,0x3a,0x13,0xa4,0xe9,0xb4,0xc9,0x90,0x09,0x6a,0xcb,0x5d,0x0d,0x83,0x13,0x04,0x29,0xe5,0xa5,0xf4,0x00,0x56,0xf4,0x80,0x96,0x33,0x93,0xe4,0x9b,0xc4,0x6e,0x38,0xbf,0x0a,0xe0,0xee,0x8c,0x89,0x5d,0x60,0x36,0x7e,0x69,0xc2,0xc7,0x28,0x6f,0x2b,0x97,0xfb
+.byte 0xb3,0x5b,0x82,0xe8,0x9a,0x36,0x44,0xd7,0x1f,0x9b,0x1b,0xd0,0x14,0xe4,0xd4,0x0d,0x35,0xcd,0xee,0x88,0x50,0x37,0x5c,0x88,0x09,0xa5,0x16,0x4d,0xe1,0xbc,0xe8,0x79,0x8f,0xa9,0x18,0xb8,0x43,0xb4,0xd7,0x32,0xcd,0x26,0xdd,0x78,0x29,0x59,0xad,0x29,0xe3,0xe0,0xe7,0xcf,0x16,0x03,0xc6,0x8a,0xb6,0xa2,0x09,0x9a,0x6e,0x90,0x7b,0x0c
+.byte 0x9d,0x20,0xb6,0xc4,0x28,0x3f,0x44,0x06,0xa9,0x45,0x72,0x27,0xa7,0x56,0x3f,0x07,0xff,0x13,0xd9,0x80,0xda,0xbd,0x25,0xad,0xd3,0x74,0x2c,0xd8,0xd2,0x93,0xa5,0xda,0xbc,0x5f,0xa5,0xde,0xb7,0x3a,0xf0,0xd2,0x17,0xb1,0xc3,0x70,0x2a,0x85,0xde,0xf0,0x97,0x7b,0x96,0xb2,0x0e,0x45,0x7f,0x63,0xd4,0x94,0xd8,0x78,0x05,0xcf,0xea,0xb3
+.byte 0xfb,0x7a,0x79,0xb5,0x91,0x53,0xb8,0x8c,0xa2,0x03,0xf4,0xc3,0xed,0xf0,0xab,0x33,0x5c,0x6e,0xcd,0xbd,0x73,0xe3,0xe9,0xd0,0x83,0x2a,0x2a,0x68,0x32,0xf1,0x69,0x4f,0xd0,0x8b,0xe8,0xa1,0x7d,0x5b,0x0f,0x69,0xc2,0x33,0xbf,0xc1,0x54,0x29,0x47,0xed,0x9f,0xdb,0x35,0x0a,0x3d,0x2b,0x9d,0x8b,0x91,0xb6,0xe0,0xbc,0x53,0xba,0xb7,0xcd
+.byte 0x2c,0xd9,0xeb,0x81,0xa0,0x2e,0x14,0x6e,0xdc,0xe1,0x90,0x36,0x14,0x9d,0xa8,0x8b,0x6b,0x1b,0xac,0x4c,0x09,0x8b,0x1a,0x87,0xf4,0x66,0xf6,0xfb,0x62,0x92,0x13,0xcf,0xb2,0x96,0xf0,0xc9,0x8b,0x12,0x99,0xf1,0x16,0xae,0x5c,0x27,0x24,0xa8,0xfd,0xb3,0x4c,0xc2,0xe6,0x3f,0xd2,0xc6,0x0c,0xf2,0x65,0x4e,0xdf,0xf1,0x06,0xb8,0x99,0xc4
+.byte 0x3a,0x35,0xba,0xed,0x18,0x3e,0xfa,0x03,0x51,0x8d,0x45,0x68,0x12,0x7b,0xb6,0xac,0x63,0x99,0x47,0xee,0x6f,0x8b,0xcb,0xc1,0x0a,0xf9,0x23,0xf0,0x05,0xe1,0x03,0x4a,0xb5,0xe0,0x65,0x71,0xc8,0x64,0x7e,0x0d,0x39,0xe7,0x96,0xdb,0x34,0x63,0x2e,0x1a,0x27,0x85,0x52,0x63,0x8e,0x44,0xfb,0x61,0xca,0x79,0xe5,0x91,0x99,0x83,0x2d,0xe0
+.byte 0x26,0x04,0xad,0x43,0x26,0xf2,0x7e,0x56,0xae,0x35,0x6a,0xfb,0xec,0xc6,0x27,0xe4,0x3a,0xa3,0x6b,0x63,0x72,0xba,0x98,0x03,0x9f,0x2a,0x4c,0xb1,0x33,0x22,0x9d,0x53,0xf6,0x00,0xa3,0x1e,0x32,0xcb,0xbe,0xe0,0xc2,0xf8,0x71,0xcd,0x3f,0xe3,0x4d,0x83,0xf2,0x9f,0x1c,0x91,0x35,0x97,0x52,0x95,0xba,0x24,0x04,0x04,0xca,0x32,0x6d,0xd7
+.byte 0x4b,0xd4,0x9e,0x8b,0x73,0x42,0xfb,0x9f,0xfc,0x93,0xea,0xc2,0x41,0x56,0xa9,0xe5,0xdd,0xd0,0x37,0x8a,0xe2,0x92,0x9f,0x45,0x4f,0xd8,0xef,0xe6,0x6f,0x58,0x41,0x5f,0x7b,0xe7,0x0f,0x32,0xce,0x06,0x02,0x7f,0xe2,0x37,0x87,0xb7,0x35,0x72,0x68,0x87,0xc9,0x35,0xa8,0x51,0xce,0xd8,0xde,0xc3,0x8c,0xb4,0xab,0xf4,0xa7,0x3b,0xcd,0xc8
+.byte 0x0a,0x56,0x5b,0x48,0xb1,0xa4,0x27,0xa8,0x9e,0x3e,0x04,0xbc,0xb3,0x63,0x3e,0xd5,0xf7,0xae,0xec,0x0c,0x6e,0x4a,0x73,0xb6,0xed,0x66,0xea,0xc1,0x7a,0xc4,0xaa,0x21,0x27,0x62,0xef,0x3d,0x1d,0x51,0x8b,0x63,0xe6,0xe2,0x8a,0xed,0x7a,0x4b,0x90,0xc3,0x9f,0x91,0xb4,0x8f,0x78,0x65,0x9c,0xdd,0x0a,0x7a,0x50,0x36,0x33,0x30,0x3b,0xb4
+.byte 0xdf,0x67,0xbd,0xfd,0x71,0xfc,0x40,0x49,0xaa,0x01,0xdf,0x68,0x67,0x73,0x31,0x2c,0x98,0x2f,0x8c,0x9e,0x2d,0xce,0x4a,0x71,0xbc,0x6f,0x90,0x1d,0xc0,0x37,0x07,0x30,0x0c,0xa3,0x04,0xfb,0xd1,0xd0,0x0e,0xcb,0xdc,0x94,0x06,0x7f,0x83,0xe5,0x45,0x47,0xd0,0x71,0x06,0x94,0x23,0x7c,0x03,0x80,0x46,0xa5,0x10,0x08,0xd1,0xdb,0xfb,0x9d
+.byte 0xd4,0x05,0x01,0x5e,0x66,0x4d,0xf9,0x32,0x9b,0x5b,0xfe,0x7a,0x60,0x63,0x77,0x9a,0x31,0x34,0xe5,0x9a,0x82,0x2d,0x2b,0xb7,0xe0,0x04,0x8f,0x86,0xf3,0xb2,0x16,0x86,0x50,0x37,0x9d,0x80,0xe7,0x62,0xdf,0x77,0xda,0xf4,0xfc,0xb7,0x42,0x9d,0xac,0xcb,0x11,0xff,0x0c,0x6f,0x4e,0x16,0x0c,0x59,0x04,0x05,0x8f,0x88,0x64,0x37,0xe6,0x6c
+.byte 0xee,0x64,0x58,0x79,0x60,0xd4,0x2f,0xb7,0x90,0x59,0xfb,0x82,0x3b,0x20,0x2e,0x2b,0xba,0x15,0xfb,0xf7,0x5b,0x1d,0x81,0x8a,0x8a,0x8f,0xe3,0x39,0x92,0x34,0xfc,0x3a,0x67,0xce,0xb6,0xa0,0x9b,0x56,0x78,0x96,0x4d,0x32,0xbf,0x9c,0x83,0x9e,0x19,0x66,0x20,0x42,0xb2,0x78,0x62,0x42,0xdd,0xdf,0x98,0xab,0x0c,0x3d,0x41,0xb5,0x74,0xc1
+.byte 0x2d,0xf0,0x02,0x58,0x6e,0xb3,0x4d,0x7b,0x41,0x1c,0xf1,0x09,0xc1,0xbb,0x84,0x67,0xf8,0x24,0x77,0x32,0xcd,0x7a,0x63,0x87,0x0d,0xf2,0xc5,0xaf,0xe4,0xb5,0xc6,0x3b,0xad,0x66,0x5e,0xae,0x90,0xc2,0x24,0x27,0x7a,0x0b,0xed,0x1b,0x86,0x5d,0x02,0x19,0x85,0x78,0xc8,0xb1,0xce,0xe7,0xc9,0x5c,0xce,0x43,0x58,0xac,0x1c,0x4e,0xcd,0xb8
+.byte 0x3a,0xb8,0x7a,0xf3,0x79,0x4b,0x97,0xcf,0xbe,0x88,0x24,0xd0,0x9a,0x5a,0x55,0x43,0x0c,0x48,0xa2,0x7f,0xaf,0x4b,0xd8,0x16,0x02,0xfb,0xe6,0x0c,0x6b,0x85,0xb4,0xb8,0x5e,0x40,0x60,0x5d,0x93,0x51,0xc6,0x32,0xb9,0x4a,0x23,0x96,0x71,0xeb,0xe8,0xe8,0x01,0x1e,0x85,0xb0,0x47,0xde,0x86,0x15,0x52,0x3a,0xb2,0xd3,0x86,0x4b,0x78,0x09
+.byte 0x9c,0x6e,0x9d,0xd9,0xef,0xe8,0x64,0x2d,0x2a,0xec,0x21,0x5a,0x60,0xa5,0xe4,0x26,0xbb,0x79,0x0c,0xdb,0x48,0xd6,0x4b,0x5c,0x5b,0xe3,0x34,0xc9,0x96,0xf0,0xcb,0x68,0x8a,0x2d,0xee,0xa3,0x37,0x34,0x5f,0x3e,0x65,0x40,0xce,0xe1,0xc8,0x2e,0x11,0xca,0x42,0x51,0x53,0x72,0x3d,0xa9,0x68,0x54,0xb4,0xd8,0xd7,0x72,0x84,0x8d,0xcd,0x6d
+.byte 0x1f,0x0e,0x0c,0x0f,0x32,0x3a,0x7d,0xdd,0xc1,0xd3,0xe7,0x2d,0x1f,0x52,0x8b,0x73,0x86,0x70,0x2a,0xcb,0x71,0x37,0xa1,0xab,0xe3,0x94,0x5a,0xd7,0x9d,0x68,0xc1,0x6e,0x5d,0x72,0x25,0x81,0xe8,0x45,0xad,0x6c,0xf8,0xdb,0x9b,0x70,0x31,0xb9,0xf0,0x4f,0x23,0xd7,0x03,0xc8,0x87,0x43,0x51,0x7a,0x55,0xfe,0x6f,0x2d,0x40,0xbc,0xfe,0xdf
+.byte 0xe6,0x21,0x4b,0x4d,0xc6,0x02,0x48,0xe7,0x7a,0x2a,0xef,0x91,0xdf,0xbc,0x98,0x91,0x6f,0x59,0xc4,0x47,0x77,0x2e,0x45,0x45,0x23,0x47,0x5d,0xf8,0x50,0x41,0x84,0x75,0x8a,0xe7,0x4d,0xfb,0xeb,0x58,0x00,0xcf,0x42,0xca,0x02,0x05,0xc7,0xfa,0x11,0xfb,0x6e,0x90,0x7d,0x53,0xa0,0x19,0x23,0x24,0x8f,0x89,0x17,0x40,0xbe,0x11,0xfb,0xd9
+.byte 0x04,0xf8,0x84,0xeb,0x90,0x7c,0x84,0x45,0x9c,0x53,0x45,0x5e,0x45,0x51,0x55,0xfc,0xf1,0x6b,0x02,0x24,0xfd,0x95,0x4a,0x40,0x80,0xdc,0xa6,0x94,0x15,0x2c,0x1d,0x85,0xa0,0x07,0x8d,0xf8,0xf2,0x95,0x0c,0xa0,0x4e,0x5a,0x5b,0x29,0x09,0xcc,0xf3,0x4e,0x8e,0xea,0xe8,0x26,0xb8,0xbe,0xb2,0x6f,0x76,0x6f,0xa4,0xe5,0x6a,0x50,0xcf,0xc8
+.byte 0x7d,0xb6,0x1e,0x9d,0x90,0x6b,0xde,0xe2,0x55,0x49,0x97,0x00,0xa5,0xc5,0x1f,0x1c,0x41,0x66,0xe7,0x6b,0x20,0xb2,0x1e,0xc7,0xb3,0xd4,0xa9,0x75,0xbb,0x83,0x24,0xd0,0xdf,0xbd,0xba,0x2c,0x2f,0xa4,0x03,0x1d,0x17,0xc5,0x74,0xc2,0x6a,0x20,0x71,0x18,0xd1,0xc5,0xb0,0x78,0xfe,0xda,0x55,0xd2,0x43,0x2a,0xd8,0x88,0x74,0x75,0x86,0x07
+.byte 0xe9,0x8b,0x0d,0x0f,0xe5,0x8d,0xe8,0x3d,0xf4,0x93,0xde,0x4c,0x97,0x98,0xe2,0x9b,0x22,0xde,0x13,0x18,0x8b,0xc5,0xe1,0x6f,0x6d,0xb4,0x19,0x46,0xff,0xbd,0xa6,0x2e,0xe6,0x48,0xcd,0x66,0x22,0x7d,0xf4,0x0e,0xeb,0x74,0x25,0x5c,0x90,0x0e,0x26,0xce,0x17,0xe9,0xdb,0x30,0xb9,0x25,0x99,0x96,0x46,0x3a,0x78,0xa3,0x76,0x2d,0x9e,0x42
+.byte 0x06,0x8a,0x1e,0x62,0x46,0xa4,0xd0,0x1d,0xe2,0x4c,0x3c,0xb4,0x4c,0xc0,0xd1,0xf7,0x05,0x5b,0xe4,0xd4,0x71,0x73,0x31,0xfc,0x98,0x2a,0x55,0xb0,0x78,0x92,0x59,0x8b,0x25,0x97,0x15,0xf2,0xf9,0x57,0x8b,0x7c,0xd4,0xc4,0x47,0x2f,0x10,0x3b,0x76,0xde,0x5f,0xb1,0xdf,0xdc,0xb0,0x15,0xd5,0x4a,0xd2,0x54,0xad,0x5e,0x32,0xf4,0x5a,0x1a
+.byte 0x8d,0xe8,0xa0,0x4a,0x4e,0x04,0xdc,0xdd,0xd2,0x57,0xe5,0x24,0x4b,0x93,0x51,0xef,0xd4,0xba,0x3f,0x77,0xfc,0x0a,0x5c,0x7d,0x6e,0xa7,0x86,0xe5,0x88,0xd1,0xac,0x74,0x46,0x9a,0x39,0xb6,0x98,0x3d,0xae,0x89,0x4e,0xea,0x8d,0xdc,0xc7,0xb9,0x0c,0xd7,0xa6,0x06,0x4d,0x28,0x2b,0x51,0x2b,0xdb,0x30,0x4a,0x91,0x1c,0x40,0x89,0xe4,0xba
+.byte 0x72,0xd5,0xed,0x16,0x66,0xb8,0xef,0x81,0xd9,0x51,0xf8,0x1b,0xff,0xab,0x8b,0x52,0xb8,0xf3,0x11,0xb3,0xe5,0x04,0x5a,0xb0,0x60,0xa3,0x35,0x12,0x6a,0xa0,0x75,0x5c,0x21,0xa9,0x5a,0xe8,0xd3,0xd7,0x8a,0x1f,0xe0,0x9b,0xb7,0x1e,0x7d,0xbe,0x81,0xaa,0x56,0x5a,0xd8,0x2d,0x7e,0x0c,0x60,0xb2,0x68,0x26,0x6d,0xaa,0x8b,0xcc,0x11,0x40
+.byte 0x25,0xea,0xc9,0x94,0xfb,0x3b,0x9b,0xa7,0x3a,0xde,0xd9,0xfe,0x6b,0x4b,0xfc,0x3f,0xbf,0xdd,0x51,0x9b,0xa1,0xca,0x2f,0xed,0x33,0xd8,0x3d,0x92,0xa4,0x1d,0xee,0xb2,0x47,0xd0,0x72,0x6a,0x96,0x33,0x0f,0xdd,0x0a,0xd9,0xbd,0x86,0xdb,0x25,0x53,0x0e,0x3c,0x31,0xad,0x05,0xb9,0x24,0x13,0x00,0xdf,0xc2,0x7c,0x3d,0x03,0x9b,0xf6,0x6d
+.byte 0x93,0xd9,0xdf,0x73,0xf8,0x1c,0x98,0xe2,0x77,0x46,0x46,0xdc,0x07,0xe6,0xbb,0xc1,0xa7,0xb6,0xbe,0x21,0x07,0xae,0xdb,0xca,0x69,0x2d,0x8a,0x2b,0x59,0x27,0xe0,0x7c,0xf0,0xf1,0x34,0x69,0x97,0x44,0xba,0xbb,0x48,0x9f,0xd9,0xd8,0x16,0x1a,0xef,0x11,0x68,0xb6,0xaf,0x3a,0x10,0xc6,0x7c,0xd1,0x12,0xc7,0x89,0x47,0xe3,0xd1,0x24,0xc6
+.byte 0x44,0x9f,0x7e,0x6a,0x66,0x43,0x48,0xd6,0x9f,0x7b,0xf0,0x1f,0xd2,0x5f,0x2b,0xa7,0x13,0x6a,0x7c,0x70,0x08,0x38,0xb0,0x00,0xbc,0x7c,0xd3,0x01,0x9b,0xf6,0x29,0xd3,0x9c,0xa4,0x11,0x90,0xe4,0x9f,0x04,0xd6,0x21,0xec,0xfd,0xcb,0xb8,0xe6,0xb6,0x49,0x2b,0xfa,0x4b,0x90,0x9e,0xc6,0x0c,0x87,0xff,0x5e,0x2e,0xcc,0xf8,0x09,0x70,0x52
+.byte 0x42,0xec,0x88,0xac,0x1e,0x76,0x2b,0xeb,0xfc,0xb3,0x65,0x81,0x34,0xb1,0x06,0x90,0xde,0xb2,0xc4,0xd3,0xfd,0xd4,0x9c,0x78,0x1a,0x5c,0x8f,0x65,0x0a,0xbd,0x88,0xe5,0x95,0x06,0xb5,0x94,0xe5,0xbf,0x90,0x31,0xbb,0xcb,0xce,0x19,0x51,0x25,0x4a,0x47,0x35,0x26,0x93,0xdb,0xe2,0x93,0x36,0x47,0x7d,0xdd,0x4e,0xd5,0xeb,0xdd,0x63,0x1c
+.byte 0xbc,0x2d,0x75,0xdb,0xd4,0xfa,0x60,0x4b,0x51,0x45,0x32,0x0f,0x01,0xf9,0x73,0x9b,0xd8,0xbc,0xee,0xaa,0x7d,0x2e,0xfe,0xbf,0x9d,0x45,0xae,0xe2,0x01,0xe3,0xbf,0x58,0xdc,0xc0,0xb8,0xe8,0x44,0x16,0x3b,0xd8,0xaa,0x3b,0x13,0xca,0xfb,0x5f,0x8d,0xb3,0x2a,0x83,0x66,0x49,0xae,0x54,0x02,0x4e,0xd8,0x68,0xee,0x21,0x1a,0xbb,0xf4,0xf7
+.byte 0xdf,0xf1,0x51,0x7b,0x62,0xa8,0xb2,0xdc,0x4b,0xd4,0x04,0xd2,0x05,0x49,0xdd,0xa4,0x75,0xe6,0x64,0x82,0xe7,0x25,0x55,0x60,0x2c,0x9f,0x8a,0x7a,0x11,0xe9,0xf2,0x72,0xfe,0x89,0xe1,0xaf,0xca,0x0c,0xb9,0xf5,0xcc,0xcf,0x07,0xef,0x8f,0xbb,0xef,0x53,0x1e,0xe2,0xfb,0x98,0xe8,0x05,0xab,0x4e,0x7e,0x38,0x56,0x24,0xd5,0x74,0x1c,0x95
+.byte 0x1a,0x0e,0x62,0x92,0x80,0x16,0x45,0x78,0x2f,0xb1,0xe1,0x83,0x24,0x2b,0x16,0x5c,0x05,0x52,0x17,0xe9,0xe8,0x9e,0x5d,0x63,0x8f,0x77,0xc4,0x89,0x22,0x76,0x43,0x31,0xfd,0x09,0xc0,0x51,0x70,0x57,0x2d,0x51,0x91,0xe5,0x61,0x3f,0x77,0xff,0x17,0xfc,0xa6,0x19,0x9d,0x82,0x46,0x11,0x0c,0x77,0x19,0x2a,0xf5,0x19,0xb4,0x3d,0xa6,0xd4
+.byte 0x8b,0x07,0x4b,0xc6,0xa3,0x1e,0x8c,0xf5,0xe8,0x2d,0xe7,0xcc,0xa1,0x38,0x57,0x66,0x76,0x1d,0xdd,0xe3,0xb9,0x0a,0x1e,0x2c,0xad,0x09,0x07,0x26,0xff,0x7a,0xc0,0xb0,0x51,0x71,0x44,0x6d,0x2c,0x39,0x3d,0xa6,0x14,0x4e,0x74,0x2c,0x54,0x3d,0xfa,0xdc,0x2e,0x0c,0xc4,0x88,0x32,0xda,0xb0,0x9d,0xf4,0x2c,0x0a,0x1b,0xb7,0xb4,0x78,0x6f
+.byte 0x1b,0x6a,0x21,0x03,0x4e,0xe0,0x87,0xa0,0x1c,0xd8,0xe6,0x0c,0x97,0x47,0xde,0x98,0x81,0x3d,0x39,0x93,0x3d,0xcb,0x29,0xa3,0x93,0x8d,0x27,0x5d,0x29,0xb5,0x85,0xc4,0x32,0xd8,0xdc,0x19,0xb1,0x63,0xdc,0x76,0x32,0xc3,0x52,0x9a,0xfd,0x3d,0xff,0xf9,0x94,0x55,0x72,0xbb,0x4d,0xe2,0x42,0xd2,0xf7,0xb2,0xac,0xac,0x5d,0x50,0x95,0xda
+.byte 0x3a,0x87,0xb6,0x0f,0x27,0x72,0x34,0xe7,0xe8,0x9f,0xc7,0xba,0xca,0x8d,0xf3,0xb9,0xa1,0xdd,0xd7,0xa5,0x70,0x3b,0xcc,0x72,0x0e,0x9d,0x85,0x75,0x01,0x11,0xe1,0xc2,0xca,0xcb,0x40,0x3a,0x31,0xf2,0x5d,0x0c,0x63,0xc8,0xbf,0x38,0xde,0x09,0x3b,0x32,0xaa,0x6c,0x07,0xd2,0x2b,0x3b,0x94,0x37,0xd0,0xd9,0xe0,0x4c,0x25,0xa3,0x22,0x64
+.byte 0x05,0xcc,0x69,0x9e,0x73,0xd4,0x46,0x2c,0x73,0x23,0xd0,0x6f,0x09,0xff,0x8b,0xef,0x7a,0x08,0x3e,0xa2,0xa7,0x9d,0xf5,0xc9,0x40,0xd1,0x06,0xd6,0xe3,0x89,0xa5,0xcc,0x9f,0x40,0x67,0x80,0x11,0xec,0x5d,0x23,0x19,0xf3,0x66,0xaf,0x06,0xcc,0xe4,0xb6,0x5e,0x20,0xf7,0x19,0xce,0x1a,0xb6,0x86,0x0d,0x39,0x1d,0xc8,0x0a,0xdb,0x50,0x52
+.byte 0x7e,0x3b,0x96,0x9f,0x05,0xdd,0xd8,0xdf,0x40,0xdf,0xe4,0x66,0x14,0x4d,0x4e,0xb3,0x9f,0x86,0x7b,0xc2,0x99,0xc3,0x8f,0xb9,0xe7,0xc3,0x50,0xa4,0xab,0xb8,0x8e,0xc5,0x28,0xce,0x8b,0x51,0xcb,0xad,0xd8,0x1a,0x23,0x7d,0x12,0xc2,0xaf,0x1a,0x93,0x4c,0x57,0xe9,0x59,0x6a,0x03,0x65,0x81,0x07,0x40,0x84,0x92,0x9d,0x22,0x8a,0x3d,0x27
+.byte 0x39,0x05,0xdd,0xf7,0x20,0xad,0xc2,0x03,0x27,0x87,0x8e,0xc1,0x23,0xad,0xe5,0x59,0x16,0xe7,0xde,0xe4,0x44,0x6b,0x06,0xb5,0x1d,0xaf,0xda,0x08,0x4a,0xfa,0x75,0x1a,0x0b,0x35,0xe8,0x6e,0x29,0xd3,0x79,0x19,0x80,0xb9,0x5f,0x36,0xec,0x43,0x25,0x3c,0xbc,0xcf,0x70,0x0c,0xc7,0x2c,0xbc,0x2e,0x72,0x40,0x73,0x98,0x11,0xc9,0x72,0x9f
+.byte 0xd9,0x95,0x9f,0x8d,0x4a,0x52,0xbb,0x89,0x30,0x5b,0xa2,0x7e,0x0c,0x21,0x11,0xda,0x4e,0xa1,0x7c,0xc1,0x0f,0x95,0x1b,0x5b,0x2e,0xbd,0xae,0x8a,0x56,0x82,0x8f,0x84,0x43,0xdf,0x24,0xac,0x99,0xaa,0x8a,0xaf,0x82,0x33,0xf7,0x0a,0xbf,0x5e,0xfd,0xf2,0x91,0xf0,0xe1,0x5d,0x4e,0xa5,0x16,0x6e,0xb4,0x39,0x8b,0x99,0x32,0x6b,0xc8,0x16
+.byte 0xc1,0x84,0x10,0xc2,0x74,0x54,0xfc,0x02,0x71,0x44,0xfc,0x52,0xfa,0xc2,0x3c,0x8d,0xf7,0x8b,0x1e,0xcc,0x5e,0x43,0x66,0x29,0x29,0x93,0xe7,0xf6,0x9f,0xa8,0xa3,0x35,0xc9,0xde,0xb0,0xbe,0x4d,0xdf,0x8c,0x61,0x5a,0x6b,0x16,0x88,0x33,0x65,0x47,0x98,0xd2,0xf8,0x71,0x09,0x9f,0x00,0xb6,0x9e,0x21,0x37,0x2a,0x0b,0xb4,0x74,0x6b,0x0e
+.byte 0x6e,0x4d,0x14,0x45,0x6c,0x1b,0xa8,0x4c,0xa7,0xc6,0xc3,0x36,0x6e,0x9e,0x63,0x5a,0x36,0x76,0x04,0x06,0x7f,0xdd,0x74,0x24,0x19,0xd8,0xb7,0xbc,0x6c,0x52,0x82,0x67,0x6b,0xd5,0xcb,0x81,0xdf,0xd7,0xe4,0xdd,0x14,0x33,0x71,0xcf,0x6b,0x7f,0xaf,0x66,0x27,0x8a,0x70,0xb8,0x45,0xae,0x8c,0x1a,0x65,0xd3,0x16,0x5c,0x05,0x65,0xd0,0xfb
+.byte 0x07,0xe3,0x98,0xa9,0x94,0x27,0x6c,0xac,0xfc,0xee,0x1b,0x35,0x43,0xd6,0x3b,0x41,0x1c,0x86,0xc0,0x4f,0xf3,0x63,0xf4,0xba,0x4d,0xdf,0x6a,0xda,0xcf,0xb5,0x9f,0x69,0x3f,0x3d,0x0c,0x80,0x79,0x02,0x34,0x4a,0x9a,0xfd,0xb6,0xea,0x0b,0x61,0x32,0x67,0x2d,0x6a,0x6b,0xcb,0xcf,0xa6,0xee,0x6a,0x93,0x11,0x00,0xb8,0x6e,0x27,0x88,0x62
+.byte 0xf7,0x4c,0x7b,0xe1,0x13,0xe1,0x47,0xaf,0x96,0x24,0x3b,0x46,0x8c,0xf4,0xbe,0x13,0xed,0x65,0xe1,0xf2,0x36,0x2d,0xa4,0x6d,0x5e,0xa6,0x93,0xfb,0x64,0x0e,0xbd,0x50,0xdc,0x29,0x4f,0x90,0x8e,0xe1,0x7f,0x5e,0x47,0x08,0x9b,0x1c,0xb7,0xce,0x06,0x80,0x52,0xc0,0xb5,0x82,0x77,0x49,0x3c,0xe0,0x70,0x1f,0x84,0x75,0x9e,0x19,0xb2,0x83
+.byte 0xda,0x40,0xf8,0xd7,0x27,0x1e,0xbc,0x39,0xb5,0x1d,0x25,0x75,0x63,0x7d,0x85,0x2f,0x09,0x07,0xe9,0x73,0x8e,0x2b,0xb8,0x9a,0xbe,0xd6,0x90,0x91,0x6e,0xdb,0x7c,0x9d,0x9b,0x43,0x1d,0x21,0x88,0x76,0xb0,0xaa,0x7b,0x68,0xe4,0xa7,0x92,0x64,0xe4,0x1f,0xff,0x53,0x1d,0xf7,0xc0,0x44,0x5c,0x0a,0x1e,0xcd,0xa7,0x6e,0x41,0x1c,0x8c,0x7d
+.byte 0x66,0xa7,0xf6,0xfc,0xa9,0x0d,0x3f,0x9c,0xfb,0x15,0x87,0x14,0x20,0x43,0x1b,0x05,0xf5,0xea,0x5c,0x07,0x61,0xb3,0x0e,0x7c,0x52,0x57,0x1c,0x09,0x33,0xb4,0xd8,0x3d,0x9d,0x17,0xee,0x86,0x25,0xdc,0x6b,0xcd,0x58,0xb7,0x18,0xbd,0x85,0x39,0x0b,0xb9,0xb8,0x35,0x3a,0x86,0xbb,0x88,0xb5,0x5e,0x4b,0x0a,0x7e,0x9c,0x02,0xb5,0x45,0xe5
+.byte 0xc7,0x38,0x56,0x1e,0xe4,0xe7,0xf7,0x88,0xac,0x75,0x9a,0x97,0xa8,0x15,0xb6,0x2d,0xcf,0x2a,0x59,0x65,0x0e,0x00,0x9f,0x8e,0xa9,0x94,0x23,0x1c,0x40,0xe4,0xb9,0x6b,0xcf,0xf0,0x53,0x7f,0x98,0xd1,0xa7,0x72,0xd7,0xe3,0x22,0xfd,0x5f,0x3d,0x3f,0xd6,0x21,0xb4,0x84,0x0c,0x1b,0x1d,0x00,0x2d,0x8f,0x72,0x22,0x2d,0x2c,0x8c,0x54,0x46
+.byte 0xe5,0x53,0xca,0x66,0x67,0x5e,0xb3,0x62,0x6f,0xaf,0x33,0x81,0xc1,0xf6,0x77,0x92,0x3e,0xdb,0x74,0x68,0x93,0xca,0x38,0xf8,0x18,0x50,0xef,0xe4,0xc9,0x45,0x40,0xc9,0xf0,0xc5,0x7a,0x4b,0xf2,0xd8,0xca,0x72,0x62,0x5f,0x67,0x10,0x10,0xcc,0xff,0x1a,0xc7,0x9c,0x3a,0x7f,0xca,0x11,0x67,0x3e,0xca,0xa6,0x9c,0x48,0x15,0xaf,0x68,0xb7
+.byte 0x2b,0xa7,0xa2,0x68,0x7b,0x40,0xb2,0xe3,0x27,0x18,0x7e,0x94,0x4c,0xca,0x0e,0x5b,0x3a,0x30,0xcb,0xc3,0x72,0x31,0x6b,0xe6,0x3e,0xa7,0x09,0x3e,0xf2,0x53,0xda,0x7d,0x6f,0x55,0x08,0xd2,0x26,0xc3,0x07,0x52,0x38,0x90,0x04,0xc6,0x3c,0xb6,0xb5,0x2a,0x7b,0x38,0x07,0x9e,0xb4,0xa5,0x48,0x36,0xf5,0x5e,0xac,0xa8,0x97,0x4e,0x37,0xc2
+.byte 0xee,0x12,0x88,0x28,0xd0,0x7d,0xd1,0xae,0xc0,0xc7,0x84,0x69,0x25,0x79,0x9a,0x8a,0x16,0x49,0x50,0x72,0x69,0x1a,0x02,0xc9,0xfe,0xd5,0x2c,0x40,0xc6,0xc8,0x8b,0x7d,0xe3,0xab,0x89,0xe3,0x78,0xf1,0xe9,0xbd,0x3c,0xbd,0x02,0x96,0xfe,0x0c,0x5c,0xc4,0x9e,0x89,0x3a,0x4b,0xe9,0xcd,0x41,0x1c,0x59,0x71,0x52,0xb0,0xc9,0x36,0xf1,0x80
+.byte 0xab,0x5e,0xbc,0xf1,0x20,0x99,0xc0,0xab,0x0c,0x59,0x43,0xc2,0xcd,0x09,0xa6,0x30,0x91,0xfa,0x12,0x23,0xbe,0x18,0x24,0xa6,0xbf,0x55,0x4c,0xe8,0x22,0xff,0x01,0xbd,0xde,0x2c,0x72,0x3c,0x0a,0x36,0xd5,0x7e,0xed,0x6a,0xe3,0x63,0x14,0x60,0xa3,0x0a,0x6f,0x04,0x90,0x64,0xc1,0xd1,0x78,0x54,0xae,0x19,0x74,0xe2,0xea,0xec,0x86,0x22
+.byte 0xc7,0xdb,0xf6,0x48,0x0e,0x75,0x43,0x04,0xf7,0x62,0xe6,0xa9,0x46,0x65,0xcc,0xa5,0xa4,0x1a,0xb2,0x94,0x7b,0x7a,0x8c,0x9a,0x80,0x62,0x32,0x17,0x80,0xc3,0xc6,0x54,0x0e,0x4e,0xe3,0x46,0x74,0xa8,0xae,0xcd,0xd0,0xc1,0x19,0x84,0x61,0xb4,0x1d,0x18,0x4d,0x80,0xf1,0x70,0x40,0xbe,0xa2,0xa3,0x38,0xcc,0x21,0x1c,0x2f,0x72,0x85,0x72
+.byte 0x0a,0xa1,0x0d,0xa3,0xdc,0xa2,0xf4,0x64,0x84,0x3c,0x43,0x6d,0xfb,0x45,0x11,0xf9,0x40,0xdc,0x25,0x85,0x80,0x41,0x84,0xa7,0x06,0x2e,0x79,0xbf,0x0c,0xa7,0x8f,0x17,0xea,0xa2,0xc4,0x6f,0xd8,0xc6,0x9e,0xab,0xdc,0x45,0x6f,0xaa,0xda,0xe9,0xe6,0x84,0xf0,0x5f,0x8a,0x90,0x99,0x33,0x9b,0xcf,0x03,0xe6,0xce,0x19,0x0c,0xad,0x2f,0xad
+.byte 0x81,0xb8,0x17,0xff,0x6b,0xff,0xc8,0x14,0xa6,0xf4,0x37,0x55,0xdc,0xbb,0x09,0x3c,0x3c,0xe7,0x29,0x95,0x23,0x5c,0x58,0x92,0x2e,0x95,0xe8,0x3b,0x8b,0x81,0x2d,0xfd,0x58,0x8a,0x1f,0xdf,0xf1,0x54,0xa3,0xd0,0x01,0xaa,0x3d,0x32,0x61,0xe5,0x8e,0x62,0xa7,0xf6,0x3b,0x2d,0x0e,0xff,0xf4,0xe9,0x08,0xe7,0xef,0x3a,0x63,0x10,0x34,0x49
+.byte 0x14,0xe1,0x88,0xd0,0xb2,0x1d,0xb7,0x31,0xc9,0xa4,0x48,0xa8,0xaf,0x64,0x29,0xab,0x1f,0x14,0x13,0xa7,0xb8,0xb8,0xa4,0x24,0x1d,0xf9,0xb6,0x3e,0x62,0xa6,0x5e,0x10,0xcb,0x44,0x5c,0x9d,0x2c,0x58,0x3a,0x36,0xa3,0x81,0x9f,0xa9,0xa4,0xa1,0x06,0x1d,0xbf,0x97,0x03,0x88,0xf2,0xf4,0x81,0x3e,0x1b,0x35,0xea,0xd0,0xb6,0x96,0xa1,0xf7
+.byte 0x1e,0x49,0xb7,0xe8,0x23,0x6f,0x05,0x7c,0x9f,0xc4,0x53,0xb1,0x63,0xdc,0x07,0xbb,0xd6,0x57,0x85,0x4d,0x77,0x33,0x21,0xbf,0x77,0xfe,0xfe,0x34,0x52,0x02,0xe7,0xe4,0x87,0x11,0xa0,0xfd,0x11,0x4a,0x34,0x36,0x88,0x69,0xdf,0x77,0xfd,0x83,0x71,0xa8,0x68,0xed,0x49,0x39,0xb4,0x06,0x32,0x48,0xf1,0xd2,0x4e,0x61,0x47,0x65,0x26,0x87
+.byte 0xba,0x2b,0x2e,0xf4,0x12,0xfc,0xd0,0x84,0x81,0xa1,0x59,0xdc,0xe3,0x13,0x51,0x9e,0xea,0x57,0x56,0x3b,0x7c,0x71,0x6b,0xff,0xe9,0xf8,0xec,0x3e,0xe7,0xbe,0x65,0x47,0xe1,0x6f,0x8f,0x7c,0x3a,0x77,0xdb,0x75,0x4a,0x43,0x43,0x39,0x37,0xb2,0x68,0x16,0x72,0xdb,0x49,0xf7,0x13,0x3c,0x09,0x93,0xef,0xc1,0x2a,0x99,0xff,0xc7,0xdb,0xd9
+.byte 0x80,0xd2,0xfe,0x7c,0x39,0x50,0x21,0xdc,0x1d,0xae,0x9b,0xfc,0xd4,0x5f,0x56,0xae,0x6a,0xd9,0x35,0xa1,0x2b,0xd6,0x53,0x90,0xe8,0x8c,0x31,0x73,0x0f,0xa3,0x9e,0xa1,0x2f,0x76,0xa8,0x72,0x4d,0x5e,0x58,0xca,0x9f,0x8f,0xdf,0xf0,0xf9,0x6a,0x54,0xb1,0x5f,0x39,0x03,0x7a,0x26,0x06,0x71,0x74,0x6f,0x42,0xee,0x63,0x76,0x13,0xb9,0xed
+.byte 0x74,0xad,0xf9,0xe0,0xa7,0x35,0x9c,0x18,0xe0,0xf7,0xc5,0xb2,0x27,0x14,0x0f,0xd7,0xaa,0x17,0x1c,0x8f,0x50,0xc8,0xb0,0xc2,0x63,0xff,0x38,0x65,0x87,0x69,0xb3,0xd5,0x3f,0xb4,0xf2,0xe8,0x8b,0x7b,0x24,0xdc,0x1f,0x62,0x2f,0x0a,0xd7,0x2d,0x0f,0x6f,0x48,0x1d,0xf0,0x3c,0xb1,0xb4,0x10,0x8d,0xc6,0x5c,0x79,0x30,0xde,0x20,0x9e,0x7b
+.byte 0xf1,0xa5,0x73,0x38,0x05,0x1b,0x13,0x78,0xb1,0x02,0x2f,0x32,0x2a,0x07,0x59,0xa4,0xfc,0x88,0x08,0x0c,0xff,0x42,0x72,0x6a,0xb0,0x8a,0xc9,0x3d,0xdb,0x04,0x90,0xdd,0x0b,0xbc,0x3a,0x4e,0xfa,0xd4,0x57,0xd8,0x2f,0x7b,0xcb,0xd9,0x6a,0xe7,0xfd,0x32,0x17,0x99,0x20,0x64,0x1e,0x76,0x07,0xb9,0xa3,0x58,0x7f,0x79,0xda,0x0c,0xe0,0xec
+.byte 0x30,0xbf,0xa4,0x85,0x0a,0x39,0xc0,0xe9,0xf7,0xbe,0xd1,0xa7,0x94,0x1f,0xa6,0x6d,0xe8,0xc5,0x1b,0x04,0x27,0xf4,0xdc,0xc2,0x4d,0x9a,0x0e,0x9b,0xe8,0xec,0x56,0x99,0x90,0x5f,0x8b,0x28,0x0a,0x92,0xaf,0x0b,0xa1,0xd2,0x85,0x86,0x26,0xc7,0x8a,0x01,0xa4,0x08,0x29,0x32,0x7d,0x3d,0xa5,0x74,0x9c,0x90,0x63,0x83,0x1f,0xd4,0xee,0x98
+.byte 0xf5,0x14,0xff,0x39,0xeb,0xbf,0x40,0xa4,0xc9,0x70,0x4f,0x81,0x03,0x19,0xef,0xf5,0xdf,0xf7,0x00,0x75,0xcb,0x2e,0x81,0x41,0xc5,0xda,0xfb,0x67,0x6a,0xf0,0xa3,0xd3,0x5a,0x60,0xaf,0x72,0x27,0x3e,0xad,0x37,0x3e,0x3d,0xe6,0x85,0x4c,0xa1,0xb0,0xe9,0xab,0xc5,0xd3,0x8b,0x04,0x0d,0x64,0x7f,0xa2,0xb9,0x6d,0x6d,0x28,0xf8,0x4b,0x43
+.byte 0x78,0x51,0xf4,0x84,0xf1,0x3c,0x67,0xd8,0xdd,0xd7,0x0b,0x67,0xc3,0xd9,0x95,0x7b,0xfc,0x7d,0xc4,0x33,0x05,0x90,0xec,0x0a,0x98,0xfb,0x6b,0x0d,0xe9,0x8c,0x74,0x94,0x20,0xf8,0xcb,0xca,0xb6,0x72,0x07,0x7c,0xef,0xfa,0xd0,0x3f,0x51,0xc5,0x6e,0xf8,0x3f,0x37,0xe3,0xfe,0xb9,0x9a,0x9c,0xb3,0xf6,0x96,0x4e,0x65,0x77,0x21,0xcf,0xaf
+.byte 0xe7,0x20,0x06,0xc2,0x93,0xc5,0x2e,0xc0,0x7f,0xe5,0x0a,0x42,0xad,0x89,0x64,0x6e,0x95,0xbf,0x95,0x1d,0x24,0x47,0xf8,0xd5,0xec,0x7c,0x1f,0x98,0x67,0x9c,0x5f,0x6e,0xaf,0x74,0x95,0x65,0x4c,0xb6,0xe0,0xd3,0xb7,0x5b,0xc7,0x76,0xe6,0x87,0x19,0xf5,0xc7,0xb0,0x2d,0xe0,0x8b,0xaf,0x6d,0x3c,0x31,0x6e,0x84,0xc8,0x86,0x51,0xff,0x29
+.byte 0x2a,0x1f,0xea,0xd4,0x2d,0x1a,0x8f,0x04,0xb4,0xc0,0x6a,0x93,0xc2,0xc5,0xe7,0x98,0x8c,0xc7,0xff,0xbf,0xb8,0x8e,0x5b,0x29,0x5b,0xa6,0x87,0xc7,0x02,0x88,0x51,0x29,0x66,0xd8,0xf3,0x68,0x38,0xd4,0xa6,0xbd,0xa2,0x5c,0x1b,0xb7,0x13,0xd7,0x64,0xed,0x68,0x21,0x88,0x2b,0x59,0xba,0x95,0x84,0xda,0xce,0x61,0x3b,0x51,0x04,0x3e,0xc2
+.byte 0xdd,0xec,0x0c,0x6b,0xbe,0x35,0x51,0x63,0x29,0x40,0xcb,0xa5,0x62,0xe4,0x27,0x35,0x15,0x1f,0x7c,0x8b,0xe5,0xd0,0x2e,0xde,0x8c,0x3d,0xa0,0xd2,0xbe,0x51,0x3d,0x65,0xed,0x94,0x8b,0x8c,0x00,0xda,0x0e,0x78,0x4d,0x25,0xef,0x8e,0x3c,0x55,0x77,0xeb,0x58,0x06,0x7d,0xd1,0xfc,0x73,0xad,0x76,0x0a,0x81,0xbe,0xda,0x50,0x30,0xf3,0xfd
+.byte 0x58,0x25,0x0a,0x4b,0x1b,0x1e,0x0b,0xd0,0x9b,0xbc,0xb9,0x31,0x26,0xbc,0x4c,0x7b,0x05,0xd7,0x5c,0xe4,0x7a,0xdd,0xff,0x04,0xac,0x5d,0xcb,0xfd,0x91,0x34,0x68,0x26,0x1e,0xb4,0x86,0xcc,0xe3,0x90,0xaf,0x6a,0x65,0xda,0x6b,0x3e,0xec,0x44,0x90,0x72,0x7a,0x34,0xfc,0x7b,0x65,0x83,0x34,0x93,0xbc,0x85,0x50,0xdf,0x03,0x89,0x35,0xb8
+.byte 0x6a,0x39,0xd3,0xb6,0x38,0x66,0x5b,0xa7,0x9e,0x93,0xa2,0x3b,0xb6,0xe7,0xee,0x1e,0x5c,0xd6,0xa8,0xd9,0x1f,0xf7,0xd1,0x0a,0x2f,0x87,0x63,0xf4,0xf9,0x8c,0xd4,0x7c,0x02,0xaf,0x7e,0xb6,0xc7,0xfc,0xc9,0x4d,0x35,0x0c,0x8c,0x3c,0x13,0x9d,0xe6,0xd7,0x2e,0x4b,0x91,0xcc,0x88,0xdb,0xfc,0x68,0x3a,0xd1,0x15,0x07,0x16,0x66,0x11,0x9b
+.byte 0x66,0x9f,0x3f,0x37,0xae,0x11,0xba,0x5f,0xc7,0x3a,0x1a,0x49,0xbc,0x14,0x21,0x75,0xdc,0xcc,0xbb,0x5c,0xed,0xdc,0x8b,0x21,0x9a,0x8f,0x5f,0x91,0x6a,0x9b,0x26,0x33,0x64,0x45,0xa0,0xdf,0xc4,0xa1,0x32,0xc4,0x4c,0xc2,0x42,0x1b,0x59,0x37,0x1f,0xdb,0x01,0x6d,0xed,0xd8,0x05,0x5b,0x90,0x59,0x32,0x45,0x50,0x5d,0xf1,0x34,0xc4,0xb7
+.byte 0x52,0x97,0xbb,0x42,0x12,0xf1,0xa5,0x76,0xe4,0x1a,0xbc,0x4a,0x64,0xd3,0x08,0xac,0xe1,0x49,0x70,0x61,0xc8,0xcf,0xb1,0xd3,0xc4,0x7f,0x38,0x31,0x6b,0xd3,0xe1,0xe1,0xe9,0x5b,0xaa,0x7a,0xec,0x26,0x81,0x44,0xd3,0xb9,0x63,0xea,0x37,0x98,0x15,0x41,0xf1,0xa1,0x72,0x87,0xcc,0x3b,0x6a,0x27,0x9b,0x85,0xa8,0x7b,0xb6,0x25,0xf9,0xd4
+.byte 0x84,0x3e,0x66,0x12,0xce,0x24,0xee,0x22,0x51,0x73,0x7e,0xba,0x1e,0x95,0x64,0xc5,0xbf,0x4e,0x4f,0x73,0xc1,0xc3,0x98,0xb9,0x6b,0x90,0x1f,0x39,0xfc,0x03,0x55,0x76,0x8c,0x57,0xea,0xe8,0xc1,0x25,0x09,0x69,0xc0,0xe8,0x54,0x91,0xc1,0x7c,0x52,0x8e,0x82,0x6d,0xf2,0x0e,0x3f,0xa9,0x98,0x04,0x40,0xda,0x1c,0xc0,0xbb,0x42,0xf0,0x7d
+.byte 0xed,0x78,0xb0,0x4f,0x94,0xba,0x0d,0xbf,0x60,0xbe,0x09,0x67,0x42,0xc5,0x41,0x4c,0x80,0x8d,0x30,0x10,0xa9,0xd2,0x07,0x8c,0xa8,0x40,0xc6,0xe2,0x08,0x42,0x7f,0x99,0xad,0xc5,0x66,0x1f,0xfd,0xd2,0xc5,0x79,0x77,0x9b,0x60,0x7d,0x25,0x2d,0x69,0x14,0x94,0xa5,0xf0,0x0a,0x14,0xb6,0xf9,0xbe,0x3a,0x4a,0x3d,0xc6,0x45,0x2e,0x27,0x4a
+.byte 0xd1,0x1d,0xcf,0x08,0xee,0x93,0x3c,0xb5,0x8a,0xee,0xdd,0xf3,0x33,0xa6,0x35,0x9d,0xd8,0xb4,0x68,0xc5,0x98,0x09,0x78,0xcc,0xb3,0xeb,0x0f,0xcd,0x25,0xf8,0x17,0x9c,0x45,0x77,0xc7,0x06,0x40,0x44,0x90,0xec,0x6a,0xd9,0xf5,0x05,0xd4,0x88,0x17,0x47,0xeb,0x29,0x85,0x32,0x76,0x7b,0xa4,0xe3,0x65,0x30,0x50,0x9a,0x99,0x26,0x91,0x60
+.byte 0xb0,0xb8,0xe5,0x8d,0x35,0x9e,0x9a,0x13,0x65,0x82,0xb2,0x4b,0xf1,0xed,0x1f,0xb7,0xb4,0xc0,0x03,0xe6,0x1d,0x2b,0xaa,0x1e,0x01,0x92,0x0b,0xcb,0x34,0x77,0x80,0x94,0xc2,0x4e,0x3b,0x73,0xd8,0x2e,0xd8,0x95,0x33,0x05,0x65,0xa2,0x99,0x29,0x7a,0xd1,0xb3,0xed,0x5a,0x8d,0x4d,0x6a,0x6d,0x69,0x2b,0x5a,0xa1,0x3a,0xc0,0x81,0x96,0xf1
+.byte 0xc2,0xa7,0x4e,0x07,0x90,0x04,0x99,0x70,0xea,0x1a,0x3a,0x26,0xb5,0xed,0x92,0xbd,0x57,0x80,0x11,0x06,0xf2,0xb4,0x05,0x69,0x7a,0xbf,0x27,0xa1,0xbd,0xdb,0x09,0xe5,0xb3,0x2d,0x86,0x41,0xcc,0x5d,0x68,0x37,0x9e,0x98,0xa5,0x4a,0x20,0x8a,0x5f,0x54,0xae,0x4f,0x73,0xd0,0x22,0x18,0x8d,0x2b,0x91,0xcb,0xbb,0x83,0x1e,0x04,0x93,0xc8
+.byte 0xc3,0x89,0x35,0xfd,0xda,0xeb,0x52,0x53,0x9f,0xdc,0x33,0xf0,0xe0,0x99,0x19,0x11,0xeb,0x55,0xd3,0x3c,0x5f,0xca,0x29,0x52,0xe7,0x6b,0xd1,0xad,0xeb,0xed,0x8e,0x68,0x82,0x91,0x85,0x81,0x68,0x70,0x78,0x61,0x1e,0x0c,0x09,0x3a,0x82,0xdc,0xdb,0x26,0x66,0x1c,0xa3,0x80,0x99,0x23,0x8a,0x45,0xd7,0xb8,0x10,0x97,0x80,0x70,0x49,0x78
+.byte 0xa9,0x4c,0xf0,0xec,0xcc,0x05,0xd0,0x6a,0x6a,0x1a,0xa0,0xf7,0xde,0x78,0xc6,0x42,0xbe,0xbd,0xa0,0x24,0x1d,0x3f,0xdd,0xfb,0x92,0xc2,0xbd,0xd6,0x5c,0x25,0x74,0x3d,0x2b,0xb8,0x60,0x67,0xdb,0x70,0x1e,0xe8,0x9f,0xcd,0xb4,0x82,0x90,0x9e,0x2a,0x94,0xa5,0xa2,0xd4,0xd2,0x24,0xa7,0xca,0xbf,0xe1,0x8b,0xab,0xf3,0xd2,0x7c,0xa6,0xc8
+.byte 0xe6,0xaf,0xef,0xe3,0x86,0xb1,0x42,0x1d,0xc6,0xa2,0x37,0x9b,0x26,0x46,0x0b,0xfd,0xee,0x88,0xa4,0xf1,0xa8,0x72,0xaf,0xda,0x30,0x56,0x22,0xd3,0x1b,0x31,0x76,0xd7,0x03,0xef,0xf3,0x98,0x16,0x4d,0x36,0x57,0x1b,0xd5,0x90,0xb8,0x67,0x50,0x7f,0x22,0xa8,0xdc,0x9c,0xf1,0x6e,0xa4,0x65,0x45,0xf0,0x73,0xd8,0x7e,0x41,0xb0,0x68,0x52
+.byte 0x00,0x0a,0xda,0x99,0x6c,0x84,0xce,0xf0,0x73,0x65,0x93,0x52,0xc8,0x4b,0xb4,0x72,0xda,0x2c,0xa1,0x47,0xb5,0xe3,0x00,0x63,0xc0,0x4e,0x84,0x16,0x00,0xe6,0x1f,0xbd,0xba,0x49,0xcb,0xd3,0x7d,0xd2,0xeb,0x4a,0xb2,0xd5,0xb2,0x53,0x96,0xfb,0x04,0x73,0xc0,0x09,0x31,0xf3,0xf2,0xc0,0xd3,0xa6,0xe1,0xea,0xe1,0x58,0xbe,0x90,0xc9,0xfb
+.byte 0x6e,0x13,0x69,0xbe,0x17,0xd4,0x16,0x5b,0xcb,0xf4,0x93,0x0a,0x38,0x46,0xea,0x64,0xad,0xb0,0x0d,0xc0,0x3b,0xfc,0xe3,0xd4,0x20,0x75,0x0c,0x3e,0x71,0x1b,0x5f,0xde,0xff,0xd6,0xfa,0x6f,0xe4,0x10,0xb0,0x14,0x05,0xaa,0x05,0x70,0x5e,0xbd,0x58,0x9f,0x3c,0x9d,0x4f,0xa7,0x5a,0x65,0x57,0x02,0x05,0x44,0xe0,0x95,0x9d,0xa2,0x60,0x06
+.byte 0xcb,0xfd,0x91,0x8e,0x7f,0xce,0xa1,0x80,0x94,0xbb,0x88,0xf2,0xa6,0xe7,0x83,0xf9,0x38,0x8f,0x09,0x8e,0xe4,0xa9,0xc2,0xc7,0x84,0x9d,0x25,0x09,0x52,0x8b,0x32,0xaa,0x3b,0xde,0xb6,0x82,0x9f,0x6d,0xc4,0xdf,0x11,0xf7,0x72,0x1a,0xe4,0x00,0x51,0x41,0x01,0xba,0x21,0xea,0x0a,0xda,0xf2,0xbb,0x66,0xae,0x51,0x2b,0xb0,0x6d,0x1d,0xe8
+.byte 0x4b,0x1e,0x42,0x68,0x3a,0xed,0xe6,0x59,0x13,0x42,0x07,0x54,0xae,0x2e,0x15,0x93,0xd7,0xff,0xad,0x49,0x09,0x41,0x52,0x6b,0x3b,0x9c,0x41,0x43,0x0d,0xed,0xed,0x6f,0xb8,0xe9,0x0d,0xcc,0xde,0x0d,0xaa,0x91,0xef,0x89,0x2f,0x2d,0x94,0xd0,0x03,0x2b,0x51,0x7f,0x85,0x9b,0x7b,0x08,0xc8,0xb6,0xe2,0x82,0x22,0xa9,0x57,0x71,0xf2,0xae
+.byte 0x08,0xfa,0x6c,0xd8,0xca,0x78,0x42,0x98,0x23,0xfd,0x38,0x4b,0x6c,0xd3,0x9f,0xc6,0xa3,0xb2,0xc1,0x8c,0x4a,0xa3,0xcd,0x9f,0x56,0xe7,0xc2,0x06,0xd7,0xc5,0xc2,0xd9,0x98,0x57,0xc8,0x5a,0xaa,0xf4,0xaa,0x44,0x02,0x83,0x11,0x1e,0xf6,0x64,0x8d,0xf7,0x3b,0x86,0x3c,0x04,0x53,0x5f,0x62,0xc8,0x7a,0x0e,0x1c,0x4f,0xa8,0xe3,0x5c,0xe8
+.byte 0x64,0xf7,0xe3,0x5d,0xea,0xb5,0x2d,0xdb,0x7b,0x0e,0xdb,0x91,0x34,0xd5,0x87,0x4f,0xe6,0x73,0xee,0x3d,0x79,0x7c,0x67,0x48,0xb5,0xbb,0x42,0x96,0x0d,0x9d,0xbd,0x68,0x98,0xe5,0x59,0x51,0x16,0x45,0x15,0xac,0x80,0x41,0xae,0x45,0xdb,0xe4,0x2a,0x44,0x0d,0xe4,0x25,0xc7,0xd3,0x06,0xf7,0x98,0x15,0xe1,0xc5,0x9b,0x34,0x0e,0x87,0xb8
+.byte 0x90,0x1b,0x24,0x84,0x06,0x24,0xb0,0x80,0xbe,0x03,0xa0,0x95,0x10,0x1e,0x72,0xde,0x0f,0xd4,0x15,0x7b,0xa0,0xf5,0x42,0xc3,0x6f,0x10,0xe9,0x76,0x44,0xe3,0xa9,0xb7,0xef,0xf6,0xc2,0x80,0xe2,0x0c,0x2d,0xad,0xe0,0xb9,0x45,0xca,0x67,0x6f,0xb6,0xc5,0xc0,0x8d,0x25,0xee,0x50,0xeb,0x51,0xc6,0x87,0x87,0x61,0x3a,0x75,0x95,0x41,0x47
+.byte 0x26,0xfd,0x35,0xf6,0x46,0xf4,0xe9,0x42,0xc6,0xef,0x37,0x97,0xb3,0x0a,0x1d,0xc8,0xdf,0x07,0x24,0xb1,0x0d,0x07,0x43,0x67,0x7d,0x81,0x09,0x58,0xdd,0xf6,0xcf,0xf1,0x47,0x42,0xbd,0x3c,0xa3,0xd7,0xe8,0x73,0xf9,0x5b,0xff,0x2c,0xcd,0xe6,0xd1,0xe9,0x47,0x6d,0x19,0x9b,0x6a,0x63,0x69,0xf4,0x4a,0xdf,0x69,0xab,0xa9,0xb7,0xe5,0x8d
+.byte 0x1c,0x44,0x52,0x0c,0x7e,0xa1,0xfe,0x9d,0xd5,0xa4,0x71,0x62,0x0b,0x3c,0xf6,0xd2,0xd3,0xe9,0x70,0x09,0x68,0xf7,0xd6,0x0a,0x00,0x61,0xf1,0xf3,0xd0,0x41,0x4a,0x14,0xc6,0xf5,0x49,0xb1,0xde,0x10,0xd3,0x20,0x8b,0xfe,0x78,0x6a,0x87,0x79,0x15,0xd3,0x43,0x00,0xbe,0x71,0x40,0xaa,0xca,0x1a,0x64,0xe3,0x96,0x34,0x2f,0xea,0x0c,0x11
+.byte 0x41,0x21,0xf8,0xa7,0x65,0x9b,0x75,0xe2,0x1e,0x6f,0x5e,0xe0,0x68,0x42,0xca,0xd3,0x19,0x35,0xe8,0x88,0x0f,0x05,0xa3,0xb1,0x73,0xea,0x53,0x79,0x40,0x24,0x00,0x86,0x20,0xbb,0x25,0x58,0x89,0x6b,0xde,0xd6,0xd0,0x36,0xbb,0x33,0x30,0x59,0x4b,0x30,0x92,0xac,0xe5,0x95,0x94,0x22,0xab,0xc1,0x10,0x35,0x9c,0xa1,0x20,0x11,0x5d,0x4f
+.byte 0x57,0x5c,0x9c,0xb8,0x3a,0xdc,0x97,0xa5,0xf3,0x0b,0xf5,0x96,0xe7,0xef,0x90,0x72,0x01,0x52,0x70,0x5a,0xf0,0xd9,0x7e,0x59,0x05,0x8c,0xd1,0x45,0x47,0xbf,0x16,0x15,0xa2,0xc9,0xdd,0xe7,0x5f,0x4b,0x94,0x5f,0xe6,0xf9,0x78,0xbb,0x8f,0xf9,0x79,0x9f,0x5e,0xd7,0x1f,0x0b,0xef,0x8d,0xfe,0x75,0xd4,0x8a,0x12,0x28,0xa5,0xf9,0x6e,0x14
+.byte 0x3c,0x52,0x80,0x57,0xc6,0x96,0xae,0x67,0x27,0xc1,0x1c,0xb6,0xd6,0x1c,0x74,0x8c,0x6f,0xc7,0x71,0x3e,0xd5,0x73,0xf2,0x3e,0x02,0x15,0x67,0x18,0xb8,0x5b,0x61,0x9e,0xfa,0x7e,0xba,0x00,0xe9,0xd9,0x51,0x91,0x63,0x7e,0xf7,0xab,0xc0,0xc6,0xee,0x66,0xdd,0x66,0x88,0x7a,0x8a,0xc5,0xc2,0x08,0x45,0x62,0xde,0xe1,0xfb,0x35,0x65,0x34
+.byte 0x00,0x9e,0x1d,0x25,0xdf,0x69,0xb6,0xe3,0xfe,0xbb,0x13,0xac,0xd3,0x13,0xb2,0x64,0x5a,0xf3,0x47,0xf1,0x36,0x55,0x5f,0x1b,0x87,0xea,0x5d,0x5c,0xfd,0x8a,0x68,0x69,0x8a,0x00,0x9f,0x83,0xbe,0x79,0x7d,0x01,0x9e,0xf2,0xb2,0x5d,0x56,0xe0,0xe6,0x49,0xe5,0xe1,0x76,0x57,0x7a,0x85,0xac,0x94,0x16,0xe3,0x68,0x05,0x14,0xb5,0x33,0x54
+.byte 0x64,0x5a,0xbe,0xa3,0x04,0x90,0x5c,0x1c,0xf8,0x97,0x16,0x36,0xce,0x76,0xe7,0xf0,0xaf,0x8a,0xea,0x65,0xa8,0x15,0x5b,0x1e,0x0a,0x91,0xad,0x62,0x62,0x67,0xb4,0xf0,0x94,0x1f,0x64,0x50,0xa8,0xc0,0x6b,0x38,0x80,0xd7,0x53,0xbb,0x70,0xbd,0x54,0x01,0xb0,0xa5,0xbc,0x00,0xe0,0xd6,0x23,0x37,0xe6,0x9f,0x0f,0x2f,0x96,0x21,0xc2,0x90
+.byte 0x55,0x26,0x55,0xa4,0xcd,0x3e,0x54,0x6b,0xa6,0xb0,0x2c,0xf2,0xd4,0xcc,0x6a,0x44,0xea,0x18,0x61,0xc5,0x1a,0x8e,0x60,0x64,0xf4,0x5f,0x21,0x36,0x01,0x5d,0x9f,0xc4,0x2c,0x67,0x1c,0x48,0x94,0x16,0xae,0xa8,0x13,0x5c,0xee,0x18,0x88,0x61,0xe4,0x54,0x6b,0xa2,0xe8,0x7f,0xf0,0x15,0xc3,0xce,0xbc,0x5b,0x91,0x25,0x7b,0x1d,0xd3,0x9f
+.byte 0x13,0x1b,0x01,0x5d,0x43,0xe8,0xa1,0x77,0x5a,0x87,0x79,0x8b,0xd5,0x69,0xf7,0xdf,0x66,0xa2,0x84,0x0c,0x66,0xac,0x15,0x65,0xbf,0x74,0xc0,0xd2,0x78,0x6a,0x3a,0x9c,0x98,0x62,0x04,0x41,0x95,0xb2,0x23,0x59,0xc6,0xb0,0xc5,0x22,0xc0,0xfa,0xaa,0xc8,0x94,0x73,0x91,0x5b,0x64,0x1b,0x74,0xbe,0xcb,0xa1,0x81,0xb1,0xc1,0x26,0xa1,0x94
+.byte 0x55,0x04,0xb3,0x9c,0x80,0xb7,0x00,0x6f,0x36,0xc7,0x7f,0x6d,0x97,0xea,0xf3,0xf5,0x55,0xc5,0xfe,0x61,0xd9,0xb1,0x6d,0x8c,0xa1,0x02,0x08,0xb3,0x41,0xe6,0xe6,0x57,0xc6,0xff,0x6e,0x47,0xa4,0x22,0x2e,0x2d,0x21,0x53,0xbe,0xe3,0xbe,0x15,0xec,0x23,0x9d,0x87,0xe0,0x2e,0xcc,0x6c,0xd0,0xc7,0xb7,0x3d,0xa4,0x07,0x5f,0x69,0x4e,0x2b
+.byte 0x07,0x69,0x4f,0xc5,0xa3,0x66,0x52,0x91,0x8f,0xa4,0x48,0xb9,0x40,0x76,0xd9,0xcb,0x6e,0x1a,0x35,0x9e,0x50,0x9f,0xd1,0x78,0xb2,0xb8,0x0d,0xa8,0xf8,0x6e,0x07,0xa5,0x3a,0xdf,0x3c,0x32,0xa6,0x10,0xbd,0x73,0x2f,0x07,0x45,0x66,0x0f,0x61,0xce,0xc2,0x08,0x19,0x98,0x33,0x4b,0x59,0x81,0xb5,0x78,0x4f,0x46,0x88,0xae,0x29,0xf8,0xf5
+.byte 0xc2,0x29,0x6f,0x8f,0xe5,0x8f,0xb0,0x53,0xc8,0x7a,0x48,0xda,0x6f,0x7e,0x8a,0x69,0x68,0xab,0xba,0xd9,0x20,0x0f,0x96,0x69,0x41,0xa6,0x92,0x94,0x8e,0x0f,0x86,0xdf,0x8d,0x70,0xaf,0xfe,0xf1,0x20,0x50,0x01,0xff,0xca,0x30,0x24,0x67,0x4a,0x04,0xa2,0xde,0x06,0xdc,0x26,0x1e,0x17,0xbc,0x52,0x9a,0x62,0x72,0xc1,0xd8,0xd7,0xe0,0xed
+.byte 0xcf,0x4b,0x13,0x80,0x9a,0xbf,0x72,0x4f,0xf4,0x24,0x26,0xcd,0xe0,0x21,0x99,0x7b,0x5c,0x4f,0xbf,0x5c,0x41,0x08,0x8b,0x17,0x69,0x62,0x60,0x2c,0x74,0xb0,0x2d,0x22,0x7e,0x25,0x95,0x6a,0x84,0x0f,0x45,0x8f,0x9a,0x92,0xa1,0xcd,0xa5,0x50,0xf0,0x52,0x7f,0x60,0xd8,0x91,0xe1,0x17,0xe1,0x66,0x8f,0xd3,0x1f,0x41,0x7f,0x6f,0xf1,0x72
+.byte 0xa3,0xb6,0x12,0x62,0x46,0x16,0xea,0x26,0x9e,0xda,0x61,0x13,0x0b,0x17,0xf7,0xe1,0xec,0xc0,0x38,0xfe,0x40,0x31,0x6b,0x38,0x2a,0x4b,0xa5,0x8e,0xfb,0x99,0x60,0xd6,0x4a,0xbd,0xfb,0x75,0x2b,0x41,0xd4,0x33,0x5d,0x35,0xfe,0x2d,0xfc,0x1a,0xac,0x02,0xb3,0xf0,0xa2,0x6d,0xfa,0x8b,0x12,0x99,0xdd,0x54,0xf2,0x1c,0x35,0xd3,0x60,0x5a
+.byte 0xdb,0x65,0xa7,0x58,0x1b,0x82,0xb4,0xf6,0x49,0x77,0xf2,0xea,0xa3,0xa9,0x57,0x94,0xb7,0x6e,0x19,0xda,0x7e,0xa5,0x70,0xb8,0xff,0x39,0x81,0x7d,0xfa,0xea,0xd6,0xc6,0x12,0x84,0x0a,0x8a,0x16,0xde,0x99,0xa6,0xe7,0xe0,0x77,0x76,0xb8,0xa3,0x6f,0xfb,0xb4,0x8f,0xc3,0xbd,0x90,0xd8,0x2a,0x04,0xed,0x42,0x91,0x9b,0x84,0x40,0x2d,0x01
+.byte 0x94,0xdb,0xbb,0x58,0x25,0xed,0xa3,0xdd,0xaa,0x0c,0xce,0x25,0x12,0xcd,0x11,0xbf,0xd0,0x57,0xe9,0x51,0x74,0xa7,0x45,0x6c,0x58,0xe7,0x4d,0x43,0xc6,0xd0,0x09,0x93,0x2d,0xe0,0xe3,0xae,0x7b,0x8f,0x53,0xa0,0x80,0xa1,0xef,0xcb,0xf5,0xfe,0x38,0x4d,0x31,0xa2,0x5c,0xd3,0x4a,0x66,0x1a,0x5c,0x07,0xbe,0x25,0xba,0x30,0xb6,0x00,0x27
+.byte 0x52,0xb9,0x1f,0xa3,0xed,0xd7,0x31,0x33,0x4a,0xf6,0x3f,0xed,0x75,0xe7,0xa4,0xf4,0xdf,0x97,0xc1,0x78,0x90,0x9b,0x4b,0xbd,0x06,0xc6,0x72,0x5c,0xdf,0x57,0x60,0xbe,0xbc,0x88,0x02,0xb6,0x5a,0x65,0xea,0x3a,0x3a,0x74,0x03,0xc8,0x66,0xef,0xf0,0x63,0xc7,0x9d,0x58,0x8e,0xa1,0xb2,0x25,0x4f,0xc4,0x14,0x5f,0x80,0x78,0x08,0x06,0x21
+.byte 0x50,0x34,0x01,0x2b,0x15,0xf4,0x7d,0x1f,0x1f,0x32,0x36,0x0a,0x52,0x1f,0x50,0xa2,0x50,0xbc,0x9a,0xdf,0x4e,0x84,0x49,0x2d,0x08,0xaa,0x46,0xc0,0x0e,0xcf,0x27,0x17,0x91,0x78,0x8c,0xb9,0x72,0xc5,0x8e,0x25,0x85,0x11,0xff,0x2f,0x4a,0x71,0x7c,0x14,0xfe,0x86,0xfe,0xb4,0x3a,0xd0,0x67,0xfd,0xaa,0x9b,0xee,0x89,0x66,0x03,0x59,0x4e
+.byte 0x1c,0x96,0xaf,0x2b,0x8d,0x4d,0x6f,0xf6,0x72,0xc6,0x13,0xc7,0x14,0xce,0x19,0x0c,0x0b,0xa3,0x01,0x12,0x7c,0x8e,0x10,0xb8,0x63,0x41,0x57,0xb9,0xfe,0x6e,0x3e,0xda,0x20,0xfb,0x92,0x08,0x7d,0x66,0x31,0x9d,0x4f,0xdb,0x14,0xf4,0xb6,0xb8,0xea,0xee,0x54,0x0f,0xaf,0xc1,0x99,0xf0,0x8f,0x55,0x44,0x20,0x44,0xd0,0xa6,0x98,0xa3,0xa8
+.byte 0x8b,0x8e,0x26,0x03,0xec,0x2d,0x50,0x4f,0xb0,0x8d,0xd0,0xf2,0x96,0xcc,0x18,0xa9,0xb1,0x0f,0x79,0xe3,0x9f,0x08,0xb3,0x53,0x0b,0x9c,0x9f,0x22,0xdb,0x45,0x57,0xd6,0xaa,0x3b,0x6a,0xcb,0xdc,0xc9,0xda,0x57,0x75,0x65,0x0a,0xc1,0x17,0xb3,0x97,0xa9,0x07,0x40,0x20,0xfb,0x72,0x2d,0xc6,0x37,0x1e,0x44,0xb7,0x7e,0x0b,0x38,0xcc,0xfc
+.byte 0xa0,0xed,0x48,0xa9,0x9b,0x87,0xbc,0x71,0x0f,0x8b,0xda,0x4f,0x09,0x27,0x1e,0x3d,0x9c,0x03,0x62,0x81,0xa8,0x7c,0x7b,0x8a,0x14,0xa7,0x22,0x69,0xa8,0xba,0x0e,0xcc,0x1f,0x2b,0xb3,0x0f,0x7d,0xce,0x3f,0xec,0xb5,0x9d,0xe0,0x3a,0x67,0x56,0x08,0x5d,0x03,0x8b,0x71,0x01,0x44,0x11,0x1b,0x7b,0xcf,0xcc,0x2e,0xfc,0xa5,0x52,0x9b,0xeb
+.byte 0x1e,0x8a,0xa1,0x86,0x64,0xcf,0x32,0x03,0x6b,0x3e,0x29,0xe7,0x9a,0x16,0x7e,0xe2,0x21,0x2f,0x5f,0xe2,0x86,0x7f,0xf8,0x22,0x36,0x10,0x99,0xc8,0x27,0x43,0xa1,0xb9,0xf4,0xb4,0xb8,0xe1,0xa3,0x1d,0x80,0x9c,0x81,0x92,0xef,0x1f,0x28,0x54,0x51,0xf3,0x62,0x9c,0x7a,0x24,0xd4,0x5a,0xdc,0x38,0x4f,0xa5,0x57,0xdd,0x4d,0xa1,0x52,0xf3
+.byte 0xd3,0x9d,0xa1,0x93,0x5e,0xbe,0x9b,0xd1,0x2a,0x52,0xf1,0xbb,0xa5,0x3f,0x3a,0x94,0x7c,0x7d,0x41,0x61,0x36,0x14,0x25,0x5f,0xab,0xef,0x32,0xf3,0x0f,0x6c,0xc5,0xf5,0x5f,0xe5,0x88,0x51,0x17,0x60,0x8b,0xd5,0xa6,0xea,0x8b,0x21,0xec,0x1a,0xa7,0x69,0xa0,0x59,0xf9,0xeb,0x51,0x94,0x70,0x2b,0x96,0x2e,0x71,0xa9,0x8c,0x12,0x15,0xce
+.byte 0x7d,0x59,0x6b,0xf2,0xca,0x2c,0xbd,0x85,0xfb,0x23,0xab,0xcb,0x89,0x89,0xda,0x28,0x49,0x7e,0xfc,0x90,0x2a,0x9a,0x3d,0x6d,0x24,0x57,0xba,0xd9,0x30,0xe0,0x10,0x04,0xb1,0x7f,0x8a,0xcf,0xc8,0x27,0x63,0xd6,0xbd,0xea,0xef,0x90,0x6f,0xc2,0xfc,0x78,0xfd,0xc4,0x5b,0x45,0x0c,0x41,0x8a,0x53,0x5b,0xbc,0x62,0x32,0x86,0x7f,0x19,0xb7
+.byte 0x8b,0x03,0x50,0xed,0xca,0x8e,0x8b,0xa0,0xe3,0xc2,0x0e,0x81,0xe5,0x8a,0xe8,0xf1,0x6a,0x0b,0x1a,0xa7,0xb6,0xed,0x74,0x23,0x34,0xad,0x5b,0xd8,0xf7,0x17,0x8d,0xa5,0x05,0xf3,0x00,0x4a,0xad,0x7e,0x91,0xc9,0x6b,0x13,0xff,0x76,0x78,0xf0,0xd1,0xf4,0x99,0x43,0x73,0xd9,0xba,0x59,0xbe,0xb5,0xa3,0xbd,0x5e,0xc5,0xd3,0x88,0x06,0x9c
+.byte 0x86,0x32,0xb4,0xd5,0x30,0x77,0x78,0x8e,0xd5,0x6a,0x1d,0xeb,0xfd,0x6b,0xe6,0xf8,0x4b,0xe8,0xf3,0xba,0xbb,0x86,0x8e,0xe6,0x63,0x83,0x92,0x23,0x05,0x58,0x2e,0x61,0xdd,0x38,0xad,0x8d,0x19,0x7d,0xfa,0x7c,0x3e,0xc8,0x9f,0xae,0xea,0x6d,0x12,0xf0,0xa4,0x08,0xed,0x12,0x0c,0x97,0x87,0x58,0xd8,0xbc,0x3f,0xde,0x7c,0xee,0x0c,0xc0
+.byte 0xa2,0x2e,0xf0,0x25,0x6d,0xf3,0x30,0x23,0xa7,0xc2,0xc8,0x09,0x67,0x01,0xe1,0x25,0x26,0x46,0x38,0xf5,0x5e,0x55,0x8b,0xd6,0x43,0x6a,0xb8,0xe4,0xdf,0x0f,0x5d,0x6c,0xc3,0xb2,0x56,0x38,0xda,0xbc,0xbf,0x5e,0x85,0x8c,0xd5,0x2a,0x6a,0xe2,0xff,0x4f,0x36,0xf7,0x52,0x2c,0xe2,0xae,0x65,0x65,0xd1,0xfc,0xd3,0xc6,0xf7,0x26,0xa6,0xd0
+.byte 0x0b,0xc8,0xf0,0x68,0x5d,0x07,0x89,0x06,0xb3,0xfb,0x39,0x1d,0xd8,0xd8,0xd7,0x53,0xd0,0xc9,0x76,0x56,0xc0,0xd3,0xf5,0x66,0x80,0x5b,0xff,0x4a,0xdf,0xae,0x52,0x86,0x54,0x24,0x53,0xcf,0xcf,0xd2,0x89,0xde,0x71,0x62,0x9c,0x31,0xa5,0x3d,0x62,0x07,0xa1,0x33,0x49,0xbb,0x06,0x88,0xd8,0xa1,0xdd,0x0e,0x47,0x8d,0x72,0x00,0x2d,0x51
+.byte 0xa3,0x35,0x6e,0xb6,0x1f,0xbf,0xe5,0x42,0x68,0x6f,0x62,0xfa,0xf3,0x12,0xa9,0x1a,0xbd,0xe8,0xa4,0xf1,0x6d,0x07,0xe7,0x70,0x87,0x44,0xb7,0x3d,0xea,0xdc,0x3a,0x24,0xbd,0xa0,0x9b,0xb8,0xc5,0xa8,0xd9,0x06,0xde,0x02,0x68,0x7e,0xd5,0x2d,0x3b,0x5f,0x12,0x31,0x72,0x35,0x77,0xf6,0x10,0x6e,0x81,0x7d,0x3c,0xac,0x95,0x5b,0xbe,0x90
+.byte 0x74,0xf3,0x3e,0x9b,0x07,0x54,0x97,0xe3,0x1d,0xcf,0xe2,0xc5,0x80,0x6b,0x5f,0x0b,0x96,0x00,0x0f,0x0e,0x53,0x36,0x76,0x6e,0x99,0x0c,0x32,0xa2,0xc9,0xaa,0xa0,0xa1,0xb7,0xee,0x9d,0xd6,0x46,0xe7,0x2d,0x10,0x7a,0xf2,0x22,0x50,0x52,0xbf,0xec,0xcc,0xbc,0x0d,0x81,0x55,0x2d,0xac,0x2e,0xf7,0x99,0xbe,0x68,0x09,0xb0,0x11,0xc3,0xc8
+.byte 0xca,0x63,0xa7,0xc2,0x0f,0x37,0x2a,0x9e,0x85,0x79,0x6b,0x44,0xc1,0x4f,0xb9,0xd6,0x6c,0x56,0x0e,0x59,0x33,0xc3,0x00,0x53,0xe2,0xf4,0x30,0x90,0x4e,0x4b,0x09,0x4d,0x6f,0x9a,0x9e,0xb9,0x8d,0x0b,0xa1,0x80,0xfd,0xfb,0xde,0x74,0x49,0x53,0x04,0x3a,0x35,0xcb,0x45,0xe2,0x67,0x2c,0x4d,0x6e,0x39,0x7b,0xbd,0x68,0xaa,0x93,0x1e,0xee
+.byte 0x1e,0x35,0xae,0x1e,0xf2,0xe7,0xb1,0x80,0x92,0x45,0x27,0x85,0xd0,0xc7,0x26,0x17,0x54,0x30,0xba,0x0c,0x8e,0x48,0xf3,0x08,0x51,0xa6,0x41,0x70,0xba,0x5b,0x90,0x69,0x7c,0x64,0x1d,0x61,0xb5,0x23,0x4a,0xef,0x97,0xe4,0x9a,0xd0,0xff,0x47,0x7a,0x93,0x1a,0x28,0xb3,0x8a,0x32,0x29,0xf8,0xe9,0x08,0xc3,0xf3,0x24,0xd7,0x2e,0x18,0x6d
+.byte 0x99,0x40,0x77,0x43,0x9f,0x98,0xe4,0xe5,0x3a,0x34,0x9d,0x46,0x52,0x9f,0x84,0x79,0x8c,0x70,0xbc,0x88,0x30,0xaf,0x87,0x69,0x57,0x6e,0xde,0x2e,0xfe,0x0f,0x3b,0x8d,0xc8,0x95,0xcf,0x69,0x78,0xff,0xa1,0xb1,0x81,0x49,0x1e,0x45,0xc0,0x83,0x1b,0xa3,0x5a,0xee,0x3e,0x9a,0x15,0x7c,0xf0,0xa2,0xfd,0x04,0x22,0x55,0x2d,0x74,0x61,0x29
+.byte 0x0e,0x4f,0x31,0xdb,0x35,0x99,0x37,0xb7,0x7d,0x11,0xde,0x87,0x4f,0x84,0xeb,0x6c,0x14,0xcc,0xbb,0x71,0x47,0xab,0x5b,0x61,0x51,0xeb,0xa1,0xc1,0x5f,0xe4,0x5c,0x3c,0xab,0x04,0xf1,0x60,0x50,0xe1,0xd0,0x58,0xdf,0x42,0xed,0x73,0x5f,0x31,0xdf,0x8d,0xb8,0xb8,0xdc,0x4e,0x2f,0xe3,0x7f,0x89,0x9e,0x62,0xc9,0xef,0xfd,0x60,0xae,0x58
+.byte 0xa9,0xa5,0x8b,0xa8,0x3b,0xd8,0x5f,0xd4,0x09,0xff,0x61,0x8c,0x25,0xde,0x84,0x7f,0x35,0xc9,0x5c,0x2b,0xe8,0x46,0xe4,0x1c,0xbd,0x77,0x51,0x31,0x55,0x3d,0xb4,0x35,0xf3,0xdc,0xa5,0x55,0xd3,0xe3,0x24,0xf9,0x41,0xe2,0xf0,0xbd,0xf5,0xff,0x81,0x87,0x64,0xc9,0xe7,0x69,0x29,0x86,0xaf,0x98,0x33,0x33,0x62,0x9c,0x7b,0x16,0xbb,0xfe
+.byte 0x0b,0xa7,0x92,0xa5,0x7b,0x81,0xbc,0x50,0x88,0xf6,0xe7,0xfc,0x73,0xd6,0x37,0x43,0x09,0xa5,0xc6,0xd6,0x4d,0x28,0xb5,0xaa,0x53,0x52,0x8c,0x2c,0x06,0x64,0x6c,0x21,0x6b,0xe7,0x67,0x4a,0xa5,0xcc,0xa1,0x32,0xf0,0xd9,0x78,0xb9,0xc3,0xdb,0x41,0xee,0x10,0x11,0x81,0x04,0x03,0x73,0x48,0xc6,0x3e,0x60,0x6d,0x82,0xef,0xe2,0xa8,0xe8
+.byte 0xd7,0xda,0xd9,0xb5,0x34,0x42,0xc8,0x1c,0xa7,0xa4,0x8e,0x88,0x2e,0xbc,0x96,0x0a,0xfc,0x40,0x36,0x80,0xdf,0x60,0xe9,0x03,0x02,0x0c,0x51,0xf7,0x7d,0x01,0xd2,0x21,0x38,0x44,0x4b,0x34,0x80,0xbf,0x5e,0xc1,0x86,0xf2,0x35,0xeb,0xa8,0x21,0x15,0x74,0x7c,0x99,0x55,0x64,0xf4,0x48,0xd6,0xd1,0x47,0x1f,0x4d,0xbf,0x0c,0x20,0x5d,0x86
+.byte 0xb9,0xab,0x4e,0xc8,0x86,0x08,0x71,0x1d,0x13,0xf6,0xd3,0x17,0xac,0x61,0x10,0x5d,0x2a,0xb4,0x48,0xa1,0xb9,0x79,0x5a,0x09,0x3a,0x65,0x4c,0xbd,0x97,0xbe,0x48,0xc6,0x66,0xd8,0xce,0x0c,0x19,0xb5,0x44,0x02,0xfa,0xb7,0xa8,0x3f,0x9b,0x86,0xec,0xd1,0xef,0x1d,0x7d,0xb3,0x82,0x5c,0x92,0x48,0x02,0x2c,0x56,0x0f,0xff,0xf7,0x19,0x74
+.byte 0xc2,0x38,0x24,0x8d,0xb2,0x87,0xb6,0xeb,0x49,0x50,0x6a,0x33,0x74,0x4e,0x2a,0xcb,0xf4,0x13,0x2c,0xfa,0x3b,0x0e,0x3d,0x98,0x3e,0x33,0xd9,0x55,0xfa,0xb9,0x74,0xb8,0x6f,0xc1,0xd8,0xfd,0x8f,0xff,0xb9,0x1a,0x17,0xf8,0xb6,0x21,0xc4,0x9d,0x47,0x5e,0x84,0xf6,0xe5,0xbf,0x93,0x98,0xac,0x8f,0x68,0x85,0xf8,0xe8,0x79,0x7f,0x6f,0x0d
+.byte 0x62,0x2c,0xaa,0x1e,0xe4,0xab,0x73,0xf8,0x6f,0x02,0xda,0x6b,0x3c,0x14,0x2e,0xc9,0xdb,0xb0,0x4e,0x39,0xb5,0xcf,0x05,0xae,0x9c,0x63,0x2f,0x6a,0x25,0x61,0x9d,0x40,0xeb,0x7e,0xd8,0x97,0x97,0x33,0x67,0x5c,0x78,0x84,0x68,0xc2,0x7a,0x26,0x58,0xe3,0x6c,0x0a,0x2e,0x6a,0x82,0xd6,0x43,0xed,0x79,0xa5,0x8d,0x4e,0x7c,0xf7,0x80,0x01
+.byte 0xe7,0x02,0x5e,0x3a,0xf7,0x8a,0x4a,0x85,0xe9,0x98,0x1e,0x69,0x33,0xf3,0x54,0x96,0x79,0xc8,0x03,0x0a,0x9f,0x0c,0x5d,0x66,0x44,0x88,0x3c,0xd7,0x9e,0xd1,0xde,0x01,0xfd,0x5e,0xa5,0x6a,0x82,0x00,0x36,0xe6,0x12,0xe3,0x62,0x46,0x45,0x69,0xfb,0x4f,0x44,0x8e,0xe5,0x8d,0x21,0x57,0x6a,0x61,0x8e,0x56,0xcb,0x5b,0x2c,0x5f,0x65,0x41
+.byte 0x2c,0xad,0xf2,0x98,0x34,0xbb,0x06,0x0d,0x8a,0x3c,0x34,0x0d,0xa3,0xe2,0x6e,0x86,0xfa,0xa9,0xfb,0x6f,0xbb,0x32,0xd6,0x0d,0x76,0x6b,0x77,0xf3,0x83,0x41,0xc0,0x80,0x63,0x55,0x47,0xb8,0x13,0x6b,0x99,0x96,0x08,0x9b,0xc0,0x82,0xae,0x49,0x4a,0x51,0x63,0x74,0xf2,0xec,0xfa,0x0d,0xbc,0x3a,0xde,0xf5,0x4b,0x4f,0x08,0x41,0x23,0x88
+.byte 0x14,0x88,0x6a,0x3a,0xf0,0x5f,0x0c,0x45,0x7f,0x65,0x7a,0x67,0xd8,0x17,0xed,0x04,0x47,0x60,0x0e,0x74,0x8f,0xfd,0x48,0xda,0xcd,0xe9,0xfe,0xf5,0x6f,0x43,0xcd,0xa5,0x05,0xa2,0x2e,0x78,0x5b,0xff,0xb8,0x6f,0x2e,0xfd,0x3e,0x4b,0xef,0xcf,0xe0,0x06,0x57,0x28,0xf4,0x2e,0x3b,0xb5,0x9e,0x3c,0xbd,0x63,0xa6,0x78,0x8e,0xd5,0xb8,0x81
+.byte 0x4e,0xf0,0xbf,0x14,0x65,0xc8,0x00,0x9f,0x0e,0x25,0x6a,0x7a,0x63,0x58,0xe4,0xe7,0xa9,0x82,0x16,0xc9,0x86,0x20,0x94,0x71,0x5b,0x9f,0x9b,0xc3,0xc5,0x32,0xb0,0x6c,0x2b,0x8c,0x54,0x67,0x36,0x94,0xb1,0x47,0x33,0xfd,0x9f,0x7c,0x7f,0x7e,0x08,0x51,0x1f,0x7e,0xbf,0x09,0x57,0xf3,0xaa,0x77,0x94,0xf3,0x20,0x1b,0x95,0xf6,0x04,0xb2
+.byte 0x09,0x9d,0xe2,0xbb,0x4d,0xfe,0x6b,0x99,0x06,0x58,0x40,0x84,0x90,0xfa,0x0e,0x9b,0x58,0x6d,0x02,0xbe,0x53,0x73,0xd1,0xc9,0xc7,0x31,0x2a,0x4a,0x12,0x2c,0xb6,0x1c,0xfb,0x49,0xc6,0x1a,0x93,0x33,0x1f,0x29,0x8b,0x94,0xe9,0x20,0xa7,0xe6,0x20,0xe6,0xbf,0xcd,0x5c,0xb6,0x52,0x42,0xf0,0x9c,0x6c,0x21,0x61,0x10,0xe7,0x0e,0x9f,0x33
+.byte 0x5f,0xc8,0xd0,0x20,0xe0,0x3e,0xc5,0x7a,0x10,0xf1,0xe5,0x19,0x52,0xcd,0xe1,0xa8,0x62,0x43,0x20,0x79,0xc3,0xac,0x93,0x27,0x02,0x8e,0x21,0x06,0xb9,0x66,0xd9,0xc8,0x40,0xe0,0xd1,0xf0,0x64,0x81,0xa6,0xc4,0x87,0x85,0x2b,0x92,0x1c,0xd6,0x48,0x85,0xb1,0xbe,0x78,0xf3,0x89,0xa2,0xf0,0xe5,0x39,0xac,0xbf,0x59,0x5d,0xf8,0x4f,0x74
+.byte 0x44,0x85,0x98,0x03,0x81,0x4b,0x7e,0x6f,0x5c,0xa1,0x11,0xd2,0xfd,0x30,0x7f,0xcd,0xd0,0xe2,0xcc,0xd4,0x80,0x16,0x46,0xa6,0x64,0x8b,0x9e,0xfc,0x2a,0x1a,0x65,0x5c,0x90,0x82,0xf9,0x23,0x48,0x11,0xf6,0xf2,0x50,0x3f,0xed,0x44,0xf2,0x9a,0x5a,0xca,0x1c,0x9a,0xd2,0x71,0x1b,0xd6,0x4c,0x51,0xf6,0x89,0x6f,0x65,0xe4,0x97,0x41,0x47
+.byte 0x1b,0x86,0xbd,0x83,0xa0,0xfe,0xac,0x16,0xe8,0xab,0x28,0x96,0x2f,0xa2,0x12,0x5f,0x7c,0xb3,0x18,0x2b,0x05,0x51,0x49,0xba,0xb4,0x1f,0x1e,0xe6,0x8a,0x82,0xca,0x33,0x7d,0xe6,0x8c,0x95,0xba,0x08,0x60,0x47,0x6d,0x79,0xac,0x0f,0xba,0x46,0xff,0xed,0xe0,0x34,0x03,0xfe,0xa7,0x85,0xe5,0x61,0xe3,0xe4,0x6c,0x5c,0x1b,0x9d,0x8a,0x54
+.byte 0x17,0xaf,0x08,0x4c,0x44,0x7f,0xb7,0xb0,0x6a,0x3a,0xff,0xb7,0xf6,0x10,0xc4,0x8f,0x31,0xd6,0x1a,0x25,0x27,0x35,0xca,0x87,0xa9,0x61,0x0b,0x35,0x96,0x89,0x0f,0x1a,0xbd,0x1e,0xf6,0xee,0xaa,0x95,0x16,0xe4,0x38,0x7b,0xb2,0xbe,0xea,0xc9,0x5a,0xcd,0x3b,0xb8,0x9e,0xd7,0x20,0xcd,0x3f,0x90,0xaa,0x8b,0x2a,0x42,0xed,0xab,0xc1,0x53
+.byte 0x83,0xc7,0xb8,0x3f,0xa1,0xb9,0xf4,0xf4,0xb0,0xe0,0x1f,0xb0,0xeb,0xa9,0x81,0x9f,0x31,0x67,0x1e,0x6c,0x96,0x9f,0x09,0xea,0x04,0xfe,0x37,0x22,0x87,0x60,0xb9,0x91,0x8f,0xa9,0x11,0xa3,0x68,0x5e,0x29,0x21,0x41,0xa3,0x02,0x08,0x82,0xd0,0x2b,0x66,0x6d,0x3c,0x46,0xc7,0x23,0x09,0x86,0x7f,0x53,0x11,0x3e,0x83,0x52,0x0a,0x4a,0xe4
+.byte 0x93,0xc6,0xc1,0x96,0x17,0x94,0x51,0x17,0x69,0xea,0x72,0xb8,0x85,0xde,0x7e,0x13,0x4a,0x08,0x26,0xae,0x31,0x19,0x0f,0x6f,0x48,0xa1,0xf2,0x57,0xa2,0x01,0x8e,0x84,0xee,0x63,0x23,0xc0,0x97,0x84,0xa2,0xf5,0x3f,0xeb,0x30,0x9e,0xdd,0xd2,0x43,0x24,0xa2,0x57,0xb7,0x57,0x86,0x26,0xa3,0xe6,0x6e,0xf2,0xcd,0xfb,0x7b,0x34,0x74,0x53
+.byte 0x07,0x95,0x51,0xb7,0xfd,0xf3,0xd1,0x83,0xbd,0x25,0xd6,0x2c,0x69,0x73,0x02,0x8e,0x76,0x19,0xea,0xb0,0x83,0x60,0x8c,0x53,0x9d,0x77,0x86,0x1e,0x65,0xc7,0x57,0x31,0x29,0xd9,0xa9,0x3a,0xb2,0x0d,0xd8,0xf4,0xf9,0x48,0x49,0xfb,0x3c,0x40,0x3d,0x1b,0xc4,0x8b,0x94,0x0e,0x50,0x7f,0xd5,0x39,0x5e,0x57,0x86,0xd1,0xba,0x0c,0x38,0x10
+.byte 0x01,0x5f,0x44,0xf3,0xe5,0xb0,0xf8,0xae,0x17,0xdf,0xd2,0xb3,0x10,0xc5,0x3b,0xfd,0xd9,0x68,0x90,0x9c,0x6c,0x26,0xdf,0x12,0x50,0xfa,0xbf,0x8b,0xce,0x68,0x80,0x8c,0x04,0x60,0xbf,0x34,0x81,0xbd,0x29,0xa3,0xa2,0xe4,0xe0,0x2d,0x25,0xb2,0xff,0x9f,0xd1,0x20,0x07,0xd5,0x8c,0x19,0xfa,0x3f,0x47,0xec,0xc1,0x8d,0xc9,0x36,0xf8,0x51
+.byte 0x4c,0xaa,0x40,0xe3,0x6a,0x21,0xd5,0xe6,0xa6,0xcf,0x8c,0xd9,0x10,0x47,0x66,0xfd,0x32,0x48,0x36,0x8f,0x14,0xed,0x09,0x80,0x50,0x27,0xaa,0xd5,0x1f,0x69,0xb8,0xe4,0x96,0x27,0x56,0x78,0xd6,0xd5,0x2d,0xf0,0x4f,0x14,0x30,0x17,0x9e,0x5b,0x69,0x8c,0x7c,0x1c,0x97,0x38,0x65,0x77,0x75,0x49,0xac,0x4b,0x06,0xda,0x74,0x11,0x86,0xbc
+.byte 0xad,0x01,0xf2,0x03,0x29,0x5d,0xa7,0x74,0xd3,0x44,0xae,0x1d,0xbf,0xf9,0xc5,0x5b,0x83,0x8c,0xd6,0x84,0x8a,0x8e,0xe9,0xa6,0x08,0xf4,0x88,0x13,0xcb,0x16,0x45,0x13,0x9c,0xc7,0x75,0xa9,0xa7,0x55,0x04,0x91,0xd6,0xe9,0xd4,0xe5,0x65,0xa0,0x3a,0x53,0xa0,0xfc,0x62,0xce,0x91,0x01,0xb4,0x06,0x8b,0x10,0x79,0x6f,0x2c,0xd6,0x0a,0xa2
+.byte 0x31,0x8f,0x75,0x32,0x0e,0xfa,0x0d,0xec,0xfd,0x71,0x7f,0x74,0x97,0x30,0xe9,0xee,0x9f,0x04,0x21,0xb5,0xc9,0xd1,0x52,0x2a,0x0f,0x18,0xbe,0x3e,0xbb,0x98,0xaf,0x59,0x9b,0x85,0x79,0x5e,0x52,0x93,0x1c,0x42,0x67,0x67,0x6b,0xd5,0x41,0xaf,0xba,0x09,0x3a,0xb4,0x0e,0x97,0x22,0xe6,0xbb,0xe1,0x27,0xa1,0xf9,0xf0,0xcd,0xa2,0x3d,0xdb
+.byte 0x81,0x2f,0x65,0x90,0xb7,0xe5,0xe5,0xce,0x1d,0x3b,0xfe,0x34,0x57,0xcd,0x3a,0xbd,0x19,0x59,0x23,0x12,0xf1,0xb6,0xf2,0xf7,0xc1,0xf5,0x1d,0x0b,0x46,0x8f,0x16,0x6a,0x81,0xfe,0xc1,0x97,0x8d,0x69,0x55,0x60,0xdd,0xf0,0x61,0xe9,0x22,0x30,0x72,0x1a,0x24,0x30,0xd7,0xbc,0x1c,0xfa,0x02,0x55,0xfc,0xb9,0x4b,0x0a,0xe4,0x90,0x90,0x3a
+.byte 0xe3,0xce,0xd4,0xa0,0x7d,0x21,0x5a,0xf7,0x79,0x6e,0x03,0x4f,0x4e,0x93,0xad,0xc4,0x8e,0x9d,0x9f,0x8a,0x39,0x59,0x20,0xc1,0x5d,0x6a,0x4d,0x8f,0x69,0x78,0xea,0xba,0xde,0xc0,0x87,0xb2,0xf2,0x20,0xd6,0x7a,0x9c,0xf9,0x09,0x03,0x2a,0x4d,0xb9,0x10,0xfc,0xe5,0x05,0x90,0xed,0x45,0x4f,0x5f,0x7c,0x5d,0xfa,0xe6,0x0d,0x07,0xae,0xcc
+.byte 0x21,0xc8,0x1c,0x7a,0xfb,0x1d,0xb9,0xe3,0x69,0xa1,0xb7,0x5f,0xb5,0x6a,0xb9,0x58,0x9d,0xcd,0x99,0xf8,0x38,0xbb,0xa0,0xfe,0xf8,0x41,0x51,0x72,0xce,0x76,0x89,0x59,0xa2,0xab,0xef,0xea,0xab,0x79,0xbc,0xda,0x73,0xdb,0x18,0xda,0x60,0x1b,0xc4,0xb7,0x4f,0xb3,0x86,0x21,0x2a,0xc3,0xec,0x7f,0x0e,0x89,0x16,0x0e,0xd2,0xbd,0xea,0x0e
+.byte 0xcf,0xc1,0x4b,0x2c,0x97,0x69,0xce,0xd3,0x94,0xad,0x81,0xe9,0x70,0xf4,0xf8,0xe5,0x77,0xe6,0x92,0xe0,0x23,0x38,0xd3,0xc1,0xdd,0x2e,0x58,0x77,0xc5,0xc3,0x29,0x34,0x66,0x48,0xf9,0x75,0x3c,0x8a,0x6a,0xb8,0xbf,0xf8,0xba,0xf0,0xb9,0xa1,0x81,0x0b,0xa1,0xaa,0x17,0x34,0x1a,0xbb,0xa3,0xa2,0xba,0x21,0x45,0xc0,0x1d,0x57,0x11,0x4d
+.byte 0x9b,0xd4,0x64,0x84,0xd7,0x0b,0xd6,0xfb,0x72,0x2c,0xdb,0xc3,0xe6,0x24,0xa9,0xf3,0x30,0x9f,0x21,0x05,0x1e,0xcc,0x48,0x58,0xed,0xfd,0xb2,0x34,0xe3,0xf7,0x7e,0x56,0xee,0xdf,0xa4,0xbb,0xb1,0xcc,0x7f,0x81,0x40,0xe9,0xdf,0x3f,0x82,0xc4,0x0d,0x14,0x9b,0x3b,0x80,0x15,0x24,0x6e,0xa4,0xce,0xfa,0x28,0xa7,0x7f,0x89,0xfb,0xc6,0x83
+.byte 0xe8,0x2a,0x70,0xfb,0x9c,0x75,0xb8,0xfd,0xec,0xbc,0xbb,0xf5,0xef,0x0a,0xa5,0x77,0x0b,0x38,0xa0,0x63,0xa5,0x71,0x12,0xc9,0xaa,0xc3,0xf9,0x72,0x30,0x45,0x4e,0x19,0x44,0x2d,0x09,0xf4,0xf1,0xa8,0xe8,0xde,0x58,0x87,0x70,0xa8,0x91,0x86,0xef,0x5d,0x02,0x90,0x55,0x63,0x99,0xde,0xd7,0xb7,0x5f,0x07,0x01,0xdf,0xb1,0xe5,0x55,0xf5
+.byte 0x87,0x69,0xd2,0x7a,0x71,0xbc,0x0e,0x4b,0x8b,0x98,0xf7,0xf6,0x0a,0x01,0xbb,0x9f,0x1b,0x15,0xb6,0x76,0xe0,0xc0,0x4b,0x5d,0x08,0xba,0xba,0x73,0x3f,0x36,0x5a,0x29,0xd7,0x7c,0xc2,0x87,0x03,0x75,0xff,0x26,0x21,0xae,0xbe,0x66,0x70,0xa2,0x99,0x11,0x35,0x49,0x78,0x7b,0x3a,0xfe,0x94,0xf7,0x37,0xe0,0x69,0x56,0x39,0xf7,0x3f,0x71
+.byte 0x39,0x74,0x75,0x32,0x1f,0xfb,0x3a,0x87,0x07,0xab,0xf1,0xed,0xe3,0xe2,0xbf,0x3f,0xb1,0x73,0x11,0xc9,0x34,0x4b,0xb1,0x1e,0x62,0x4e,0xc1,0x8a,0xae,0xcc,0xc7,0xb3,0xa7,0x70,0x01,0x73,0xad,0xb3,0xc3,0x59,0x70,0x14,0x31,0x94,0x9f,0x6b,0x18,0x11,0x50,0x52,0xc9,0xf0,0xf8,0x12,0x9d,0x7c,0x90,0x64,0x9d,0xd9,0x41,0xa6,0x45,0xe3
+.byte 0xc9,0x25,0x73,0xe7,0x48,0x9d,0xdc,0xe0,0x2c,0x71,0xd3,0x68,0xc5,0xab,0xac,0xe3,0x16,0x95,0xe3,0xa5,0xae,0x2f,0x57,0x60,0x4b,0x11,0x90,0xaa,0xe7,0x48,0xca,0xc7,0xde,0x2e,0x56,0x10,0x8e,0xc3,0x0a,0x7d,0x66,0xf1,0xc3,0xf7,0x2d,0xdd,0xfa,0x5e,0xb2,0xcb,0x99,0x4d,0xaa,0x4e,0x91,0xc1,0x94,0x60,0x27,0x33,0x82,0xa6,0x2a,0xba
+.byte 0x05,0x32,0x33,0x0a,0x30,0x47,0xb0,0xac,0x68,0x7d,0xef,0x25,0x09,0xcf,0x51,0xf4,0x06,0x28,0x14,0xb2,0xb4,0x1f,0xaf,0x37,0xdc,0x70,0x88,0x4d,0xb9,0xfc,0x2d,0x61,0x25,0x13,0x1f,0x32,0x48,0x6d,0xeb,0x46,0x05,0x66,0x44,0xa1,0xec,0xce,0xe9,0x51,0xa9,0xba,0xf8,0xde,0x95,0x1b,0x20,0xe1,0x21,0x75,0x4b,0x25,0x7f,0x3c,0x16,0xf7
+.byte 0xe2,0xbe,0xeb,0xca,0x2b,0x77,0x92,0x16,0x32,0xe2,0x74,0x21,0x52,0x3f,0x08,0xba,0x41,0xb0,0xd3,0xd2,0xf7,0xf3,0x29,0xb6,0x10,0xfa,0xa5,0x29,0x35,0x29,0x21,0x0d,0xec,0xba,0x5a,0xf3,0x63,0x0f,0x9d,0xbc,0x42,0x02,0x46,0xe9,0x07,0x4a,0x9a,0xe8,0xd3,0x78,0x92,0xa2,0xe5,0x03,0xec,0xd4,0xe2,0xc8,0x8f,0x92,0x4a,0xae,0xbc,0xd7
+.byte 0xdf,0x4b,0x07,0x22,0x47,0xbd,0xb4,0xb5,0xa0,0x7e,0xfb,0x21,0x40,0x62,0xb1,0x6c,0x07,0x00,0x64,0xf6,0xb2,0x75,0x5c,0x29,0x84,0xff,0x38,0x0c,0xc8,0x08,0x38,0x92,0xf9,0xad,0xd7,0xcc,0xc3,0x1c,0x03,0x80,0x49,0x39,0x1c,0xdb,0xae,0x60,0x87,0x8a,0x5c,0xe9,0x17,0xbd,0x2b,0x0f,0xa5,0xa1,0xf9,0x0d,0x4b,0x8c,0x4d,0x39,0xda,0x15
+.byte 0x8c,0xc4,0x69,0xaf,0x2b,0xb0,0xa1,0xfd,0xd9,0x65,0x3c,0x87,0x4b,0xf2,0x5a,0xd7,0xd8,0xb9,0xef,0x78,0x67,0x30,0x4c,0x6c,0x92,0xc5,0x1e,0x15,0xf8,0xd9,0x74,0x1b,0x54,0x0c,0x10,0x1b,0xb5,0x11,0x13,0xd6,0xb4,0xc0,0x53,0x03,0x2c,0x4b,0xee,0xac,0xf9,0x87,0x17,0x51,0x35,0xb8,0x1a,0xdc,0x16,0x61,0x5b,0xe9,0x5a,0x43,0x94,0x42
+.byte 0x8f,0x68,0xbd,0xb6,0x52,0x00,0x63,0xa3,0x52,0x6e,0x5d,0x8e,0xe9,0x4f,0xf5,0x69,0xd8,0x4f,0xf5,0x5c,0x89,0x7e,0x1c,0xb9,0xdc,0x7b,0x92,0x8a,0x2b,0xfc,0xb8,0xad,0xbb,0xff,0x61,0x2e,0xc0,0xdc,0xfb,0x2f,0x78,0x2a,0x50,0x32,0x9b,0x4c,0xfd,0x9e,0xab,0x80,0x5c,0x7d,0xc8,0x6b,0xb3,0x2d,0x0a,0xfe,0x43,0xa2,0x10,0x10,0x79,0xbc
+.byte 0x8c,0xa0,0x86,0x09,0x8c,0x8b,0x28,0xf3,0x8a,0xc9,0xeb,0xcb,0xb5,0x0e,0x56,0x19,0xae,0xe0,0xa1,0x22,0x72,0xc5,0xad,0x01,0x12,0x69,0xb6,0x52,0xb8,0xdd,0x36,0x25,0x21,0xae,0x73,0x06,0xc1,0xe0,0x23,0x20,0xe1,0x8e,0xe4,0x99,0xcd,0x86,0xca,0xf5,0x93,0x0e,0x6b,0xb8,0xba,0x18,0x4a,0x36,0xed,0xd0,0x37,0xc8,0xc7,0x8a,0xb2,0x63
+.byte 0x2e,0xa4,0x22,0x76,0x6f,0xf7,0xdd,0x81,0xd6,0x6f,0xcd,0xb9,0x65,0xf0,0x95,0x77,0xae,0xca,0x54,0x62,0xce,0x5d,0x47,0x9e,0x10,0x89,0xb9,0xfa,0x72,0x0a,0xef,0x24,0x17,0x45,0xb0,0xb0,0xc7,0x51,0x85,0xa1,0xb1,0x6a,0xd2,0xea,0x48,0xe2,0x6a,0x03,0x2a,0xdf,0xa8,0x0e,0x62,0xa2,0x1e,0xe2,0xa7,0x20,0x57,0xbd,0x73,0xeb,0xef,0x86
+.byte 0xc9,0xd4,0xfa,0x96,0xfe,0xfa,0xb3,0xc6,0xbf,0x7a,0x16,0xa2,0x43,0x73,0x56,0x71,0x78,0x32,0x3b,0xc1,0xd8,0x26,0xbf,0xde,0x39,0x5d,0xbd,0x3b,0xff,0xd7,0x4f,0xa0,0x67,0xa6,0x09,0x9a,0x81,0xfd,0xec,0x34,0x73,0xcd,0x90,0x15,0x8b,0x3e,0x2d,0x6f,0x7d,0xcc,0xf5,0x20,0x15,0x07,0xa8,0x2f,0xa5,0x5b,0x2b,0x4f,0xb8,0x2f,0x14,0x6c
+.byte 0x52,0x78,0xbd,0x92,0x98,0xda,0x69,0x19,0x58,0x4c,0x76,0xe4,0x20,0xb2,0x48,0xa4,0x9f,0x2f,0x4c,0x9b,0x45,0x7f,0x7d,0x1c,0x46,0xe9,0x1e,0x43,0x26,0x49,0x39,0xb6,0x42,0x3a,0x4c,0x59,0x95,0x6b,0x28,0xd5,0xbe,0xa7,0x2e,0xd0,0x0c,0x00,0xa0,0x67,0x06,0x4e,0xee,0xae,0x7f,0xc2,0xb5,0x12,0x46,0x3f,0xb4,0x35,0x16,0x2a,0xda,0xbf
+.byte 0x41,0x34,0xbe,0x30,0x2a,0x0f,0x7b,0x60,0xa6,0x8b,0xcd,0xae,0x7a,0x8c,0xd6,0x97,0xab,0x06,0x1e,0x14,0x87,0x45,0xa3,0x3c,0x9c,0xc4,0xa0,0x1d,0xee,0xf0,0xca,0xb8,0xa6,0x8d,0x37,0x92,0xad,0xbc,0xe6,0x1f,0x65,0x75,0xd3,0xbc,0x72,0x66,0xe2,0xff,0xbc,0x19,0x93,0xae,0xee,0xd0,0x63,0x6d,0x97,0x6f,0x57,0xf3,0x77,0xcd,0xe3,0x57
+.byte 0x3f,0x00,0xc8,0xe1,0x63,0x83,0x15,0x84,0xc6,0x08,0xdb,0x03,0xc9,0x27,0x47,0x4c,0x17,0x12,0x40,0x6e,0xac,0x74,0x6f,0x3c,0x22,0x57,0x36,0x29,0xbb,0x6a,0xc7,0x5a,0xfe,0x60,0x1c,0x0f,0x32,0x95,0x1b,0xf2,0x3c,0xed,0x04,0x87,0x4c,0x48,0xc7,0x63,0x79,0x24,0xb3,0x12,0xbf,0x55,0x3b,0x32,0xbf,0x52,0x4e,0x1e,0xc1,0x1f,0xf2,0xfd
+.byte 0xe6,0xb8,0x56,0x38,0x0e,0xd2,0x75,0x3d,0x41,0x99,0x0c,0x7a,0x12,0x3f,0xa7,0x3a,0x79,0xa0,0xd7,0x6f,0x47,0x97,0x7e,0x9e,0xf6,0xfe,0x29,0xc0,0x16,0x34,0x38,0x80,0x2f,0xde,0x65,0x79,0xc9,0xfd,0xa0,0x84,0xc3,0x39,0xbc,0x0b,0xbe,0x18,0xba,0x0d,0xe3,0x35,0x11,0xba,0x9f,0xde,0x5d,0x0c,0xae,0x8e,0x0c,0x0f,0x66,0x9c,0xe6,0xfc
+.byte 0x3d,0xdb,0x46,0xf1,0x84,0x57,0x62,0xb0,0x00,0xd4,0x8c,0xaa,0x93,0xeb,0xf7,0xa7,0x8e,0x82,0xba,0x89,0x67,0xbb,0x38,0xb0,0xb6,0x13,0x0c,0x96,0x22,0x9c,0x6a,0x86,0xea,0x83,0xad,0x5f,0x7b,0x3a,0x28,0xd8,0x53,0x90,0x2d,0xab,0xc9,0xbe,0x99,0xfb,0x68,0x42,0x27,0xf6,0xe3,0x5a,0xaf,0xf3,0xd6,0xee,0xb6,0xa2,0xe0,0x32,0x3c,0x1d
+.byte 0xd4,0x3c,0x2b,0x58,0xc2,0x4f,0x3d,0x20,0x39,0xdb,0x80,0x89,0x20,0x20,0x7b,0xe6,0x1d,0xd0,0xa2,0x1a,0xd4,0x88,0xc9,0xe0,0xb9,0xf6,0xb2,0xa1,0xcd,0xf2,0x67,0x60,0x44,0xd8,0xce,0x6a,0xe2,0x52,0xc3,0xf3,0x61,0xa3,0x14,0x58,0xd6,0xe5,0x43,0x4a,0x8d,0xcc,0x4f,0xf8,0x17,0xdd,0xd2,0x5d,0xd5,0x5a,0x86,0x8e,0xc4,0x74,0xdc,0x1b
+.byte 0xad,0xca,0x63,0x75,0xf0,0x43,0x41,0x16,0x02,0x49,0x6a,0x3a,0xe3,0xb9,0xa9,0xdc,0xfb,0x99,0xbc,0x60,0x0d,0xdb,0xa0,0xcf,0x27,0xaa,0xd5,0xc5,0x42,0x0b,0x02,0x00,0x43,0xaf,0xb5,0x4f,0xe1,0x88,0xa1,0x9d,0xca,0xfb,0x9f,0x1f,0x08,0x9c,0x66,0x23,0xca,0x4b,0x88,0xb4,0x40,0xdc,0xd3,0xd3,0x1a,0x64,0xe3,0x9b,0x43,0xea,0x20,0x90
+.byte 0x30,0x2e,0xc4,0x75,0xc5,0x52,0xc5,0x7c,0x0e,0x35,0x56,0xf5,0x1f,0x50,0x2b,0xf6,0x28,0x93,0x6f,0xde,0x10,0xc6,0x49,0x2b,0x77,0xb1,0x6d,0xce,0xfd,0x37,0xd4,0x8d,0x11,0xed,0x88,0x1e,0xca,0x68,0x0c,0x4e,0x38,0x7f,0x0f,0xab,0x6f,0x8d,0x1c,0x7d,0xd4,0x7d,0xd8,0xa9,0x5c,0x24,0x5a,0x7d,0xf4,0x5b,0xb6,0xb7,0x28,0xc7,0x93,0xd6
+.byte 0xa9,0xe5,0xac,0x62,0x16,0x9c,0x4e,0x5c,0x24,0xa0,0x2a,0x76,0xce,0x7d,0x5c,0x4b,0xbe,0xbc,0x83,0x5c,0x9a,0xc8,0x06,0x7b,0x1e,0xac,0x98,0x67,0x17,0x32,0x94,0xda,0xd1,0x8b,0x58,0xad,0x8e,0x26,0x03,0x81,0x7c,0x48,0xd1,0x83,0x03,0xba,0x6c,0x51,0xe9,0x25,0x82,0xd2,0xb9,0x7f,0xd8,0x33,0x3f,0x77,0x29,0x45,0x41,0xa9,0x17,0x3d
+.byte 0x62,0xc6,0xd2,0xfb,0xd1,0x24,0xc7,0xee,0x10,0xc0,0x64,0xc3,0x46,0xc6,0x2b,0xe8,0x9c,0xc8,0x99,0x23,0x77,0xa9,0xb5,0x12,0xc4,0x53,0xde,0xbc,0x20,0xb2,0xc4,0x12,0xdb,0xc2,0x0b,0x63,0x70,0x6a,0x41,0x31,0x65,0x48,0xa0,0xfc,0xbc,0xd6,0x3f,0x55,0x18,0x17,0x65,0x35,0x58,0xe3,0x33,0xac,0xaf,0xca,0xb2,0x51,0xc1,0xcc,0x60,0x38
+.byte 0x94,0x8f,0x13,0xb8,0xcc,0x8c,0xc4,0x12,0xea,0xd5,0x39,0xd3,0x46,0x55,0x17,0x27,0x7a,0x07,0x01,0x02,0x74,0xa6,0xe7,0xc8,0xa7,0xd0,0x76,0xc8,0x5e,0x57,0x50,0xc5,0x19,0xf1,0x95,0xa3,0x52,0x10,0xa3,0x1e,0xcd,0xb1,0x05,0x64,0xe5,0x69,0xd9,0x5e,0xfc,0x71,0xef,0xe1,0xf6,0xb3,0xa7,0xf7,0xf9,0x71,0xfd,0xbb,0x5b,0x2b,0x7a,0xd2
+.byte 0x72,0x7c,0xc7,0x73,0x89,0xf7,0xe2,0x0b,0xcd,0x05,0x4f,0x0c,0x10,0xed,0xcc,0xda,0xb6,0x81,0x19,0xe6,0x2b,0x06,0x66,0xef,0xc5,0xfd,0xd5,0xc6,0x66,0x20,0x86,0x2a,0x4f,0x05,0x49,0xf1,0x54,0x4a,0x6e,0x1d,0xcd,0xad,0x18,0xeb,0x6c,0x58,0xd6,0x75,0x3e,0x62,0x48,0xab,0xea,0x1f,0x7f,0x05,0x45,0x6e,0x75,0x2a,0x5e,0x97,0x5b,0xde
+.byte 0x5a,0x99,0x42,0xc1,0x62,0xab,0xc7,0x01,0x4d,0xac,0xd6,0xdc,0xc9,0x71,0x24,0xd1,0x33,0xe2,0x4b,0x1f,0x09,0x04,0x1f,0x0d,0x42,0x45,0xcf,0x7c,0xa0,0xee,0x48,0xfd,0x8b,0x1f,0xaa,0x50,0x48,0x6d,0x8e,0x34,0x76,0x09,0x23,0x8a,0x40,0x0d,0x5d,0xc1,0x2a,0xba,0x5f,0x9c,0x86,0xfb,0x37,0xdf,0x24,0xff,0x27,0x88,0xbf,0xf6,0xa4,0xc3
+.byte 0xf0,0xd3,0x02,0xa8,0x7c,0x6d,0xc4,0xc5,0x14,0xc3,0x64,0x28,0xa8,0x05,0x33,0xc2,0xda,0x12,0xfc,0xbe,0x0d,0x8e,0xf4,0xf5,0x48,0x5a,0x8e,0x8a,0xd2,0x50,0x7c,0xc0,0xbc,0xde,0xdb,0x9a,0xf6,0xa0,0x92,0x8d,0x19,0xbc,0x5a,0xdc,0xbf,0xfb,0x13,0x8f,0x41,0x09,0xba,0xd9,0x0b,0x91,0x7a,0xdb,0x92,0x10,0xac,0xf2,0xb5,0x76,0xb5,0x7d
+.byte 0x80,0x04,0xd6,0xec,0x98,0x09,0x5f,0x63,0x0d,0x58,0x00,0x8a,0x07,0x76,0xfa,0xe6,0x6e,0xdf,0xbf,0x73,0xe5,0xc9,0xe5,0x12,0x44,0x58,0xf9,0x2e,0xb1,0xe6,0x2c,0xf5,0x0d,0x94,0xa9,0x51,0x0d,0x01,0x03,0xab,0x79,0xf9,0xee,0x7e,0x10,0x4b,0xcb,0x20,0xbb,0x01,0x19,0xd6,0x12,0xd1,0xac,0x96,0xe9,0x0e,0xde,0xbf,0x7e,0x80,0xf6,0x58
+.byte 0xc9,0xec,0xaf,0xf7,0x2d,0x98,0xbc,0x2b,0xb1,0xf1,0x34,0x94,0x39,0x8e,0xbc,0x13,0x13,0x41,0x8f,0xf3,0x4e,0x4e,0x6b,0x2a,0xaa,0xea,0x70,0x5c,0xf8,0x42,0xf7,0xbc,0xfd,0xbd,0x6f,0x62,0x1b,0xcb,0xb9,0x39,0xdc,0x6a,0x47,0x81,0xaf,0xff,0x5b,0x7e,0x80,0xb9,0xbf,0xfa,0x15,0x7e,0xd1,0xc3,0xb2,0x80,0x99,0xbd,0xb9,0x30,0x8d,0xb5
+.byte 0x43,0x6b,0x7a,0x31,0xaf,0x45,0xf7,0xdd,0x21,0x8f,0x54,0xb1,0xf6,0x2d,0x7d,0x96,0x63,0x4a,0x93,0x98,0x37,0x7f,0x48,0x02,0x4b,0x0f,0x71,0xe4,0x70,0xce,0x66,0x6a,0x36,0xde,0x58,0x84,0x69,0xd6,0xbd,0x1a,0x9a,0x8b,0xc5,0xda,0x97,0xc5,0xe1,0x4e,0xec,0x9b,0x7a,0x65,0xe0,0xa5,0xdd,0x39,0x3c,0x9f,0xfd,0x45,0x17,0x4c,0x2f,0xb4
+.byte 0xb1,0xb1,0x42,0xe8,0x88,0x75,0x9f,0xb4,0xc1,0xdf,0x44,0xf9,0x4f,0x9a,0xf7,0x3d,0x35,0xc5,0x32,0xbe,0x43,0xd0,0x0d,0x71,0x4e,0x21,0xbf,0x31,0x99,0x73,0x5a,0x84,0x45,0x2e,0x00,0x8b,0x42,0x2b,0x14,0x86,0x51,0xcb,0xa0,0x98,0xa9,0x68,0x8d,0xdb,0x58,0x3d,0x73,0x9d,0xf9,0x2d,0x86,0x76,0x62,0xcb,0x93,0x29,0x48,0x92,0x38,0xfb
+.byte 0xeb,0x1d,0xda,0xc3,0x10,0x1f,0x32,0x68,0xee,0xcb,0xb7,0x8a,0xcb,0xcb,0xe0,0x37,0x31,0xe8,0xad,0x7b,0x4a,0x29,0x2c,0x10,0x9e,0xdf,0x86,0xeb,0x13,0x0c,0xab,0xa4,0x30,0x36,0xf0,0xe0,0xac,0x14,0x41,0xa4,0xf4,0xf8,0x44,0x95,0xe8,0x8f,0x28,0xc2,0x35,0x0a,0x44,0x61,0xc7,0x60,0xc5,0x3b,0xc4,0x1d,0x67,0xfd,0xac,0x0b,0x2e,0x49
+.byte 0x62,0xea,0x17,0x3c,0xf5,0x4b,0xbe,0xba,0xba,0x42,0x02,0x0d,0x13,0xf1,0x15,0xff,0x2e,0x47,0x46,0xd1,0x27,0x64,0xb7,0x35,0x28,0x31,0xb5,0xde,0x1e,0xf9,0x26,0x6c,0x04,0x3c,0x0e,0x06,0x9d,0x4d,0xc7,0x1c,0x97,0x67,0x2c,0x6d,0x36,0x0d,0x4c,0x61,0x08,0xe9,0xbd,0x04,0x1d,0x8d,0xfb,0x0c,0x03,0x3d,0xb4,0x40,0xd5,0x1b,0x69,0x3b
+.byte 0x68,0xcf,0x46,0x27,0xcf,0xb3,0xda,0x1e,0xdc,0x85,0x6f,0x4f,0x6b,0x09,0x9d,0xe9,0x6c,0x73,0x40,0x27,0xc9,0x8b,0x12,0x97,0xea,0x34,0xd7,0x51,0x32,0x90,0x4e,0xd7,0x91,0x41,0x3a,0xee,0xbc,0x97,0xb0,0x4a,0x39,0xdb,0xe3,0xe5,0x12,0x73,0xbf,0x5d,0x68,0xe0,0xc6,0x7c,0x6f,0x0d,0x14,0x1c,0xaa,0xde,0x29,0xb7,0xc7,0xa5,0x90,0x62
+.byte 0xe9,0xc5,0x75,0x16,0xe6,0xc0,0x9d,0xc5,0xb8,0xd6,0xfa,0xb0,0x72,0xb7,0x27,0xa6,0xa8,0x3f,0xbf,0x18,0x8b,0xaa,0x94,0xb3,0x47,0x50,0x2f,0x1c,0x49,0xab,0x46,0x38,0x7f,0x3e,0xf3,0xf1,0xb8,0xb3,0x44,0xaa,0x1f,0x76,0xb4,0x67,0xff,0xcf,0x7c,0x4b,0xa9,0xe1,0x62,0x93,0x4d,0x3e,0x96,0xdb,0x56,0xf6,0x26,0x5d,0x95,0x4c,0xfa,0x5f
+.byte 0x06,0x2b,0x5c,0x33,0x2d,0xf8,0xfa,0x68,0x8a,0xed,0x28,0x2a,0x6e,0x95,0x86,0x59,0x71,0xef,0x86,0x47,0x60,0xec,0x35,0x79,0xa9,0x98,0x2d,0x6e,0x20,0x26,0x3a,0x21,0xec,0x59,0x15,0x65,0xcd,0xb9,0x91,0x19,0x6e,0x74,0x89,0x3b,0x10,0x00,0xab,0x8a,0x45,0x23,0x20,0x94,0x03,0x02,0x77,0xb7,0xcf,0x9c,0x71,0x18,0x0c,0x5b,0x40,0x62
+.byte 0x3b,0x8f,0xc9,0xf6,0x4c,0x8f,0x60,0x66,0x05,0x87,0x05,0x90,0xd4,0x08,0x76,0xd7,0xa3,0xb6,0x37,0xa8,0x83,0x05,0xb2,0x48,0xe9,0x24,0xc4,0xfb,0x79,0xa1,0xce,0xac,0x29,0x13,0x4e,0x72,0xdf,0xad,0x9e,0x5b,0xcd,0x9c,0x39,0x1d,0x3e,0x57,0x9d,0xf2,0x96,0x13,0xa4,0x79,0x4c,0x76,0x40,0x03,0xb3,0x18,0xcf,0xd7,0x45,0x2a,0x2d,0x07
+.byte 0xe5,0x2e,0xb7,0x74,0xda,0x94,0xea,0x32,0x74,0xb0,0xca,0xf4,0xd1,0x09,0x97,0x3c,0x69,0x17,0xf6,0x5b,0x13,0x7b,0xb8,0xb1,0xd9,0x0e,0x12,0x44,0x29,0xea,0x26,0xd8,0xaa,0x9d,0x26,0x87,0x0c,0x89,0x4e,0xec,0x29,0x48,0x43,0x66,0x21,0x0b,0xab,0xce,0x40,0x57,0x4c,0xa7,0xdd,0x56,0xde,0xac,0x5c,0x62,0xea,0xc4,0x54,0x4a,0xe0,0x8d
+.byte 0x54,0xc8,0x65,0x44,0xcc,0x6f,0x2a,0xcd,0x0e,0xb3,0xad,0xa3,0x30,0xd1,0xb7,0x19,0x70,0x51,0xd3,0x9a,0xcf,0xe5,0x42,0x6c,0xa1,0xc1,0x0f,0xe2,0xda,0x86,0xb4,0x51,0x50,0x62,0xdc,0x51,0x3f,0xd2,0xff,0xde,0x7f,0x38,0x5a,0xff,0x2d,0x21,0x1d,0x59,0xb9,0xdd,0xde,0x83,0x13,0xb0,0x25,0xf5,0xbb,0x11,0x47,0x4a,0xaf,0x81,0x15,0xa0
+.byte 0x39,0x5b,0x30,0x17,0x2b,0xbf,0x5a,0x03,0x60,0xb6,0xbb,0x86,0x9f,0x50,0x45,0x15,0x0b,0xba,0x42,0xf4,0x3d,0x05,0x62,0xcd,0x9b,0x8c,0xcf,0x93,0x5c,0x33,0x6c,0xea,0x4b,0xd0,0x1d,0x91,0x3e,0xbf,0xa4,0x9d,0x7c,0x2c,0x87,0x9c,0x42,0x9f,0x03,0x98,0x03,0x1b,0x98,0x66,0x4f,0x8f,0x29,0x12,0xc5,0xb5,0xec,0x81,0xf8,0xb2,0x5e,0x44
+.byte 0x4f,0xb0,0x31,0xe4,0x2a,0x73,0x83,0xac,0x5a,0x3f,0xfa,0xcf,0x8b,0x7c,0xa3,0xf1,0x01,0x14,0xa1,0xca,0x60,0x8d,0x6a,0x6c,0x04,0x31,0xcc,0xba,0x12,0xe0,0x4e,0xaf,0x01,0x8d,0xf5,0x60,0x23,0x79,0x8a,0x80,0xcc,0x32,0x31,0x69,0x83,0xb6,0x83,0xaa,0xd9,0x3b,0x86,0x4a,0xd8,0x10,0x28,0x09,0x82,0x36,0xee,0x6a,0xc0,0x80,0x3f,0xfd
+.byte 0xb1,0xd2,0xde,0x34,0xf9,0x4c,0x87,0x5b,0xdd,0xd0,0xb6,0x2d,0x99,0x69,0xd3,0x2c,0xb7,0x0b,0xfc,0x16,0x88,0x7b,0x80,0x21,0xbc,0x30,0x7b,0x56,0xe5,0x7b,0x41,0x43,0x4d,0xaf,0x40,0x5e,0x74,0x14,0x17,0x66,0x32,0xd6,0x81,0x53,0x94,0x35,0xf0,0x0f,0x4f,0x99,0x54,0x9a,0x38,0xc0,0x2a,0xa9,0xd3,0x53,0xdd,0x9a,0xc5,0x29,0x18,0x62
+.byte 0xf6,0x93,0xa3,0x02,0xf0,0x13,0xcb,0xcb,0xcc,0x64,0x0b,0x00,0xf4,0x43,0x03,0x26,0xe6,0x2f,0x39,0xa1,0x83,0xea,0x94,0x2f,0xde,0x61,0xbd,0xe1,0xbe,0x08,0xf8,0xd4,0x01,0x6e,0x61,0x98,0x01,0x39,0x4b,0x93,0x39,0x38,0x34,0x58,0x24,0xc1,0xf5,0x03,0x05,0x15,0x9c,0xf0,0x30,0x20,0x24,0xd4,0x7e,0x73,0xb2,0x60,0x06,0x3b,0xd3,0xb7
+.byte 0x2c,0x47,0x17,0xc4,0x79,0x4e,0x45,0x0b,0x89,0xf0,0xfc,0x42,0xa0,0x0d,0x80,0xd2,0x44,0x36,0x70,0xaa,0x9e,0x72,0x85,0xa8,0xc8,0x1d,0x35,0x28,0xc3,0x5a,0x72,0x4c,0x06,0x6d,0xf4,0xae,0x54,0x86,0x9a,0x32,0x3c,0xa5,0x06,0x63,0xc1,0x37,0xbb,0xaf,0xa6,0xae,0xce,0x94,0xea,0x9c,0x4a,0x9e,0x56,0xb1,0xc3,0x84,0x84,0xef,0x3d,0xe9
+.byte 0x24,0xf4,0xbf,0xc3,0xf6,0x45,0x74,0x4e,0xbb,0x86,0xd3,0x7f,0xab,0x19,0xe3,0x63,0x67,0x81,0xb6,0x18,0xc8,0x78,0x8e,0xf8,0x83,0x5f,0xfb,0x2e,0x49,0x97,0x2b,0x34,0xbb,0x76,0x2e,0x93,0xec,0xe9,0x7f,0x4d,0x7e,0x52,0x0c,0x92,0xbc,0x6d,0x3a,0x34,0x9b,0x5e,0x61,0x6f,0xea,0x45,0xe7,0x5c,0x34,0x6b,0xcb,0xc0,0x31,0x61,0x64,0x9d
+.byte 0xad,0x7f,0x98,0xca,0xfe,0x3d,0xad,0xf7,0x21,0xf6,0x4c,0x2a,0x21,0x07,0x80,0x25,0xa2,0xea,0x26,0x85,0xc3,0xb1,0x74,0x04,0x7f,0xd1,0x1c,0x1b,0xa5,0x7e,0x96,0x45,0xfe,0x6f,0xa6,0x34,0xdf,0x94,0x1f,0x7e,0xfb,0xcf,0xfd,0x29,0xeb,0x3a,0xb0,0xfc,0xb6,0xd5,0x80,0x8b,0x37,0x71,0xfb,0x70,0x19,0x30,0xc4,0x6f,0xa0,0x5b,0xae,0x5b
+.byte 0x75,0x51,0x98,0x89,0x9e,0xf0,0xf5,0x79,0xaf,0x1c,0x07,0xb6,0x5e,0xcf,0x34,0x70,0x0f,0x0b,0xbc,0x0a,0xa6,0x40,0xc7,0xf8,0xe4,0xef,0xe6,0xb7,0x94,0x6e,0x98,0x75,0x22,0x73,0x5c,0xca,0xcc,0xfb,0x09,0x2f,0x9c,0xfe,0x49,0x0f,0xd3,0x65,0xfe,0xd4,0xf0,0x9b,0xeb,0x8c,0xd7,0x8c,0xff,0x4b,0x18,0x3e,0xf3,0x9d,0x3f,0xf5,0x83,0xd6
+.byte 0x1d,0x3d,0x23,0x79,0x0f,0xae,0x17,0x62,0x33,0x07,0xc3,0xac,0x98,0x07,0x72,0x9b,0xd9,0x26,0x5c,0x1a,0x9d,0xf1,0x35,0x92,0xf9,0x38,0x17,0xf8,0xee,0x26,0xf9,0x64,0xfc,0x5e,0x8b,0x80,0xce,0xdb,0x64,0xf7,0xde,0x20,0x19,0x5c,0x26,0xf6,0x23,0xd6,0x99,0x8e,0x75,0x77,0x3d,0x17,0x0f,0xea,0x31,0x5a,0x65,0x32,0x1b,0x78,0x78,0xe4
+.byte 0xfe,0x76,0xf8,0xa7,0x81,0x34,0xf1,0x2a,0x13,0x22,0xe4,0x8a,0xe1,0x42,0x5a,0x3f,0x44,0x22,0xeb,0x7e,0xcd,0x20,0xcd,0xf7,0x44,0x1a,0x87,0xb9,0x7a,0x0e,0xf8,0xcb,0xb5,0x0a,0x1f,0x6a,0xe6,0x0b,0x70,0x59,0x38,0xa3,0x6b,0x64,0x7b,0x61,0xfe,0xbd,0xa4,0xb7,0x89,0x7a,0x28,0x70,0xfe,0x9d,0x64,0x2c,0xe9,0xc4,0xc9,0x2f,0xc8,0x3e
+.byte 0xfa,0x70,0xce,0x21,0x9b,0xa8,0x10,0x6a,0x16,0xdd,0x28,0xce,0x4e,0xd4,0x6c,0x8c,0x47,0x83,0x13,0x8b,0xec,0x1c,0x76,0xdc,0x4d,0x81,0x25,0x08,0xd8,0xf9,0xde,0x66,0x1d,0xe2,0xf3,0xe7,0xdc,0x3e,0x3c,0x6b,0x98,0x25,0x55,0x88,0xe8,0xda,0x7f,0x16,0xe5,0x7d,0xad,0x8a,0x36,0x00,0xf0,0x68,0xc5,0xe4,0xfc,0xe9,0xe3,0x54,0xeb,0x4c
+.byte 0xd1,0xff,0x07,0x1a,0x5c,0x5e,0xd4,0xb1,0xff,0x7d,0xfc,0x5b,0x34,0x42,0x95,0x89,0x01,0x24,0x8e,0x30,0xec,0xfe,0x67,0xf8,0xe2,0xaa,0xd5,0x6a,0x9f,0xe3,0xc3,0xa5,0x53,0x7f,0xd3,0xf4,0x98,0xa5,0x47,0x11,0xad,0xac,0xea,0xba,0x20,0x34,0x03,0x65,0x8c,0xec,0xb6,0xa3,0x2b,0xf6,0x93,0xe1,0xc8,0xad,0x34,0x30,0x8f,0x0e,0x3b,0xf6
+.byte 0x63,0xc6,0x58,0xc3,0xe8,0xa3,0x85,0xf8,0x24,0x8e,0x21,0xb9,0x36,0x7c,0xe0,0x11,0x64,0x31,0x6a,0x6a,0xa2,0xad,0xd3,0x94,0xbb,0x13,0x5b,0xb4,0xe9,0xee,0x09,0xdc,0xfe,0xb2,0xad,0xa8,0x43,0x02,0xba,0x85,0x1f,0x56,0xcb,0xb5,0x95,0x32,0xcc,0x7e,0xe0,0x00,0xde,0xfa,0x3f,0x91,0x71,0xde,0x21,0x19,0xff,0xc9,0x97,0x43,0x95,0xd8
+.byte 0x0d,0xc2,0x8a,0xde,0xcc,0x34,0x48,0xf4,0x35,0x41,0xb8,0x56,0x52,0xce,0x06,0xb3,0xcf,0xd4,0xae,0x7a,0xcb,0xe9,0xed,0x37,0xd6,0x76,0xa0,0x77,0x04,0xfb,0xb7,0x41,0x25,0x38,0xe1,0xd1,0xb5,0xde,0x21,0xe0,0x64,0xd8,0x83,0x13,0x7b,0x4b,0xb8,0xc9,0x12,0x02,0x51,0x56,0x52,0xe9,0x1c,0x49,0x48,0x83,0xd0,0x99,0x73,0x60,0x4a,0x4c
+.byte 0x7d,0x8d,0x43,0xf9,0x06,0xa4,0xbb,0x0e,0xb6,0xdd,0x5f,0xc7,0x5e,0x35,0xcb,0xa0,0xc1,0x66,0x4a,0xe3,0x4a,0xa9,0xec,0xa4,0x5a,0xd7,0xd6,0xea,0xa5,0x20,0xa6,0xc3,0x1b,0xc0,0xa8,0xd1,0xf1,0x08,0x05,0xab,0x40,0x14,0x35,0xf2,0xdd,0x0f,0xc5,0xda,0xb3,0xa6,0xb1,0x07,0x36,0x17,0x5d,0xe9,0x96,0x23,0x96,0x46,0xd4,0xa7,0x71,0x64
+.byte 0x13,0x72,0x4e,0x83,0xe0,0x65,0x40,0x41,0xaf,0xb6,0x5b,0x00,0xa2,0xab,0x09,0x7f,0xa5,0xd5,0xc2,0xd9,0xc0,0x68,0x2a,0x44,0xdc,0x43,0x37,0x81,0xb8,0x88,0x4c,0x85,0x1b,0xb1,0x83,0xb2,0x56,0xa3,0x91,0x0f,0xa6,0x70,0x3f,0xbd,0xe9,0xda,0x40,0x9b,0xf5,0x9e,0x53,0xed,0x5f,0x84,0x70,0xd2,0x4c,0x1c,0xb6,0x87,0xd6,0xbb,0x3b,0xec
+.byte 0xe5,0x35,0x1b,0x2c,0x9b,0xf1,0xe5,0xf8,0x0e,0x07,0x98,0xcc,0x58,0x38,0x57,0x74,0xdb,0x0e,0x08,0xd9,0x56,0xe8,0x08,0x63,0x3d,0x94,0x4a,0xdc,0x59,0xfc,0x3d,0xc1,0xa4,0x36,0xc3,0xe8,0xbe,0x4b,0xd7,0x47,0x69,0x33,0xb8,0x72,0x30,0x59,0x28,0x4e,0xf1,0xc1,0x25,0xa3,0xa4,0xe3,0x12,0xcf,0x31,0xf6,0xf8,0xae,0x31,0x06,0x76,0x92
+.byte 0x64,0x87,0x8e,0xb0,0x9f,0x1d,0xf4,0x56,0x73,0xc5,0x5d,0xbb,0x80,0x0d,0x19,0x3f,0x56,0x8c,0xe4,0xd6,0x8a,0x9a,0x62,0x26,0x4e,0x8a,0x21,0x7d,0x72,0x34,0x87,0xb6,0x7e,0x49,0xdc,0xfd,0x27,0x95,0xba,0x25,0xdd,0xf4,0x58,0x2b,0x11,0x3f,0xd1,0xd7,0x13,0x1d,0xb0,0xec,0xe2,0x55,0x5e,0x72,0xea,0x36,0xc9,0xd8,0x61,0xc0,0xee,0xc4
+.byte 0x9f,0x35,0x7e,0x73,0xd3,0xf6,0xd7,0x6a,0xce,0xd6,0xd2,0x80,0xe6,0x10,0x4b,0x65,0x18,0x6f,0xab,0xd3,0x41,0xbb,0x39,0x36,0x95,0x84,0x3c,0x99,0x9a,0xfd,0xf0,0xa3,0x46,0xdf,0x48,0x7c,0xd5,0x57,0x9d,0x10,0x59,0xca,0x70,0xc4,0xb5,0xbe,0x47,0x9e,0xca,0x2b,0x49,0x54,0xbb,0x34,0x8e,0x39,0xf4,0xf8,0x8c,0xa5,0xa1,0xab,0xf6,0x51
+.byte 0xd8,0x22,0x9a,0xd5,0xc2,0x12,0xf8,0x26,0xc6,0x19,0x2a,0xa6,0x6e,0xab,0xd3,0xac,0xd1,0x21,0x97,0x67,0x3e,0x39,0x90,0x5c,0x37,0x65,0x7b,0x06,0x54,0x1a,0xb8,0x2a,0x56,0x02,0xa3,0x92,0xee,0xf3,0x38,0x53,0x25,0x4d,0x5d,0x0a,0x37,0x9e,0xbb,0xf4,0xb2,0x13,0x77,0xbb,0x93,0xa9,0x85,0xf2,0x15,0xfd,0x71,0x17,0x00,0x89,0xe7,0x7b
+.byte 0xa9,0xdc,0x10,0xd9,0xc7,0x44,0xa5,0x7b,0x3f,0x2f,0x1e,0x6d,0xa7,0xfe,0x0c,0x0e,0x83,0x3e,0x38,0x27,0xa7,0x4e,0x85,0x3c,0x84,0xfe,0x95,0x48,0x85,0x09,0x75,0x62,0x1d,0xa4,0x64,0x54,0xed,0x89,0xd5,0x28,0x62,0x52,0x18,0xef,0xf0,0x57,0x05,0x30,0xf0,0xce,0x87,0x05,0x0d,0x81,0xe8,0x2a,0x3c,0x8c,0x22,0xe1,0x4b,0x32,0x42,0x9d
+.byte 0x02,0xc5,0xe4,0x6a,0xa4,0x4d,0x9b,0xc4,0x82,0x47,0xdc,0x61,0xbd,0x82,0x01,0xcd,0x5e,0x64,0x9f,0x4c,0xe3,0x31,0xe9,0x48,0x53,0x85,0x07,0xc7,0x47,0x49,0x35,0xd8,0x6a,0xab,0x4f,0x73,0x3f,0xd3,0xde,0x87,0x29,0xac,0xbc,0x35,0x0a,0xb4,0x74,0xc2,0xa7,0x0b,0xb1,0x93,0x92,0x29,0x3b,0x3e,0xa8,0xde,0x12,0x49,0x75,0xda,0x16,0x27
+.byte 0x52,0x2f,0x93,0x23,0xd6,0xf7,0x10,0xfe,0x1e,0x93,0x97,0x06,0x9d,0xef,0x4f,0xe4,0x3d,0x5d,0xde,0x30,0x70,0x3d,0x78,0x3a,0x30,0x00,0x9b,0x77,0x12,0x90,0x62,0xda,0x32,0x9b,0x6a,0x47,0xd7,0x0f,0xee,0x75,0x18,0xdd,0x4d,0x8a,0xe2,0x35,0x5b,0x60,0xb8,0xf9,0xa4,0x6c,0x93,0x3e,0x47,0x23,0xed,0x7a,0xe2,0x58,0x42,0xd6,0x3f,0x90
+.byte 0xc0,0x12,0x38,0x8b,0x70,0xe0,0xf8,0x1a,0xb5,0x8d,0xe1,0x39,0xdf,0x93,0x25,0x72,0x2e,0xa9,0x3f,0x58,0x12,0x40,0xc4,0x92,0x46,0x08,0xf0,0x64,0xdd,0x34,0x42,0xfe,0x74,0x35,0x0c,0xda,0xef,0x06,0x0b,0x33,0x59,0xd9,0xee,0x4c,0xf9,0x02,0x3a,0x93,0x40,0xa3,0x99,0x0e,0x64,0x11,0x2f,0x52,0x9d,0x28,0x4d,0xe8,0x45,0xd0,0x22,0xd7
+.byte 0x8f,0xd6,0x28,0x8c,0x0e,0x18,0x87,0x24,0xf9,0x88,0xd2,0xc0,0xe8,0xd4,0x9d,0xa2,0x5a,0x79,0x83,0x37,0x18,0x84,0x12,0xca,0xc7,0x10,0xd5,0x5a,0xa8,0xe5,0xa8,0xe7,0x79,0xb6,0x2c,0xb3,0x90,0x6c,0xc5,0xa4,0x99,0x1b,0x85,0x29,0x78,0x0b,0x09,0x77,0x05,0xf4,0x23,0x79,0x5c,0x91,0xf3,0xe0,0xe4,0x6f,0x82,0x33,0x4e,0xa2,0x2e,0xa2
+.byte 0x65,0x79,0xad,0x98,0x36,0x34,0x72,0x97,0xd7,0x39,0x89,0x5e,0x82,0x9f,0x4c,0xe2,0xea,0x51,0x85,0x62,0x0c,0x39,0xf6,0xdc,0xc6,0x80,0x48,0xcf,0x98,0x93,0x64,0x7d,0xf9,0x63,0xf4,0xf5,0x18,0x2a,0xb6,0x04,0xb7,0x44,0xc4,0x60,0xc0,0xcf,0x3d,0x88,0xa8,0xb6,0x81,0xa3,0x99,0x2a,0xf0,0x1a,0x8d,0x76,0x20,0x1d,0xcc,0x10,0x50,0x58
+.byte 0x09,0xf9,0xda,0x65,0x60,0xc3,0xb1,0xc1,0xc0,0x4d,0x62,0x52,0x22,0x45,0x32,0xbc,0x11,0x93,0x15,0xb6,0x25,0x8f,0x65,0xa0,0x4c,0x88,0xc9,0x83,0xe1,0x5c,0xbb,0xfb,0x1a,0xab,0xdb,0x35,0x40,0x66,0xc0,0x2f,0xdc,0xf5,0x92,0x08,0x4c,0xc7,0xb8,0x49,0x05,0xe0,0xe1,0x61,0x2b,0xde,0xc7,0x6a,0x04,0x05,0x4d,0x9f,0xe9,0x59,0x22,0x56
+.byte 0x63,0x77,0x9d,0xe3,0x1e,0x36,0xdf,0x87,0x4a,0xeb,0xba,0x42,0x3d,0x1b,0xa5,0xd0,0xc5,0x44,0x07,0xbe,0x37,0x37,0x70,0x10,0x2d,0x02,0x9b,0xf6,0x52,0xf3,0x54,0x6d,0x50,0xdb,0xdb,0x57,0x01,0x0b,0x9b,0xd5,0x99,0x99,0x69,0x9b,0x10,0x76,0x48,0xea,0x28,0x27,0x06,0x30,0x63,0x3b,0xdf,0x06,0x30,0x37,0x28,0x75,0xcf,0x9c,0xe7,0x52
+.byte 0x43,0xe2,0xd5,0x7b,0xfa,0x88,0x98,0x9c,0x3e,0x27,0x30,0x21,0xcc,0x11,0x71,0x14,0x24,0x04,0x1a,0x8c,0xe9,0xfe,0x2f,0x9d,0xec,0xb1,0x10,0x33,0x05,0x31,0x01,0x1b,0xde,0x6b,0x30,0x20,0x6d,0xf4,0x7c,0xbf,0x41,0x04,0x5f,0xb9,0x9c,0x24,0x63,0x74,0x98,0x3e,0x60,0xc7,0xf1,0xb1,0xc6,0x94,0xf3,0x6f,0x95,0x24,0xdf,0x97,0xd5,0xc7
+.byte 0x50,0x19,0xaf,0xa5,0xae,0x51,0xde,0x6d,0x44,0x0c,0x90,0x72,0x11,0x82,0x04,0xf9,0xda,0x17,0xd8,0xf3,0x03,0xf2,0x03,0x3f,0x65,0x7f,0xd7,0x66,0x84,0x9a,0x02,0x90,0x2b,0x65,0x00,0xd9,0x9c,0xfb,0xaa,0xe2,0xde,0x5f,0x1e,0x19,0x1e,0x6d,0x20,0x1e,0x01,0xf1,0xca,0x7b,0x90,0x06,0x96,0x1d,0x7a,0x34,0x0c,0x66,0x57,0xd7,0x61,0x1f
+.byte 0x74,0x03,0xcb,0xae,0xea,0xaf,0x65,0x8e,0x32,0xbe,0xb8,0xe6,0xd8,0x6d,0xf7,0x51,0x6d,0xec,0x7e,0xc6,0x9d,0x20,0x01,0xbf,0xd7,0xbc,0xcb,0x34,0x7c,0xe5,0x1f,0x92,0x72,0x2f,0x6f,0xa3,0x1f,0xe8,0x4d,0x7e,0xa5,0x85,0x3b,0xed,0xc7,0x25,0x53,0xe3,0x77,0x90,0x1f,0xda,0xb7,0x48,0x7d,0xbe,0x20,0x48,0x9f,0xb4,0x05,0x5d,0x41,0xc5
+.byte 0x48,0xd0,0xc9,0x83,0xbe,0xf8,0xd8,0x6b,0x0d,0x26,0x66,0x2e,0xef,0x6b,0x13,0x58,0x6b,0x5f,0x0e,0x8b,0x4e,0x57,0xb2,0x6b,0x3d,0x4d,0xcd,0xcb,0x9a,0x9b,0xda,0x4d,0x7f,0xea,0x17,0x06,0x7f,0xcd,0xaf,0x18,0xda,0x3d,0xf0,0x30,0x2e,0xbb,0xc2,0x1d,0xcf,0xde,0xf7,0xee,0xda,0xd6,0x3d,0x75,0xcf,0x19,0xcf,0xfc,0xdf,0x7a,0xb6,0x1f
+.byte 0x89,0xf5,0x0c,0xe9,0xd5,0xf1,0xd0,0x40,0xbd,0xae,0xb5,0x16,0xf6,0x05,0x1e,0xba,0xcd,0x18,0x80,0x4a,0xb3,0x87,0x93,0x6b,0x19,0xfc,0x47,0xa8,0x45,0x4b,0x75,0xe8,0x06,0xc0,0xbd,0x86,0xf7,0xcf,0x2c,0x39,0xc6,0x0b,0x3f,0x32,0xcd,0x1c,0x02,0xec,0x4b,0xd5,0x90,0x84,0xaf,0xc9,0x5c,0x9e,0x64,0x82,0x13,0x81,0x05,0x03,0xe4,0xed
+.byte 0x48,0x23,0xc3,0x53,0x2c,0x5a,0x22,0x0a,0x27,0x7e,0x55,0x79,0xdc,0x46,0xf5,0x4b,0x04,0xcc,0x43,0x87,0x6c,0xb5,0xa4,0x2d,0x78,0x70,0x02,0x43,0x0e,0x76,0x62,0x99,0x86,0x40,0x2a,0xe4,0x62,0xe6,0xee,0x4e,0x03,0x64,0x83,0x9c,0x38,0x6d,0x62,0xa6,0x85,0xb8,0xce,0xd7,0xf8,0xcb,0x78,0x00,0x7a,0x48,0x72,0x75,0x4e,0x9c,0x6f,0x0c
+.byte 0x61,0xc7,0x93,0x4e,0x6d,0x65,0xa3,0x1b,0x17,0x84,0xc6,0xd2,0x29,0xc3,0x4d,0xe3,0x14,0x21,0x5f,0x9e,0xa9,0x28,0x11,0xf3,0xb2,0xe8,0xe7,0x60,0x9e,0x24,0xab,0x88,0x9c,0x9c,0x5e,0x17,0xe4,0xe1,0xa7,0x74,0xb4,0x82,0xd5,0xaa,0x92,0x08,0xa7,0xa2,0x04,0x6f,0x77,0x14,0x54,0x44,0x5d,0x13,0x10,0xa2,0x40,0x1d,0xf0,0x44,0x16,0x17
+.byte 0xda,0x8c,0x80,0x83,0x2b,0x19,0xb8,0xab,0xf2,0xb8,0xb1,0x92,0xb5,0xc5,0x05,0x3e,0xd2,0x1a,0xfc,0xfd,0x21,0xa6,0xb2,0xbd,0x89,0xee,0x9c,0x3c,0x90,0xd9,0xf1,0xd2,0xe8,0xc3,0x21,0xb9,0x0e,0x0c,0x98,0xbc,0x5e,0xa1,0x0d,0x89,0xfe,0x0f,0x3c,0x45,0xea,0xe1,0x6e,0x06,0x59,0xff,0x79,0xf4,0x7e,0xf4,0x82,0xc0,0x6b,0xd9,0x53,0x30
+.byte 0x98,0xed,0x8d,0x6f,0x3d,0x0e,0xfb,0x42,0x66,0xab,0x41,0xa8,0x4a,0xef,0x73,0xa4,0x54,0x99,0x4f,0xb6,0x65,0x44,0xf9,0xd9,0x3c,0x6b,0x59,0x36,0xb0,0xe3,0x7c,0x4a,0x85,0x80,0x6c,0x77,0x6f,0x34,0x4e,0x9e,0x54,0xfd,0x0c,0x25,0x72,0xc3,0x5a,0xb6,0x3b,0xad,0x2b,0xd5,0x29,0x55,0x31,0xab,0x62,0xe4,0x15,0xed,0xef,0x16,0xef,0x43
+.byte 0xd5,0xdd,0x3d,0x64,0x8c,0x13,0xbc,0xcd,0x4d,0xfb,0x4f,0x86,0x3b,0x73,0x1e,0xc4,0xe8,0x54,0xb4,0xcc,0x49,0xba,0x4f,0x81,0xcd,0xe8,0x30,0x92,0x4b,0x57,0xd1,0x7c,0x0c,0x65,0x7d,0xe1,0x59,0xc6,0x8c,0x7d,0xad,0xd5,0xcf,0x6c,0xc4,0x9d,0xc5,0x3f,0x23,0x1f,0xb0,0x6d,0x1c,0x07,0xbf,0x38,0xc9,0x16,0xdc,0x5b,0x51,0xa1,0xdb,0x8f
+.byte 0xf8,0x25,0xc6,0x4d,0xc0,0x4d,0xa1,0x02,0xd9,0xd3,0xb5,0x63,0xda,0xe1,0x91,0x60,0x71,0x39,0x46,0x1a,0x13,0xe0,0xf2,0xca,0xcc,0xd3,0xbb,0x6b,0xd0,0x64,0xaa,0x0e,0xc0,0x89,0xa3,0xc6,0x14,0x56,0xe4,0x44,0x97,0xa9,0xcc,0x17,0x68,0xe6,0xfc,0xe5,0xfd,0xf0,0xa6,0x69,0xcd,0xac,0x20,0xc7,0xeb,0x53,0x1b,0x4f,0xdd,0xd3,0xb0,0xed
+.byte 0x30,0x4e,0x36,0x73,0x63,0xef,0x51,0x3e,0x9a,0x3e,0x41,0x2b,0x9c,0xda,0x67,0x96,0x46,0x33,0xe3,0x3f,0x87,0x01,0xd8,0xc5,0x26,0x80,0xe4,0x7e,0xf4,0x78,0x8c,0x2b,0x81,0x2a,0x01,0x7c,0xe3,0xfc,0x8d,0x6b,0xdc,0x84,0xb9,0xff,0x43,0x37,0x57,0xce,0x3f,0x5e,0x63,0xd3,0xbe,0xb6,0x4a,0x31,0xbf,0xb8,0x74,0x64,0x9c,0xf3,0xc5,0x8a
+.byte 0xae,0xe8,0x5f,0x68,0xcf,0xce,0xff,0x3f,0xc5,0xb5,0xfd,0x13,0x08,0x11,0x9d,0x1a,0x0f,0x06,0x08,0x4d,0x7c,0xf9,0xd4,0x20,0xdf,0x82,0xf9,0x86,0xfc,0xf3,0x67,0xa0,0x14,0x99,0xe5,0x47,0xf0,0x02,0x7b,0x16,0xca,0xcf,0xb9,0x0f,0x68,0x08,0x5d,0x1d,0x65,0xee,0x23,0x56,0xeb,0x11,0x5b,0xca,0xf1,0xa7,0xad,0x50,0xb2,0xd1,0x37,0x65
+.byte 0xe9,0x7e,0xf6,0xe9,0x64,0x42,0x49,0x80,0x40,0x17,0xe3,0x43,0x00,0xda,0xe1,0x7a,0x1c,0xb3,0xde,0xd9,0xf7,0x33,0xeb,0xb3,0xb8,0xf5,0x40,0x1b,0xcd,0x71,0x97,0x30,0xf9,0x9c,0x4d,0xac,0x7e,0x8e,0xd9,0x36,0x92,0x39,0xb5,0x56,0x0f,0x4f,0xbf,0x58,0xb8,0xba,0xc3,0xbd,0x79,0xb0,0xd7,0x6c,0x45,0x49,0xe2,0xde,0x94,0x04,0x9d,0x3e
+.byte 0x91,0x0a,0xb2,0x9b,0x90,0x57,0x2e,0x69,0xa4,0x4f,0x61,0xbf,0xdb,0xfb,0xe3,0xe9,0x81,0x26,0xe0,0x48,0x90,0x8c,0x32,0x95,0x8d,0x38,0xec,0x8e,0xa7,0x5e,0xc3,0x36,0xc6,0xd1,0xbc,0x9a,0xb3,0xba,0xdb,0x2c,0xe4,0xa0,0x50,0x74,0xef,0x98,0x48,0x14,0xc9,0x38,0x4d,0xa9,0x48,0x13,0xd4,0x08,0x60,0xfd,0xcf,0x5e,0xf2,0xcd,0xc7,0xeb
+.byte 0xaf,0x88,0x32,0x30,0x6f,0x19,0x01,0xec,0x87,0xae,0x6d,0x63,0xa3,0xa7,0x7b,0xcd,0x53,0xa7,0xf2,0xf2,0x9f,0x43,0xcb,0x0a,0x3f,0x8c,0xd2,0x55,0x8d,0xa7,0x95,0xcf,0x5b,0xae,0x64,0x23,0xda,0xb4,0xbd,0x32,0x34,0x95,0x8a,0x03,0xe7,0x6e,0xef,0x3f,0xb4,0xcf,0xc6,0x8a,0x2f,0xc6,0x59,0x99,0xdf,0xad,0x3c,0x15,0xed,0x83,0x0b,0x59
+.byte 0x8b,0xcd,0x0d,0xa6,0xcf,0x3a,0xc3,0xdb,0xc3,0x01,0xa9,0x32,0x38,0x45,0x5c,0xc8,0x56,0x81,0xef,0x21,0x7f,0x52,0xc4,0xb5,0x48,0x97,0x6a,0x60,0x75,0x3a,0x1a,0xd3,0xb0,0x60,0x9a,0x83,0x61,0xad,0x3b,0x4b,0x65,0xaa,0x9e,0x77,0x47,0x6f,0x3b,0x48,0xb0,0xc6,0x36,0x9a,0x59,0x5e,0x26,0xc4,0xb9,0xed,0x04,0xf3,0xc7,0x09,0x33,0xda
+.byte 0x81,0x63,0xa6,0x5d,0xe1,0x54,0x6b,0x04,0x17,0x2b,0xb9,0x2f,0xbd,0x55,0xdb,0xa1,0x69,0x00,0xcd,0xba,0xfa,0x36,0xaa,0x47,0x5a,0x7c,0xf4,0x1f,0x53,0x94,0x95,0x2f,0xf8,0x2a,0x4b,0xa8,0xcc,0x73,0xab,0xfd,0x25,0xb2,0x4e,0xd6,0x62,0x90,0x8c,0x8f,0x02,0xe4,0xdc,0x22,0x79,0x04,0x34,0x9b,0x54,0x5c,0x54,0xca,0x9b,0x8a,0xf8,0x05
+.byte 0xd1,0xb0,0x9e,0x8f,0xa3,0x0b,0x53,0xa8,0x6f,0x1b,0x2e,0xf2,0x71,0x78,0x28,0xce,0xa9,0xdb,0x4c,0x5b,0x83,0xfe,0xaa,0xff,0x99,0x2f,0x03,0x14,0xb2,0xe0,0x5f,0xaa,0x65,0x15,0x1f,0xd2,0x31,0x95,0x70,0x3c,0x8b,0x55,0x8e,0x87,0xed,0xbb,0x0c,0x91,0x87,0xaa,0xbe,0x49,0xdb,0x18,0x7b,0x1d,0x26,0xa7,0xdf,0x00,0xff,0x73,0x70,0x2e
+.byte 0x10,0xaf,0x46,0xea,0x7f,0xca,0xfa,0x09,0x13,0x02,0xac,0x3f,0xa0,0x02,0xa6,0x67,0xb7,0xec,0x18,0x73,0x91,0x25,0xa0,0x28,0xe3,0xd8,0xfa,0x11,0x6d,0x34,0x79,0x1d,0xe4,0x8f,0x7c,0x73,0x66,0x77,0x3e,0x43,0x23,0xb0,0xee,0x84,0xb5,0x75,0xc9,0x23,0x87,0x6a,0x4f,0x59,0x3d,0xb5,0xf1,0xd6,0x06,0xf8,0xa6,0x5d,0x0c,0x24,0xed,0x94
+.byte 0xd7,0xa8,0x31,0x37,0x10,0x60,0xb6,0x03,0x33,0x27,0x38,0xdd,0xd3,0x74,0x02,0xa3,0xa6,0x01,0x94,0xa9,0x56,0x11,0x23,0x0e,0xdb,0xfd,0x25,0x92,0xa8,0xfb,0x79,0xc8,0x8e,0x0e,0x10,0x1f,0xca,0x95,0xf6,0xad,0x28,0xe7,0xaa,0x2b,0xf1,0x40,0xf6,0xef,0x7b,0x40,0x28,0x57,0xbb,0x4c,0xac,0x0b,0x8b,0xb3,0xe3,0xec,0x53,0xf2,0x15,0x61
+.byte 0x2e,0x91,0xdf,0x91,0xfb,0x55,0xb6,0x7f,0x6c,0xfc,0xb7,0x4b,0x91,0xdc,0xf7,0xe5,0x91,0xd8,0x70,0x92,0x94,0xea,0x3f,0x62,0x98,0x14,0xc3,0x43,0x34,0x02,0x87,0xc7,0xca,0x60,0x4a,0xfb,0x50,0xe4,0xa9,0x92,0x10,0x04,0x7c,0x55,0xd3,0x9a,0x89,0xba,0x8e,0x6f,0x02,0xd6,0xc7,0x6f,0x91,0xb5,0x87,0xb9,0x0e,0xbe,0xe4,0x9f,0x01,0x0b
+.byte 0x20,0x60,0xc8,0x16,0xe6,0x23,0x1d,0x5f,0x4d,0x82,0xf4,0x42,0x25,0xe6,0x05,0xe3,0x5b,0xbb,0xd1,0xb0,0xad,0x0b,0x05,0x71,0x3a,0x7b,0xee,0x0e,0xe1,0xe4,0x08,0x9f,0xda,0xdf,0x59,0x57,0x4f,0x05,0x5a,0x51,0x9a,0x60,0xfd,0x85,0x21,0xd1,0x0a,0x3b,0x0a,0x15,0x61,0x28,0x98,0x0a,0x8f,0x1e,0x33,0x15,0xb3,0x5f,0xf3,0xbb,0x89,0x22
+.byte 0x0c,0xaf,0x91,0xce,0x44,0xb1,0x54,0xd0,0x80,0x86,0x43,0xa1,0xb9,0x07,0xde,0xab,0x1f,0x9b,0xae,0xef,0x07,0xf2,0x40,0x33,0x31,0x4d,0xf9,0x45,0x97,0xf6,0xcc,0xe5,0x3c,0x49,0xcd,0x83,0x6e,0x38,0x81,0xab,0x40,0x18,0xda,0xf6,0xfe,0xe7,0x96,0xd1,0x17,0x98,0xae,0xec,0xe9,0x93,0x37,0xbc,0x0b,0xa8,0x12,0xe7,0x65,0xca,0x27,0x37
+.byte 0x6a,0x74,0x81,0xf1,0xe0,0x6c,0x0d,0xba,0x86,0x48,0x94,0xd0,0x72,0xd5,0x4d,0x71,0xcf,0xa8,0x5e,0xd1,0x97,0xd1,0xed,0xf0,0xd3,0xe4,0xe3,0x41,0xc9,0x8f,0xfc,0x89,0xe8,0xbf,0x96,0x8b,0x86,0xb0,0x97,0x79,0x95,0xdf,0x69,0x56,0x6d,0x61,0x0a,0x37,0xcb,0x36,0xe1,0x95,0x88,0xf5,0xf0,0xe2,0x5c,0xb2,0x44,0x73,0xda,0x83,0xa7,0xdc
+.byte 0x8b,0x35,0x3e,0xc1,0xd5,0x88,0x17,0x3b,0xeb,0xcf,0x36,0x9c,0xef,0x40,0xb2,0x72,0xde,0x4f,0x16,0x6c,0x8c,0x9d,0x15,0xce,0x7d,0x0d,0xc3,0x2f,0xea,0xab,0x50,0xdf,0x02,0xe0,0x24,0xcc,0xf4,0xa7,0x25,0xba,0x85,0x0d,0x62,0x9a,0x39,0xc7,0x5a,0xd1,0x9a,0xd1,0xa7,0x45,0x5f,0xc2,0x44,0xf5,0xa9,0x8d,0xd8,0xbc,0xd3,0xc8,0x75,0x0d
+.byte 0x06,0xc6,0x4b,0x24,0xc6,0xe5,0x72,0xf7,0xd5,0x87,0xca,0x3c,0xc0,0x1c,0x18,0xa9,0x40,0xc6,0x7b,0xe5,0x4c,0xe6,0xb7,0x01,0x57,0xc1,0xcf,0x63,0x83,0x58,0x63,0x47,0xcf,0xa4,0xd3,0xf6,0x1d,0x2c,0xbf,0x17,0xe6,0x0a,0x7b,0x2d,0xa9,0x34,0x23,0xfc,0x1f,0x06,0x31,0x47,0x7b,0x31,0x34,0x8c,0x3c,0x15,0x9b,0xac,0xfd,0x38,0xe6,0xa3
+.byte 0x9e,0xa7,0xdf,0xa6,0x37,0x61,0xfd,0x85,0xb8,0x2e,0x67,0x73,0x7f,0x60,0x12,0x8b,0x62,0xb0,0x38,0xd0,0xaa,0xc4,0xad,0x3b,0xa9,0x04,0x66,0xdd,0xbb,0x9c,0xb1,0x95,0xe1,0x9c,0x0a,0x72,0x80,0x12,0xaa,0xa8,0x0c,0x3f,0x90,0x20,0x33,0xb4,0x76,0xdd,0x26,0xfe,0x1e,0x8f,0x6a,0x2d,0xea,0x4a,0xdc,0x28,0x47,0x66,0x36,0x5b,0x50,0x60
+.byte 0x7e,0x3e,0x93,0xf3,0xe9,0x37,0x31,0x3b,0x43,0x46,0x85,0xb3,0xa9,0xb2,0x14,0x95,0x96,0x49,0xf9,0x2a,0xe7,0x9e,0x3a,0x3e,0xd8,0x12,0xf7,0xbc,0x43,0x8c,0x35,0x31,0x44,0x08,0x7f,0x25,0x39,0x86,0x98,0x6a,0xe8,0xe3,0x2e,0x73,0x2d,0x3b,0xac,0x2d,0x75,0x4c,0xc8,0xca,0x21,0x2d,0x96,0x9b,0x4f,0x56,0xff,0x2d,0xc2,0xe2,0x98,0x3d
+.byte 0xe2,0x3f,0xee,0x10,0xb7,0xc3,0x3d,0xa8,0x50,0x88,0x7f,0xd5,0x4e,0xbd,0xc7,0x9d,0xdc,0x01,0x49,0x27,0xf2,0xae,0xea,0x93,0x72,0xdf,0x00,0xcd,0xe6,0xa1,0xdd,0xd1,0x18,0xeb,0xa7,0xe1,0x4a,0x7b,0x38,0x72,0x73,0x29,0x46,0xa3,0xb3,0x25,0x23,0x6d,0x26,0xab,0x86,0xdc,0x67,0x52,0xe5,0x4a,0x5e,0x8f,0x16,0x67,0x8a,0x28,0x13,0xba
+.byte 0x44,0x42,0xb5,0x21,0x9f,0x30,0x66,0x7f,0xc9,0x87,0x40,0xcb,0x75,0x58,0x2e,0xcd,0x09,0xb9,0x8a,0x84,0xa3,0xbd,0x63,0x53,0x75,0x2f,0x77,0x8b,0x7e,0x19,0x31,0x33,0x3b,0x9a,0xfb,0x86,0x39,0xa6,0xd9,0xeb,0x9b,0x43,0xc6,0xd9,0xc2,0x10,0xab,0x42,0xe5,0xc6,0x4a,0xe6,0x3e,0xde,0x9d,0xac,0x8e,0x95,0xf0,0xdb,0x48,0x95,0xc2,0x87
+.byte 0x6b,0x7f,0xde,0x09,0xdb,0xed,0x49,0x19,0x73,0x2d,0xa4,0x5c,0xdf,0xfa,0x2e,0x15,0xd0,0xb6,0x46,0x32,0xc9,0x7f,0x7e,0x01,0xd3,0x25,0x45,0x0e,0x5b,0x0d,0xf0,0x67,0xe3,0xd9,0xdf,0x4f,0x3b,0x6f,0xb3,0x15,0xc5,0x6b,0x91,0x75,0xa2,0xaf,0x42,0x3a,0x14,0x50,0xd9,0x4f,0x19,0x65,0x12,0x83,0x5d,0x8f,0x8a,0x01,0x0b,0x89,0xcc,0x7f
+.byte 0x1a,0xde,0x5b,0x44,0x34,0x98,0x0f,0x8e,0x5a,0x5e,0x03,0x41,0x3e,0x66,0x9b,0x16,0xf5,0x91,0x7c,0xb0,0xc1,0xbf,0xa2,0x10,0x0b,0x60,0x3a,0x63,0x0c,0xcf,0xd8,0x49,0xdb,0x42,0x88,0x1f,0x36,0x8e,0x15,0xdb,0x5d,0x3f,0xe7,0xf1,0x9a,0x73,0x2b,0x74,0x0c,0xd5,0x09,0xab,0x01,0x2e,0x52,0x6f,0x03,0xf6,0xc9,0x0b,0xeb,0xa5,0xce,0x2e
+.byte 0x1c,0x02,0x35,0xca,0xce,0xfe,0x4b,0xad,0x67,0x21,0xf8,0x44,0xea,0x70,0xf2,0x3d,0xfc,0x43,0x77,0x05,0x26,0xbe,0xaf,0x99,0xab,0x41,0xd4,0xcc,0x53,0x33,0x33,0xcd,0xb4,0x2d,0x76,0xfb,0xae,0x0c,0xac,0xc1,0xd0,0x42,0xfb,0x45,0x4a,0x6e,0x55,0xd2,0x93,0xef,0xb9,0x06,0xbc,0x38,0xce,0x94,0xc2,0x01,0xdf,0x27,0xc8,0x47,0xff,0x74
+.byte 0xfb,0x84,0xc5,0xa2,0x78,0x1f,0x4f,0x73,0x12,0xec,0x2d,0x82,0x5b,0xeb,0x3c,0xb6,0x1c,0x5a,0x29,0x9c,0xba,0x9e,0xa4,0x85,0x94,0x84,0x68,0x01,0xd7,0xb1,0x27,0x84,0x4a,0x7d,0x62,0x9c,0x32,0x12,0x89,0xd8,0x66,0xb5,0xe9,0x07,0xf4,0x5f,0x6b,0x0e,0x90,0x87,0xe5,0xc1,0x8b,0xaf,0x8f,0xf7,0xca,0x54,0xe0,0xc6,0x5f,0xa5,0xec,0xd1
+.byte 0xdc,0xdc,0x17,0x9e,0xca,0x4b,0x72,0x72,0x03,0x96,0x62,0xaa,0xc1,0xfe,0x23,0x7e,0xd2,0x06,0x61,0xb6,0xc9,0x0d,0x7e,0xbf,0x72,0x1c,0x66,0x46,0x0b,0x31,0x96,0x81,0x11,0x3d,0xac,0x5e,0xd0,0x35,0xaf,0xac,0x4c,0x74,0xce,0xf9,0x9c,0x64,0x3d,0xe5,0x9d,0xfe,0xc7,0x05,0x09,0xe1,0x70,0xc5,0x37,0xd5,0x4e,0xd8,0x7d,0xdb,0xfa,0x1c
+.byte 0x28,0xfc,0x10,0x2a,0xe8,0x62,0x18,0x09,0x97,0xe0,0x98,0x2e,0x9f,0x1d,0x18,0xff,0x22,0xe9,0x5d,0x37,0xd2,0x74,0xf1,0x81,0x08,0x8a,0x55,0xc0,0x40,0x0f,0x70,0xbe,0x82,0x23,0x78,0x35,0xc8,0xf8,0x59,0x6e,0x0d,0x2e,0xd5,0xe7,0xf5,0x2e,0xbd,0xcd,0x1a,0xcf,0x76,0x43,0x1f,0xca,0x15,0x6c,0x4a,0xb7,0xc7,0xb9,0xaf,0x68,0xd7,0x31
+.byte 0x1e,0x0c,0x9c,0x78,0x74,0x66,0x80,0xc6,0x74,0xbe,0x86,0x59,0x0c,0x12,0xdc,0xf3,0x1b,0xaf,0x63,0x74,0xce,0x1e,0xac,0xf0,0x65,0xa0,0xab,0x7f,0x96,0x08,0x32,0xb2,0xca,0x9c,0xfb,0x9d,0x66,0x63,0x76,0xf9,0x69,0x08,0x6e,0xd3,0x46,0xde,0xdf,0x54,0x06,0x0d,0x25,0x81,0xd9,0x5a,0x45,0xeb,0xe5,0xc0,0xf6,0x86,0x0f,0xe9,0x27,0x7c
+.byte 0xdc,0x52,0x28,0xb5,0xd0,0x7d,0x07,0xc1,0xb6,0x9b,0xdc,0xea,0xd3,0x2a,0xba,0xb0,0xd5,0xa3,0xd8,0x25,0x07,0x9c,0x6c,0xd6,0x16,0xa5,0x93,0x43,0x52,0xa7,0x5c,0x2b,0xe2,0xfa,0x8e,0x6e,0xaa,0x04,0x84,0x63,0x80,0x0f,0x90,0x10,0x41,0x1c,0xf6,0x67,0xea,0x39,0xb0,0x16,0xfc,0x6f,0x85,0x28,0x8c,0x8e,0xfb,0x79,0x39,0xdf,0xf6,0x6e
+.byte 0x57,0xa1,0xaa,0xf1,0x0b,0x99,0xde,0xad,0x69,0xe2,0xf4,0x74,0x8e,0x8c,0x2d,0x20,0xdb,0xf3,0x2d,0xc2,0x75,0xe7,0xd6,0xc8,0x9d,0x46,0x3b,0x8b,0x8b,0x18,0xd8,0x41,0xfd,0xc2,0x7d,0xec,0x66,0x78,0xe7,0xbe,0xee,0x2b,0x07,0xd8,0x7e,0x13,0x61,0x7e,0xab,0x7d,0x2b,0x3f,0x83,0x96,0xf5,0xab,0x0b,0x20,0xd2,0x5b,0xb0,0xeb,0xf7,0x1b
+.byte 0xac,0x1a,0x16,0x46,0x21,0x90,0xdb,0x67,0x66,0x42,0xe2,0x54,0x34,0xae,0x34,0xae,0x21,0x33,0x8c,0x48,0x19,0xdb,0x1f,0xa8,0x25,0x76,0xe0,0x03,0x1c,0x35,0x8d,0xd3,0xab,0x6b,0x93,0xf3,0xad,0x7d,0x3c,0x76,0x1d,0xaa,0x43,0x80,0x0f,0x5f,0x20,0xd9,0xf0,0xff,0x8b,0xf4,0xdb,0xbc,0xf2,0xff,0xf2,0x8a,0xfc,0xf5,0x0e,0x4e,0xd9,0xb0
+.byte 0xd6,0xb3,0x86,0x5b,0x3e,0x10,0x87,0x50,0xf1,0xd2,0x8f,0x8d,0xa4,0x39,0x85,0xf5,0x90,0xd6,0x53,0x69,0x40,0x42,0xc1,0xc3,0x7c,0xc1,0x3e,0x97,0xb4,0x08,0x49,0x93,0x4e,0x4c,0x67,0xd9,0x2e,0x05,0x70,0x04,0x98,0x0a,0xed,0xd0,0xff,0x0c,0x13,0xe4,0xde,0x75,0x81,0x24,0xb1,0x27,0x79,0xeb,0x80,0x68,0x52,0x50,0x66,0x77,0x4f,0xf6
+.byte 0x64,0x2f,0x85,0x9e,0xc1,0xbf,0x9f,0x0e,0x31,0x9a,0x36,0x24,0xcd,0xa8,0xe8,0xce,0x41,0x86,0xd1,0x02,0x96,0xdc,0x1a,0xa0,0x48,0xca,0x61,0xd5,0x87,0xdb,0x0a,0xeb,0x69,0x95,0xca,0xf8,0xe5,0xa0,0x5b,0x91,0x8f,0xb9,0x59,0x5f,0x68,0x60,0x58,0xc5,0xe0,0xc7,0x02,0x68,0xa5,0x67,0x1e,0xfc,0xa9,0x27,0x9f,0x83,0x4c,0x05,0x60,0xee
+.byte 0xcb,0x79,0x31,0x73,0x36,0xf4,0x39,0x44,0xdb,0xea,0x62,0x89,0x97,0x69,0xd1,0x0d,0xf6,0x27,0xcf,0x47,0xfe,0x3d,0x5c,0xe9,0x92,0x54,0x0a,0x66,0xaf,0x82,0xb1,0x49,0x87,0x3f,0xa2,0x95,0x91,0x0e,0x72,0x1e,0x7b,0xde,0x32,0x31,0x51,0x40,0x24,0x4f,0x30,0x59,0x7d,0x97,0x28,0x30,0x7e,0x93,0xcd,0x1e,0x16,0xef,0xe1,0xb5,0xa8,0xff
+.byte 0x3a,0xd0,0x62,0x94,0x8b,0x72,0xe7,0x97,0x8f,0x2f,0x58,0x3e,0x62,0x43,0x6b,0x28,0x05,0xc9,0x0d,0xf0,0x09,0xbd,0x12,0x3b,0xd8,0x15,0xd3,0x7c,0x97,0x96,0x5a,0xf4,0x9f,0x8d,0x25,0xb7,0xc5,0x66,0xf7,0xf7,0x5f,0x7e,0xca,0x2f,0xcd,0x9a,0xf2,0xa3,0x9b,0x4f,0x6f,0xc3,0xd9,0x64,0x38,0xda,0x87,0x97,0x8a,0x49,0x2d,0x80,0x16,0x73
+.byte 0x88,0x62,0xd2,0xdf,0x4f,0xf7,0x79,0xc0,0x83,0xeb,0x2b,0x66,0x5a,0x21,0x3a,0xa2,0x2a,0xed,0x8c,0xe7,0x91,0x6d,0x56,0x18,0xfc,0x59,0x68,0xea,0x9f,0x5c,0x3c,0xd5,0x0f,0x64,0x70,0x89,0x22,0x83,0xed,0xfa,0xc9,0x21,0x68,0x3c,0x69,0xb8,0x3e,0x89,0xb5,0x9d,0x8b,0xc8,0xf7,0x57,0x17,0x27,0x90,0x12,0xa7,0xd2,0x4d,0x2c,0x30,0x64
+.byte 0x42,0xbe,0xa6,0x49,0x4e,0xa3,0x3b,0xdb,0xdb,0x64,0x0e,0x89,0x66,0x87,0x72,0x90,0x86,0x1d,0x0b,0x61,0x32,0x47,0x3d,0x55,0x81,0xb2,0x50,0x5a,0x76,0x6c,0xa3,0x46,0x12,0x1b,0xaf,0x6e,0xbf,0xfd,0x98,0x2f,0xb7,0xd2,0x31,0x92,0xb5,0x26,0x1a,0x3d,0xfa,0x5d,0xc0,0x24,0x44,0xd2,0x6b,0x1c,0x81,0xf5,0x5d,0x50,0xb0,0x33,0x18,0xe0
+.byte 0xc5,0xb3,0x6b,0xf4,0xfd,0xde,0xf7,0x2f,0x69,0x1d,0x5a,0xfe,0x03,0x6d,0xca,0xad,0x29,0xe0,0x6e,0x70,0xcd,0xe3,0x6d,0x38,0xef,0xf1,0x3a,0x76,0x2b,0x2c,0xb6,0xcd,0xff,0xeb,0xbc,0xe7,0xd9,0x40,0xbe,0x23,0x61,0x20,0xd5,0xb8,0x66,0x77,0x65,0xc9,0x33,0xf5,0x75,0x8e,0x15,0x98,0x3f,0xb1,0x4a,0xb8,0x1c,0x47,0x73,0x45,0x0f,0x73
+.byte 0x2a,0xa1,0xb7,0x73,0x76,0x94,0x16,0x45,0xcf,0xd6,0x8f,0xe3,0x62,0x8a,0x42,0xfd,0xe3,0x1e,0xe0,0x7d,0xb5,0x99,0xbd,0x1c,0xf2,0x60,0xb2,0x72,0xa8,0x4b,0x19,0xd6,0xd0,0xdb,0x0b,0x1f,0xc9,0x68,0xc0,0xf3,0x65,0x04,0x50,0x41,0xf0,0xb3,0x0e,0x0a,0x9d,0x7f,0x0b,0x1f,0xeb,0x5b,0x4c,0x58,0x6a,0xf2,0x02,0x95,0xd2,0xf3,0xac,0xe5
+.byte 0x69,0x81,0xb1,0x3f,0x08,0xfc,0xba,0xcb,0x36,0xcd,0x54,0x28,0xac,0x65,0xd8,0x81,0xab,0xc1,0x6a,0x51,0x97,0x21,0xe4,0xc6,0xaf,0xd8,0x76,0x76,0xa4,0xc4,0xd0,0x58,0x63,0xdf,0x32,0xf5,0x04,0xfb,0x11,0xeb,0x76,0x39,0xda,0x55,0xf4,0x7e,0x1c,0x7b,0x04,0x07,0x4d,0x5a,0xeb,0x74,0x0a,0x57,0xcf,0x10,0xf6,0x0e,0x73,0x02,0x25,0x67
+.byte 0x4f,0x8f,0x37,0x75,0x8f,0x44,0x2a,0x1a,0x6d,0x05,0xda,0xe0,0xa0,0xaa,0xd2,0x78,0xaa,0x7e,0x76,0x0a,0xde,0x2a,0x54,0xae,0x1e,0x39,0xcc,0x3c,0x1c,0xa6,0xd5,0x8a,0xca,0xb4,0xcc,0x76,0xb9,0x30,0xd2,0xe2,0x46,0x31,0xb6,0x51,0xcf,0xe2,0x24,0x77,0xc9,0x9b,0x57,0x3c,0xa3,0x84,0x60,0x59,0x28,0x5f,0x23,0x74,0x17,0x79,0x42,0xbe
+.byte 0x60,0x3f,0x09,0x6a,0x43,0x8e,0x40,0x25,0x79,0xb5,0xbb,0xbb,0x72,0x50,0xad,0x4f,0xaa,0xa2,0xd4,0xb2,0xc6,0x7d,0x50,0x7b,0x98,0x59,0x22,0x06,0x7d,0x2c,0x35,0xdd,0x44,0x34,0x9c,0x28,0x98,0xf3,0xe5,0xd0,0x7e,0x09,0xbe,0xc4,0x00,0x72,0xd5,0xa6,0x3b,0x0e,0xb1,0x18,0x91,0x0a,0x4d,0x5d,0xe2,0x0a,0x98,0x79,0x30,0x9b,0xaa,0x38
+.byte 0x03,0x2b,0x6c,0xb2,0x8e,0x0a,0x1d,0x30,0x59,0x8a,0xe8,0x6c,0x6d,0xb5,0xd4,0x91,0xc5,0x28,0x1d,0x5e,0x49,0xe0,0xfc,0x26,0x7f,0x40,0xc0,0x6a,0x81,0x0d,0xb9,0xc6,0x05,0xc6,0x18,0x82,0x70,0xf6,0xea,0x0e,0xb4,0x85,0xba,0x5d,0xfa,0xfd,0xe3,0xd6,0x08,0x7c,0x3d,0x99,0x03,0xd4,0xdc,0x9b,0x50,0x12,0xc8,0xbd,0x8c,0x47,0x67,0x28
+.byte 0x83,0x97,0xca,0xef,0xc3,0x1c,0x2b,0x6e,0x3b,0xf7,0xca,0x7a,0x68,0x6e,0x39,0x25,0x58,0xf7,0xa4,0x11,0x9d,0x8d,0x49,0x29,0xd6,0x6e,0x0b,0x0a,0xcf,0xa7,0x04,0x14,0x6f,0xc4,0x4c,0x36,0x1a,0x16,0x3e,0x8f,0x99,0x69,0x94,0x1d,0xa8,0x66,0x93,0xeb,0x1d,0x82,0xfd,0x3f,0x84,0xb0,0x9d,0xa4,0xe1,0xb0,0xd4,0x9d,0xb2,0x60,0x20,0xfb
+.byte 0xd3,0xa0,0xdc,0x79,0x83,0xb0,0xfc,0x50,0x18,0x57,0xe1,0xeb,0x44,0x25,0x05,0xab,0x27,0xfb,0x5f,0x83,0xcd,0x51,0xd0,0x3b,0x80,0x4a,0xce,0xbf,0xe9,0xfe,0x46,0xd2,0x5f,0xea,0x8c,0x89,0x48,0xc8,0x65,0xdd,0x2a,0xa4,0xda,0x54,0xc2,0x37,0x7e,0xd7,0xff,0x80,0x5b,0xf0,0xc3,0x40,0x44,0x40,0x72,0x63,0x23,0xc6,0x9a,0x48,0xf3,0x4b
+.byte 0x91,0x64,0x26,0xfc,0xf3,0xa0,0xb9,0x06,0x0c,0x88,0xbb,0xc0,0x93,0x73,0x63,0xf6,0x9c,0x0d,0xe2,0xf6,0xee,0xe0,0x51,0xfd,0xae,0x4d,0x21,0xb9,0x6b,0x7d,0x1e,0x34,0xa0,0x4d,0xe4,0x25,0x30,0xe6,0x81,0x2e,0x32,0xef,0xb9,0x9e,0xaf,0xa0,0x22,0xe0,0x67,0xe6,0x07,0x55,0x3a,0xed,0xef,0x4f,0x87,0x2f,0x44,0xd2,0xef,0xc1,0xfb,0xc4
+.byte 0x7b,0x27,0x20,0x44,0xd2,0xd6,0xf9,0xf3,0x67,0xc1,0xbf,0xaa,0xd5,0x9c,0xd9,0x2c,0xd5,0xf1,0x42,0x2d,0xec,0x39,0xb5,0xc1,0x18,0xed,0x6c,0x47,0x80,0xf8,0x6f,0x66,0x10,0xee,0x1d,0xd6,0x79,0x01,0x4e,0x2a,0xd0,0x83,0xa7,0x9d,0x1d,0x81,0xce,0xf5,0x6f,0x26,0x86,0xd2,0xd7,0x56,0x15,0x65,0x48,0x4c,0xf1,0xf9,0x21,0x77,0xd1,0x84
+.byte 0x22,0xce,0x4d,0x8d,0x83,0xda,0x8c,0x50,0x56,0xc8,0x3b,0xc5,0xb6,0xcf,0x3e,0x0d,0x50,0xe5,0x9d,0x6c,0xb5,0x2a,0x5a,0x58,0x28,0xf5,0x0a,0x05,0xf3,0x0e,0x40,0x8e,0xb6,0xb4,0xdf,0x11,0x1b,0x34,0x81,0xc5,0x0e,0x09,0xa6,0xfc,0x46,0x14,0x02,0x78,0x94,0xbb,0x63,0x9d,0x3e,0x25,0x2c,0xc8,0x1b,0x5c,0xef,0x64,0x77,0x0c,0x04,0x40
+.byte 0xe1,0x45,0x85,0xf8,0x07,0xbf,0x14,0x65,0xe9,0xfc,0xba,0xe4,0x9c,0xa7,0x91,0x56,0x2a,0x3a,0x8e,0x33,0xae,0x56,0x04,0x9d,0x35,0xbc,0xad,0x64,0x0e,0x99,0x8e,0xb5,0x84,0x72,0xcf,0xcc,0x81,0x14,0x11,0x9e,0xe6,0xac,0x0d,0x41,0x43,0x4e,0x2a,0x0d,0xda,0x98,0x42,0xfa,0x8c,0x21,0x79,0x93,0xa3,0xdf,0x84,0x88,0x76,0x14,0x5b,0xb9
+.byte 0xff,0xe1,0xab,0x94,0xc3,0xcd,0x10,0x69,0xee,0x53,0xea,0xfe,0xfb,0xaa,0x43,0x8f,0xdd,0x55,0x88,0x34,0x5d,0x55,0x0f,0x42,0x4d,0x1d,0x93,0xce,0x96,0x67,0xf8,0x33,0xc7,0xca,0x34,0x11,0x28,0xb2,0xed,0x0f,0x00,0x40,0x84,0xee,0x51,0x26,0x6e,0x7b,0x2d,0x77,0xeb,0x18,0xb8,0x9a,0xad,0x28,0xb6,0x6c,0x5e,0xde,0x10,0x4c,0x29,0x1d
+.byte 0x79,0x3c,0x2e,0x1c,0xf0,0xc8,0xb3,0xee,0x19,0x7a,0x10,0xe1,0xe3,0x05,0x1e,0x63,0xe9,0x00,0xd7,0xfe,0x83,0xe7,0x54,0xff,0x65,0x9a,0x27,0xa3,0x86,0x72,0x5c,0xb6,0xef,0xf5,0x84,0x68,0x1e,0xae,0xe6,0xf8,0x66,0x9c,0x1b,0x86,0xab,0xfa,0x1a,0xe3,0xb8,0x97,0x16,0xb1,0xb7,0x42,0xfa,0x85,0xa3,0x3a,0x0d,0x21,0xd2,0x35,0xb1,0x89
+.byte 0xf0,0x4f,0x1a,0x1d,0x45,0x34,0x2f,0x31,0x12,0x8c,0x19,0xe7,0x4b,0x14,0xa7,0xcf,0x0f,0xf9,0xcd,0x77,0x40,0xbe,0x09,0xeb,0xc3,0x3e,0x4a,0x37,0x55,0xab,0xbb,0x9c,0xe5,0x22,0x56,0x8a,0x66,0xfa,0xb1,0xff,0x73,0x29,0x52,0xb1,0x89,0xf7,0xab,0xa6,0x58,0x53,0x97,0xfd,0x44,0xda,0xbd,0x0b,0x1f,0xc8,0x88,0x01,0xcc,0x5e,0xf7,0x05
+.byte 0xbd,0xf7,0x0a,0x4d,0xcb,0xef,0xbf,0xd9,0x8e,0x15,0xc3,0x40,0xb9,0xc9,0x14,0xe5,0x05,0x3c,0x20,0x67,0xfe,0xdc,0xa6,0xb8,0x92,0xbd,0xf5,0x33,0xb5,0x77,0x11,0x28,0x47,0x21,0x28,0x18,0x61,0xf8,0x1c,0xdb,0x65,0xad,0x89,0x0d,0x98,0x79,0xca,0x2b,0xa3,0x4f,0x16,0xa6,0xb3,0xb9,0xcc,0x47,0x5b,0x13,0x96,0x2e,0x39,0x78,0x24,0xc5
+.byte 0xf9,0xf5,0xae,0xdc,0x34,0x3c,0xf7,0x48,0x0d,0x75,0xaf,0x51,0x75,0x48,0xbe,0x4d,0x73,0x89,0x5a,0xfc,0xd7,0x51,0xd3,0x93,0xa8,0xbc,0xc3,0xa6,0x6b,0x63,0xc1,0xc3,0x7b,0x48,0xf1,0x57,0xe4,0xb4,0xce,0x5f,0x18,0xae,0xdc,0x61,0x99,0xaa,0x7e,0x49,0xd6,0xb5,0x2c,0x62,0xb8,0x8c,0x4a,0x94,0xc1,0xc2,0x13,0x23,0xdc,0x7c,0x48,0xc2
+.byte 0xaa,0xc4,0xd9,0xc0,0x09,0x11,0x6e,0x35,0x07,0x14,0x77,0x7e,0xeb,0x87,0x00,0x05,0x30,0xec,0xb2,0xc6,0xde,0x6e,0x42,0x0b,0x2a,0xb6,0xca,0xb1,0xdc,0x69,0x57,0x1b,0xad,0x52,0xa8,0x22,0x1e,0xb5,0x2b,0xb5,0x8e,0x39,0x4b,0xbf,0x38,0xf4,0xb2,0xf5,0xa1,0x9c,0x7b,0x7f,0x6c,0x14,0x48,0x37,0xa9,0xf9,0xcd,0x85,0x50,0x53,0xb0,0xc1
+.byte 0x15,0x28,0x19,0x3b,0xb1,0x04,0x44,0x93,0x7a,0x16,0x76,0x69,0xa1,0x5c,0x67,0xcc,0x8d,0x02,0x56,0xcd,0xd9,0x91,0x49,0x8c,0x1b,0xc9,0x89,0x98,0x09,0x2e,0x5b,0xf8,0x7c,0xe6,0x0f,0x46,0xb0,0xcc,0xe5,0x75,0x63,0xaf,0x40,0xd5,0xa3,0x45,0x4a,0x76,0x67,0x1d,0x81,0xc2,0x25,0x85,0x7f,0x52,0xc5,0xf8,0x6d,0xd9,0xb6,0xa8,0xa4,0x96
+.byte 0x63,0xcc,0x15,0xc5,0xec,0x40,0x0e,0x08,0xf7,0x6f,0x85,0xa5,0xe7,0x2e,0xbe,0x3f,0xf4,0xc8,0x74,0xc7,0xed,0x86,0x85,0xc0,0x44,0x9e,0x80,0xc8,0x89,0xdc,0x16,0x47,0xb1,0x68,0x0e,0x65,0x66,0x0f,0xbc,0x33,0xb1,0x78,0x1e,0x5e,0xd7,0xde,0x97,0x96,0xb8,0x74,0x5c,0x90,0x7a,0xed,0x36,0xf4,0x10,0x91,0x5a,0x42,0x92,0x81,0x11,0x73
+.byte 0x3e,0xf1,0x5e,0xfb,0xc2,0x38,0xe6,0xe5,0x41,0xce,0x96,0xed,0x44,0x14,0x9c,0xc0,0x1f,0x83,0x5f,0xdd,0x50,0x87,0x90,0x86,0x50,0x61,0x87,0x99,0x7c,0x64,0x2d,0x50,0x17,0xa3,0xb0,0x7e,0x69,0xd3,0x86,0xb4,0x7c,0xe7,0x15,0x34,0x9e,0x3b,0x17,0xc0,0x2d,0x08,0x60,0x8b,0xae,0xec,0xa2,0xf6,0xf1,0xa4,0xbc,0x7b,0xc2,0x75,0x91,0x13
+.byte 0xf6,0xd0,0x71,0xf0,0x3c,0x9c,0x51,0xb3,0x33,0x53,0x57,0x47,0x8b,0x47,0xb0,0x0b,0x95,0x9a,0x39,0x70,0x63,0x91,0xcc,0xd8,0xd0,0x23,0x32,0xc0,0xb6,0x0f,0x91,0x30,0x29,0x45,0xf1,0xfc,0xa1,0x83,0x10,0x9a,0xa4,0x05,0x05,0x9f,0x33,0xbd,0xaf,0x16,0x3e,0x53,0x39,0xb1,0x4b,0x76,0x55,0x3e,0x6f,0x47,0x23,0x59,0x4c,0xbb,0x82,0x31
+.byte 0x19,0xe2,0xb1,0x49,0x20,0x91,0x2d,0xb0,0xfe,0xa6,0xae,0x7f,0x6e,0xd1,0x5b,0xb9,0x84,0x18,0x0f,0x68,0xc6,0x56,0x8a,0x22,0x81,0x3f,0x38,0x42,0x7a,0x31,0xa1,0xc1,0xf7,0x10,0x6a,0xc3,0xb1,0xaf,0x19,0xad,0x06,0x3a,0x53,0x9d,0x44,0x9f,0xe7,0x25,0xac,0x59,0x06,0xb9,0xd2,0xf6,0xce,0xb6,0x1e,0x4d,0x65,0x2e,0x05,0xb4,0x14,0x91
+.byte 0xfb,0x5b,0x26,0xd0,0xee,0xfa,0x45,0x5b,0x0c,0xd5,0x5c,0x1f,0x0c,0xe0,0xf6,0x50,0x78,0x77,0x7e,0x83,0x04,0xec,0x3b,0x53,0x28,0x97,0x56,0x61,0xeb,0xa0,0x78,0xe5,0xc0,0xb2,0x3c,0xcd,0x6f,0x4b,0xda,0x11,0x00,0x93,0x49,0x9f,0x03,0x22,0x39,0x3a,0xc8,0xef,0x01,0x91,0x12,0x36,0x15,0x0c,0x47,0xd5,0x8b,0x77,0x5e,0x5f,0x91,0x4b
+.byte 0x44,0x98,0xa0,0xa0,0x46,0x0f,0x17,0xef,0xf9,0x52,0x0b,0x92,0xc1,0xe0,0xfc,0x63,0x9b,0x6d,0xe2,0xde,0x88,0x89,0x32,0x89,0x93,0x44,0x6d,0x69,0xe7,0x26,0xfd,0x77,0xc0,0x18,0x58,0xdb,0x74,0xec,0x04,0x0c,0x60,0x51,0x74,0xca,0x49,0x3e,0x4f,0x5f,0xaa,0x53,0xf2,0xc1,0xcb,0x89,0x1f,0x69,0xaa,0xbb,0x97,0x17,0x04,0x49,0x5e,0x44
+.byte 0xf3,0xf3,0xc4,0x98,0x9d,0x49,0x1e,0xb0,0x27,0x7d,0xff,0x54,0xa5,0xed,0xbe,0xb0,0x52,0xf6,0x00,0x87,0x67,0x2d,0x28,0xdb,0x09,0x4e,0xa2,0xee,0x4f,0x81,0xeb,0xa1,0xca,0x2b,0x07,0x2f,0x54,0x6d,0x5a,0x2e,0x13,0xa4,0xd0,0xac,0x21,0x7c,0x44,0xc0,0x98,0xac,0xe4,0x6e,0x94,0xd1,0x5b,0x5e,0xd6,0xf1,0x3c,0x45,0x88,0xe1,0xbd,0x58
+.byte 0xf1,0xc7,0xba,0x36,0x2c,0x15,0xb9,0xf4,0xa3,0xea,0x73,0xb4,0x91,0x53,0xd8,0x18,0x86,0x23,0x87,0x0b,0x7a,0x4a,0x2d,0x2d,0x3d,0x73,0xcb,0x05,0x11,0x4c,0x19,0x26,0xf2,0x05,0x89,0xc8,0x29,0x26,0xa7,0xe4,0xcb,0x43,0xd0,0xf6,0xbc,0x76,0xbd,0x9a,0x17,0x4a,0xf1,0x39,0xe3,0xde,0x05,0x10,0x8a,0xd3,0x11,0x53,0x61,0xef,0x33,0xd9
+.byte 0x65,0x0d,0x99,0x0b,0x39,0xa4,0x1b,0x4f,0x0b,0xa5,0xf1,0x37,0xa3,0x4f,0x54,0xa7,0x29,0xc1,0xae,0x88,0x5c,0x13,0x2f,0xb2,0xbf,0xcf,0x1b,0x0d,0xa0,0x68,0x21,0xe2,0x20,0x3f,0x02,0x9f,0x08,0x39,0xc6,0x20,0x2d,0x08,0x01,0x5d,0xf1,0x47,0xde,0x88,0xad,0x49,0x09,0xf7,0x1a,0x0c,0xa7,0x29,0x91,0xe5,0xfc,0xc5,0xde,0xd7,0x92,0x3f
+.byte 0xe5,0x0c,0x91,0xea,0x24,0xfb,0x02,0x9a,0x13,0x3a,0x61,0x01,0x9d,0x7e,0x9d,0x11,0xf8,0xbd,0xe0,0x05,0xbb,0x13,0xf0,0x00,0x67,0x90,0x6f,0x80,0xe7,0x2e,0xfc,0xe0,0xea,0x8a,0x9d,0x2c,0x13,0x57,0x4c,0x78,0x1c,0x44,0xe2,0xa6,0x62,0x01,0x46,0xf8,0xbe,0xf4,0x51,0x32,0x15,0xd4,0x3c,0x7d,0x3b,0xcc,0xfd,0xc3,0x46,0x43,0xf1,0xfa
+.byte 0x9e,0xee,0xad,0x47,0x8f,0x32,0x31,0x94,0x70,0x92,0xea,0x45,0xe3,0x63,0xd6,0x28,0x23,0xa5,0xdf,0x61,0xee,0x19,0x1a,0x5e,0xb0,0xe7,0x17,0xab,0xac,0xb4,0x03,0xed,0xf6,0x9e,0xba,0xdf,0x52,0x88,0xb7,0xca,0x7c,0x27,0xcd,0x7b,0xf8,0x1e,0x54,0x4b,0xe6,0xa3,0x91,0xf7,0xeb,0x22,0x65,0x95,0x13,0xe1,0xac,0xb6,0x22,0x80,0xe3,0xeb
+.byte 0xf9,0xde,0xf1,0xb7,0x6a,0xfd,0xc7,0xb8,0x9b,0x9c,0x49,0x4f,0x84,0x7f,0x68,0x93,0x6c,0x3c,0xea,0xb1,0x8a,0xeb,0x23,0xca,0x2d,0x5e,0x29,0xb5,0x52,0x49,0x98,0x12,0x3f,0xed,0xf0,0xb7,0xbc,0x22,0x14,0x73,0x92,0x84,0x1b,0x3e,0x2f,0xed,0x24,0x1e,0x62,0xcc,0x09,0xe8,0x7c,0x5a,0x08,0xd4,0xc6,0xd9,0xd1,0x55,0x66,0x18,0x2c,0x6a
+.byte 0x99,0xc3,0x0e,0x1e,0x7b,0xb7,0xd4,0xbd,0x0e,0x1f,0x22,0x85,0x09,0x2c,0xcf,0xff,0x79,0x9f,0x93,0xbe,0xec,0xed,0x63,0xb7,0x97,0xbb,0xeb,0xd6,0x70,0x76,0xa9,0x4f,0xb7,0x9a,0x60,0x5b,0x50,0xdf,0x85,0x46,0x69,0xa0,0x9a,0x86,0xe3,0xe2,0x13,0x2b,0x8c,0x0f,0x3b,0xab,0xa8,0xce,0xa3,0xb0,0x78,0x72,0x40,0xfb,0xd1,0x26,0x72,0xc1
+.byte 0x91,0x25,0x7b,0x29,0xde,0xcf,0x99,0xf3,0x8e,0x87,0x39,0x81,0x04,0xad,0x3b,0x11,0x6a,0xda,0x00,0xdd,0xe9,0x41,0xc1,0xd8,0xcc,0xf9,0x59,0xac,0x9b,0xb1,0x64,0x6f,0xb8,0xf4,0x9f,0x20,0xde,0x67,0x09,0x1b,0xdf,0x11,0xa5,0x94,0x56,0xab,0x76,0xba,0xc5,0xda,0x6c,0x86,0xe6,0xa4,0x73,0x59,0xa9,0xe3,0x68,0xb9,0xc0,0x50,0x1b,0x55
+.byte 0x21,0x9e,0xea,0x8d,0xcc,0x5d,0xee,0x88,0xe1,0x18,0x7c,0xcd,0x8f,0xff,0x18,0xbd,0x13,0xea,0x95,0xc4,0x8e,0xd3,0x92,0xfe,0x3d,0xda,0x6f,0xa5,0xbc,0xa0,0x77,0x5a,0x1d,0x61,0xff,0x7b,0x77,0xc4,0x06,0x25,0xc5,0xa7,0x76,0x36,0x55,0xe7,0xc0,0xf0,0x46,0x7e,0xca,0xe7,0xc1,0xe8,0x88,0x65,0xff,0xa7,0xb6,0x9c,0x83,0x1d,0x2e,0x6e
+.byte 0xd6,0xd3,0x07,0x22,0x65,0x79,0x4f,0x3c,0x0a,0x5c,0x4f,0x95,0xb3,0x14,0x37,0x9b,0x0b,0x97,0x69,0xd9,0x5b,0x37,0x09,0xc3,0x70,0x5b,0x4f,0x11,0xcb,0xce,0xc0,0x06,0xf2,0xb9,0x32,0xdd,0x24,0x7b,0x8c,0xe6,0x0c,0x91,0x3b,0xa8,0xb0,0x82,0x56,0x4d,0xde,0xa0,0x5c,0x0b,0x5b,0x70,0x53,0x64,0x9d,0xab,0xbb,0x51,0x6b,0x8c,0x8f,0xe5
+.byte 0x1f,0xc0,0xb8,0xfe,0x1b,0xf6,0x24,0x26,0x62,0xcb,0x78,0x84,0x90,0x76,0x67,0x30,0x18,0x37,0xa9,0xca,0xb7,0x0d,0xac,0x17,0x86,0xb1,0x87,0x59,0x18,0xc3,0x9e,0x62,0x1b,0xb1,0x04,0x52,0xfc,0x7c,0x86,0xa0,0x37,0xb9,0x8b,0x7a,0x85,0x79,0x21,0xe0,0x0f,0x87,0x28,0x91,0xd0,0xe5,0x24,0x63,0x5c,0x7c,0xe8,0x47,0xfa,0x42,0x55,0xe9
+.byte 0x66,0xad,0xdf,0xc3,0x43,0x90,0x47,0x83,0x24,0x09,0x54,0x5f,0x14,0x27,0x53,0xb3,0x22,0x15,0x52,0x84,0x2f,0x61,0x8c,0x01,0x9e,0x34,0x61,0x3f,0x76,0x44,0x1c,0xca,0x79,0x2c,0x40,0x4e,0xa0,0x36,0x11,0xe0,0x23,0x0f,0xa7,0x78,0xf9,0xf9,0x2a,0x2c,0x98,0x5c,0xa9,0x2d,0x66,0xb9,0x87,0x43,0xd5,0xbc,0x64,0xe5,0x52,0x2f,0x1d,0xdc
+.byte 0x1d,0xf4,0xb3,0x18,0x6b,0xd1,0x3b,0x8b,0xa3,0x47,0x65,0x62,0xcc,0xca,0x5f,0x00,0xbb,0x78,0x9d,0x35,0xd4,0x79,0x45,0x33,0xc7,0xa8,0x29,0x96,0x98,0xa4,0x23,0x2c,0x23,0x7f,0x5a,0x1d,0x09,0xb4,0xcf,0xac,0x54,0xcd,0x27,0xda,0x88,0x21,0xe2,0xb4,0x85,0xdc,0xc9,0x4a,0x6b,0xc4,0xfa,0x48,0xc5,0x91,0xc1,0x53,0x4b,0xa1,0x7a,0x9c
+.byte 0x8a,0x7d,0x35,0x52,0xf1,0x58,0x9d,0x20,0x36,0xc2,0x78,0xdb,0x37,0xf8,0xa4,0x2f,0x50,0x98,0xb0,0x34,0x51,0x66,0x93,0xcf,0xe7,0xf0,0x06,0xf1,0xcd,0x0e,0x4f,0x33,0xcc,0x9b,0x73,0x3b,0xc9,0x51,0x63,0x6d,0x29,0x6b,0xf4,0x9d,0x2c,0x76,0x59,0xcd,0xfc,0x11,0x35,0x52,0xbd,0x3b,0x2e,0x7d,0x8a,0x0d,0xb0,0xbb,0x90,0x9b,0x9c,0xac
+.byte 0x1c,0x80,0x89,0xd6,0x6f,0xaf,0xea,0x89,0x38,0x74,0xef,0x83,0x82,0x91,0xf7,0x74,0x96,0x30,0x40,0xe2,0x18,0x2b,0xb4,0xf6,0x15,0xf0,0x8e,0x63,0xe1,0x82,0x55,0x7b,0x65,0x70,0x33,0x14,0xef,0x7a,0x7c,0x2d,0xa9,0x17,0x1b,0x53,0x1e,0xf8,0x98,0x1b,0xbe,0xc8,0x00,0xf5,0xbf,0x79,0xe7,0x8e,0xf2,0xdb,0x59,0x0d,0x46,0xab,0x43,0xd0
+.byte 0xe4,0xa0,0xeb,0x29,0x6a,0x8b,0xc1,0x99,0xa6,0xcc,0x8e,0xe5,0xde,0x67,0xdf,0x49,0x09,0x62,0x8d,0x4b,0xa1,0x1c,0x3b,0x01,0xe2,0x95,0x65,0x10,0xa5,0x91,0xd0,0x48,0x35,0x96,0xcf,0xe4,0x51,0xd2,0x7f,0x93,0x49,0xab,0x1a,0xba,0x08,0x33,0x54,0x34,0xd7,0x00,0xc9,0xa0,0x07,0x03,0xc7,0x8a,0x65,0xa2,0x84,0x60,0xcd,0xaa,0xa2,0x46
+.byte 0x8c,0x67,0xd9,0xc1,0xe7,0x58,0xc5,0x1d,0xc0,0xb3,0xc6,0xb2,0x2a,0xfb,0x70,0x04,0xa2,0x25,0x7f,0x75,0x3c,0xd5,0x8e,0x9c,0x33,0xa2,0xdc,0x20,0x4c,0x26,0x5b,0xbe,0xd9,0x00,0x5d,0xa2,0xbd,0x42,0xbd,0x0d,0xd6,0x52,0x79,0xb5,0x67,0xf6,0x27,0x62,0xc8,0x64,0x05,0xc5,0x0f,0xae,0xe1,0x78,0x39,0xd1,0xb5,0x28,0xe9,0xd4,0x2a,0xaa
+.byte 0xd4,0xc4,0x3e,0x43,0x27,0x83,0xfa,0xdb,0x46,0x73,0x20,0xcd,0x2c,0xba,0x33,0xb4,0x77,0x10,0x32,0x3d,0x8e,0x56,0x88,0x81,0xe1,0x4c,0x8b,0x46,0x60,0xcb,0xb7,0x67,0xd7,0x7b,0xc2,0x47,0x7d,0xd8,0x2d,0x4c,0x09,0x9f,0x07,0x8e,0x34,0x45,0xf4,0x50,0x69,0xfd,0x35,0x0a,0x09,0x9e,0xac,0x49,0x5f,0xdf,0x72,0x84,0x97,0x93,0x30,0x2c
+.byte 0xc6,0x20,0x6f,0xb5,0x18,0x03,0xb6,0x30,0x23,0xc8,0xcd,0xa1,0x43,0xbd,0xbb,0x6f,0xde,0xb3,0xcb,0x1c,0xdd,0x41,0x71,0xfa,0x37,0xa7,0xa9,0x57,0x5a,0xf7,0xee,0xcd,0xb1,0xc1,0xb6,0x78,0x1c,0xe3,0xde,0x5c,0x02,0xc8,0xce,0xb7,0x8e,0x72,0xce,0xfd,0x79,0xcf,0x1a,0xef,0xcb,0x5b,0x5d,0x3c,0x1d,0xc8,0x1e,0x9f,0x67,0x26,0x86,0xd3
+.byte 0x3b,0x98,0x49,0x04,0xcd,0x1b,0x48,0x7c,0xa6,0xbe,0x37,0x0b,0x19,0xb1,0xb7,0x8a,0x74,0x0a,0xd9,0x4f,0x7b,0xbb,0x8e,0xc6,0x9b,0xdd,0xbc,0x61,0xfd,0xdd,0x86,0x7e,0x70,0x2e,0xe4,0x94,0xb4,0x62,0x47,0x6b,0x7c,0x92,0x41,0xda,0x05,0xdc,0xaf,0x5c,0x93,0xbc,0x7d,0xad,0xce,0x44,0x9e,0x27,0x1c,0x74,0x30,0x01,0xf2,0x8a,0x22,0xce
+.byte 0x88,0x61,0xf5,0xb8,0xe2,0xf0,0xca,0x14,0x21,0x53,0xd3,0xbe,0x95,0x8f,0x52,0x10,0x21,0xc5,0x25,0x16,0xa1,0x4f,0xef,0x9a,0x6f,0xce,0xe9,0xee,0x06,0xa8,0x32,0xa4,0xac,0xee,0xd8,0x95,0x0b,0x65,0x10,0xbc,0xb3,0x15,0x48,0xf9,0x96,0xee,0xde,0x5d,0xf6,0x38,0x5f,0x32,0x70,0xd1,0x29,0xa8,0x1d,0xdc,0xf4,0x34,0x2d,0x0c,0x93,0x48
+.byte 0x8c,0x40,0xed,0x35,0x41,0xfe,0x4b,0xab,0x20,0x7d,0x95,0x74,0x02,0xe5,0x71,0x76,0x7e,0x59,0x35,0xb3,0xd7,0x43,0x1f,0xd4,0xe6,0x02,0x86,0xba,0x4f,0x53,0xd9,0xc3,0x7d,0x7f,0x3d,0xb6,0xd8,0x92,0x07,0x89,0x99,0x46,0xf8,0x09,0xcd,0x19,0x43,0x93,0xa7,0xc1,0xb2,0x5d,0xec,0xbf,0x09,0xf4,0xba,0xfc,0xf7,0xf1,0xa7,0x2e,0xfe,0x71
+.byte 0x04,0x58,0xab,0x16,0xd7,0xc0,0xf7,0x03,0xd4,0xc4,0xb9,0xe4,0xd8,0xfc,0x5b,0x66,0xa6,0xb3,0x6a,0x94,0x0e,0xba,0x8c,0x54,0x5c,0x8c,0x02,0x0a,0x33,0xcb,0xde,0x1c,0xad,0x6d,0xef,0x48,0x05,0xa6,0xca,0x9a,0x27,0xd6,0x1c,0xc3,0xea,0x3a,0x46,0x20,0xec,0x72,0xc4,0x94,0x89,0x7e,0xba,0xa9,0x2f,0xe5,0xec,0x1a,0xe4,0x50,0x54,0xeb
+.byte 0xd9,0x5a,0x08,0xc5,0x84,0xc1,0x9a,0xdf,0xb0,0xd4,0x9a,0x6d,0xa2,0x93,0x52,0xd2,0x4d,0x69,0x88,0xc8,0x40,0x2d,0x26,0xbd,0x7a,0x37,0x04,0x21,0xe1,0x9d,0xc9,0xed,0xda,0x7a,0x4c,0x11,0x49,0x14,0x42,0xa1,0xdb,0x6e,0xed,0x1b,0x37,0xbf,0x09,0xac,0x35,0xda,0x80,0xf6,0x75,0xd4,0x32,0x54,0xb5,0x18,0xe8,0x79,0x25,0xc4,0x95,0xe8
+.byte 0x74,0xcf,0x6d,0xac,0x34,0x1f,0xea,0xd4,0x2e,0xd1,0x77,0x5e,0x90,0x8f,0x12,0x51,0xbb,0x3c,0xdf,0xe6,0xf4,0x49,0x8c,0x0f,0x9a,0x8e,0xe3,0x96,0xbd,0xba,0xe6,0x47,0x4b,0x50,0xc7,0xa9,0x29,0xea,0x09,0x5d,0xef,0x3c,0x91,0x48,0xc6,0x37,0xfd,0xac,0x7b,0xe5,0x04,0x25,0x93,0x0b,0xe3,0xce,0x32,0x46,0x38,0x81,0x97,0x57,0xbe,0x1f
+.byte 0x3c,0x61,0x2d,0xd1,0x4e,0xca,0xbb,0x44,0xc6,0xfd,0xdf,0xdd,0x11,0xbf,0xbf,0xa8,0xc0,0x32,0x67,0xc1,0x2e,0xd7,0xbe,0x3c,0xe3,0xcb,0x57,0xa5,0x6d,0xbb,0x8e,0x0f,0x69,0x22,0x42,0xef,0x53,0x0f,0xce,0x09,0x6a,0xda,0xbf,0xd6,0xed,0x61,0x67,0x82,0x83,0x13,0x63,0x97,0x7d,0x1a,0xad,0x34,0x77,0x37,0xa6,0xe0,0x89,0xaa,0xd4,0xb6
+.byte 0x8f,0x93,0xff,0xb8,0x8f,0x63,0x14,0xfd,0x17,0xff,0xe5,0x7c,0x83,0x23,0xaa,0xe0,0xb9,0xd9,0x94,0x3a,0x1a,0xe7,0xa5,0xbd,0xa6,0x2b,0xd3,0x49,0xca,0xeb,0x7d,0x87,0x1d,0x54,0x16,0x93,0xec,0x14,0x8b,0x77,0x3c,0xb4,0xbe,0x33,0x76,0x5e,0xcb,0x33,0x27,0xd3,0x20,0xd6,0xed,0x0c,0x66,0xb8,0xe0,0x00,0xa6,0x76,0xcd,0x8b,0xb4,0xef
+.byte 0x11,0xbc,0xe5,0x59,0xcf,0x1d,0xf5,0x15,0x58,0x4a,0xe1,0xfd,0x87,0x8c,0x7b,0xb9,0xa4,0x42,0x5a,0xed,0x51,0x7e,0x8d,0xa6,0x19,0xaa,0xc4,0xa6,0x14,0x74,0x45,0xb1,0xda,0x87,0x0f,0xd7,0xe7,0x66,0x3b,0xcd,0x04,0x02,0x14,0x20,0x41,0x15,0x4c,0x33,0x79,0x80,0x7d,0xd4,0x44,0x2c,0xab,0x6c,0xf4,0xa8,0xd4,0x31,0x43,0x7b,0xa7,0xc7
+.byte 0x65,0x0e,0x32,0xc8,0xc8,0x6d,0xf5,0x65,0x1b,0x26,0xf1,0xe4,0x68,0x15,0x88,0x1b,0x00,0x60,0x23,0x31,0xd7,0x4b,0x57,0xda,0xf1,0x19,0xa9,0xd9,0xaf,0xe6,0xa9,0x1e,0x2c,0x0d,0x23,0xe4,0x5b,0xcb,0x43,0x38,0xf0,0x93,0xd3,0xfb,0x6a,0x9b,0x83,0x30,0x55,0x96,0x9f,0x53,0x06,0x3f,0xaf,0x40,0x69,0xef,0x9a,0x47,0x6b,0xba,0x7c,0x10
+.byte 0x10,0x44,0x89,0xfa,0xb9,0x9e,0x70,0xed,0x25,0x59,0x68,0xae,0x9b,0x17,0xcf,0x80,0x6f,0x34,0xb8,0x07,0x40,0xe5,0x27,0x6d,0xcd,0x46,0x2c,0x36,0x90,0xf3,0x83,0x74,0x68,0x35,0xf2,0x05,0xa8,0xdf,0x4e,0x34,0xc5,0xb4,0xeb,0x5a,0x7d,0xe6,0x10,0x8a,0x23,0x54,0xeb,0x9b,0x27,0xf2,0x07,0xee,0xf9,0x05,0xc2,0x5a,0x88,0xbd,0x49,0x2e
+.byte 0x1b,0x00,0x31,0x68,0x4a,0xc9,0x3a,0xc5,0x93,0x82,0xa8,0x39,0xba,0x55,0xcd,0xc1,0xda,0x49,0xc2,0x4c,0xf4,0x93,0x00,0xcf,0x61,0xa4,0xbb,0x8c,0x64,0x33,0x90,0x14,0x6d,0x1d,0xad,0x75,0x97,0xd9,0x1d,0xfb,0x27,0x67,0x43,0x04,0xdc,0x4e,0xdf,0x0e,0x0c,0x7e,0x1c,0x89,0xfe,0x31,0xb7,0x9b,0x07,0x5e,0x99,0x08,0x22,0xef,0x6e,0x4d
+.byte 0x8b,0xd6,0x27,0xe6,0x24,0x1a,0x28,0xb0,0x22,0xa5,0x69,0x17,0x82,0x46,0xe3,0x90,0xe8,0x04,0xae,0x90,0x66,0x14,0xec,0xa2,0x1b,0x7e,0x09,0x13,0x32,0x9d,0xec,0x8b,0x51,0x5f,0xa8,0x96,0x8f,0x4c,0xc6,0xbd,0x5c,0x70,0x29,0x21,0xac,0xe9,0x6e,0xb0,0x0c,0x61,0x50,0xba,0xcc,0x55,0x71,0xda,0x2a,0x92,0x86,0x0c,0xff,0xaf,0x7a,0xcf
+.byte 0xaf,0x2a,0xbd,0xd6,0x15,0xa4,0x4c,0x2e,0x76,0x0d,0xcf,0x10,0x11,0x4a,0xd1,0x89,0xdd,0x46,0x5f,0x6b,0x5a,0x02,0x05,0x49,0x6f,0x98,0x6a,0xa7,0x8a,0x66,0x87,0x59,0x23,0xb5,0x3f,0x2e,0x95,0x73,0xfe,0x48,0xe9,0x0d,0x17,0xa6,0xa5,0x4e,0x40,0x98,0x79,0x40,0x1a,0x10,0x1d,0x84,0xdd,0x6f,0x17,0xa7,0xb7,0xfb,0x49,0xbd,0x54,0x97
+.byte 0x0f,0x42,0x25,0x95,0x83,0xf0,0x97,0xe7,0x4c,0x24,0xb5,0xe8,0x23,0x0a,0xd6,0xbf,0xef,0x2c,0x03,0x4f,0x87,0x59,0xe8,0x80,0x87,0xcc,0x51,0x1b,0x94,0xd8,0x60,0xe7,0x10,0x4d,0x01,0xfd,0x83,0xf2,0xd8,0x8d,0x1b,0x33,0xbf,0xaf,0x36,0x41,0x47,0x51,0xe0,0x45,0x2a,0x05,0x5f,0xe1,0x92,0xf8,0xa5,0x15,0x46,0x35,0xd8,0x9b,0xe0,0xff
+.byte 0xee,0xa6,0x4e,0x7d,0xfd,0x96,0xa5,0x75,0xdf,0x7e,0xb0,0x7d,0x14,0x73,0xdd,0xbe,0x17,0x6d,0xdd,0xec,0xac,0x9a,0x92,0x68,0xe3,0x44,0x16,0x63,0x22,0xa8,0x15,0x58,0x8c,0x11,0x23,0x46,0x18,0xae,0x47,0x39,0x87,0xc7,0x4c,0x30,0x09,0xce,0xe5,0xc4,0xd8,0x82,0xc6,0xc6,0x3d,0x31,0xf6,0x0f,0xb5,0x69,0x61,0x63,0x88,0xd6,0xb8,0xda
+.byte 0x89,0x29,0x87,0x69,0x6e,0x3f,0x55,0x2f,0xbc,0x91,0x91,0x43,0x7d,0xb3,0x7b,0x99,0x5a,0x5a,0xb0,0x7d,0x90,0xa7,0xe7,0x30,0x0d,0x32,0xb2,0x43,0x43,0x78,0x59,0x6e,0xbb,0xd7,0x76,0xd4,0x5b,0x4d,0xc4,0xa9,0x99,0xdd,0xd3,0xce,0x3d,0x13,0x41,0x38,0x33,0xed,0xb8,0x76,0x1a,0xbb,0xfd,0x26,0xcd,0x69,0x89,0x22,0x16,0x9a,0x21,0x35
+.byte 0x38,0x77,0x14,0x10,0x42,0x17,0x1f,0xa1,0xbf,0x55,0xb4,0x51,0x62,0x15,0xac,0xd0,0xa2,0x71,0xe4,0x32,0x89,0x33,0x8b,0x74,0xc6,0x61,0x38,0xd0,0xfe,0x28,0x69,0xe6,0x88,0x1b,0x11,0x7e,0x46,0x39,0xba,0x24,0xdd,0x1f,0x61,0xf4,0x74,0xad,0x58,0x94,0xa9,0x3e,0xc7,0x2a,0x9e,0xc0,0xe1,0x1c,0xee,0x21,0xab,0x3e,0x65,0x0c,0xe8,0xd8
+.byte 0x71,0x52,0xf3,0x6c,0x64,0x53,0x75,0x17,0x87,0x55,0x14,0x42,0x25,0x7f,0xe7,0x0d,0x89,0x1b,0x77,0x26,0xc4,0xaa,0xcc,0x91,0x47,0xe5,0x54,0xae,0x1a,0x0d,0x04,0x99,0xeb,0x56,0xd8,0xb4,0x6d,0xeb,0xec,0x2f,0x6c,0xc5,0x8e,0x76,0xe1,0xa0,0xa7,0x42,0x06,0xc9,0xc3,0x03,0xee,0xa9,0x9b,0x1e,0xfc,0x11,0xf5,0x2f,0x2b,0x14,0xb8,0x9f
+.byte 0x87,0x61,0x9b,0xc7,0x38,0x0e,0x58,0xf1,0xd4,0x36,0xca,0x82,0x85,0x9c,0xde,0xec,0xd3,0x1e,0x29,0x4e,0x70,0x9e,0x9a,0xe0,0x8b,0x6f,0xfe,0xd0,0xe9,0x95,0x51,0xcf,0x36,0x31,0x9c,0xff,0x63,0xc6,0x04,0x8e,0x61,0xc2,0xcb,0x3a,0xfa,0xd0,0xd7,0x29,0xbd,0xe7,0x8a,0x2b,0x8e,0xa0,0xac,0x58,0x93,0xb3,0x52,0xca,0x80,0x17,0xd2,0x2d
+.byte 0x93,0x5f,0xe0,0x8a,0x47,0x3c,0x67,0x95,0x64,0x91,0xa4,0x76,0xa4,0x5f,0xfa,0x93,0x4d,0xc7,0x6e,0x5d,0x23,0x9f,0xe1,0x4a,0x16,0xff,0xa5,0xf0,0x94,0xa8,0x02,0xcc,0x9a,0x84,0xd5,0x9d,0xb6,0xe5,0x7c,0x76,0x3f,0xc9,0xfd,0xdc,0x8e,0x59,0x9a,0x22,0x18,0x3c,0xe6,0x90,0x85,0x10,0x73,0x2d,0x65,0xa7,0xa7,0xe1,0xeb,0xc5,0x05,0x24
+.byte 0x1e,0x0b,0x31,0x19,0xb5,0xb0,0x8d,0xc0,0xb5,0x04,0xfe,0x9d,0xfa,0xf7,0xcd,0x71,0x29,0x40,0x19,0x23,0xed,0x2c,0xdb,0x89,0x89,0x8d,0x69,0x22,0x4c,0x9c,0xa7,0xf7,0xb1,0x56,0x87,0xa3,0x44,0xa9,0xa3,0x16,0x28,0xce,0x94,0x40,0x6f,0x71,0x77,0x0e,0x6d,0xe9,0x78,0xa2,0x2a,0x17,0x45,0x03,0xeb,0x1e,0xf1,0xfa,0x56,0x3e,0xa7,0x6b
+.byte 0x08,0x06,0x6a,0xcb,0x8f,0x5e,0x0f,0xd3,0x6e,0x4b,0x21,0x31,0x73,0x50,0x94,0x56,0xf9,0xb9,0xc7,0x38,0x69,0xe8,0x09,0x3f,0x03,0xb3,0xb5,0xe8,0x2a,0x5e,0xf6,0xad,0xae,0x6f,0xab,0x6a,0x49,0xdd,0x93,0x6d,0xfb,0x8b,0xde,0xea,0x8b,0xb0,0xa1,0x44,0xf0,0xb3,0xf6,0xaa,0xe3,0xc8,0x04,0x87,0x9f,0x8b,0xee,0xab,0x13,0x1d,0x2d,0xeb
+.byte 0x09,0x62,0x21,0x49,0x5f,0xb6,0x95,0xab,0xc4,0xee,0x69,0xfb,0x31,0xff,0xbf,0x1a,0xa6,0x4c,0x67,0x66,0x84,0xe6,0x0c,0xb7,0xb2,0x3e,0x3f,0xa4,0xb3,0x52,0xde,0x15,0xc9,0xa7,0xa9,0xb5,0x0d,0xe5,0x0b,0x99,0xa6,0xb6,0x8f,0x69,0xc5,0x6d,0x6c,0xbb,0x83,0x89,0x4e,0xfc,0x49,0x79,0x4d,0x46,0x31,0xa0,0x09,0x5f,0x5d,0xd0,0x5b,0x80
+.byte 0xa1,0xf4,0x36,0x48,0x97,0x6a,0xfd,0x34,0xcb,0x20,0xa8,0x01,0x25,0x04,0xe7,0x13,0x12,0x87,0x66,0x27,0x96,0x36,0xba,0x92,0xbd,0xda,0x94,0x11,0xef,0x90,0xbd,0xbc,0x9e,0xf9,0x63,0xb3,0xa6,0xc1,0xbb,0x46,0xe8,0x86,0x3f,0x2d,0xf9,0x11,0x3a,0x23,0xa8,0x7a,0x33,0x41,0x3e,0x2e,0x5d,0xde,0xc0,0xd2,0x23,0xca,0x41,0xa0,0xb9,0x70
+.byte 0x6d,0x31,0xf3,0x89,0x87,0x9b,0x72,0xd9,0x15,0x4d,0x8b,0x51,0xdd,0x56,0xa1,0xb4,0x68,0x52,0x65,0x81,0x12,0x46,0xea,0x24,0xb4,0x34,0xcc,0xa0,0xdb,0x7d,0x96,0xd9,0x8e,0x64,0x61,0x10,0x7c,0x2a,0x00,0x4d,0x82,0x61,0x54,0xa4,0x70,0x3d,0x9c,0xa5,0x0b,0xd2,0x08,0x71,0xa8,0x94,0xb1,0xb4,0x30,0x61,0x59,0x9f,0x72,0x61,0x56,0x2d
+.byte 0xa3,0xf4,0x9d,0x1c,0xfc,0x49,0x9d,0x39,0x27,0xcb,0x54,0xb2,0xce,0x3c,0xb6,0x76,0xe5,0x8e,0xa5,0xe7,0x08,0xd4,0xc7,0x2c,0xa6,0x28,0xc8,0x3e,0x22,0x14,0x06,0x75,0x68,0x0d,0x6b,0xb5,0xa3,0x68,0x14,0x17,0xfe,0xb8,0xcc,0x26,0x5b,0x9d,0x0b,0xcc,0x3e,0xd7,0x6c,0xe0,0xec,0x5e,0x1e,0x1e,0xb8,0x9a,0xbe,0x91,0xb5,0xa6,0xb5,0x83
+.byte 0x28,0xc2,0x35,0x65,0xd3,0xde,0xdd,0x71,0x29,0x13,0xc1,0xee,0x78,0x22,0x34,0x0b,0x77,0x3a,0x48,0x98,0x26,0x43,0xc2,0xce,0x03,0xe8,0x75,0xf8,0x8a,0xdf,0x6a,0xb0,0xb4,0x8c,0x11,0x8c,0xe5,0x95,0x96,0x17,0xfb,0x06,0x5e,0x8f,0x36,0x10,0xc5,0x04,0x43,0x1b,0xed,0xd3,0xad,0xd4,0xa4,0xe0,0x17,0x85,0xed,0x9b,0xd8,0xae,0x98,0x46
+.byte 0x58,0x57,0x0e,0x46,0xea,0x3f,0x07,0x6d,0x0e,0x46,0xda,0x2f,0x68,0x2b,0xd6,0xe7,0x0d,0x4b,0xbe,0x32,0xee,0x10,0x73,0x18,0x7d,0x6b,0x2d,0x04,0x27,0x72,0xb1,0xe1,0xbf,0x89,0xaa,0x4d,0x1a,0xfc,0xbd,0xf2,0xc3,0x9f,0xf0,0x01,0x85,0x62,0x09,0x4d,0x08,0x2c,0x57,0x9a,0x7b,0xad,0x0b,0x79,0xff,0x14,0xa1,0x45,0xde,0x21,0x8f,0xe2
+.byte 0x93,0xd0,0x35,0x26,0xc3,0xbc,0x8c,0xb7,0x57,0x6a,0xdf,0x98,0xa7,0x75,0xc6,0xf6,0x4b,0x5f,0x91,0x6e,0x71,0x3a,0x5c,0x5f,0x57,0x63,0x34,0x87,0xf8,0x20,0x6a,0xa1,0xbf,0xf8,0xca,0x8e,0xf9,0xa9,0x10,0x8b,0xab,0x0b,0xc2,0xcc,0x71,0x89,0x7c,0xef,0x70,0x3a,0xb0,0xf6,0x90,0xcc,0x6b,0x2c,0xcc,0x8b,0x2a,0x21,0x78,0x23,0xa0,0x71
+.byte 0x8c,0x7b,0xc1,0x0f,0x27,0x72,0x40,0xe4,0x9e,0x35,0xf3,0x0a,0xc0,0x7e,0x7f,0xe5,0x9b,0xdb,0x93,0x49,0x08,0xc3,0x6b,0xb7,0xea,0xea,0xd4,0x5a,0x96,0x97,0x3c,0xdf,0xc7,0x02,0x39,0x9f,0xa3,0xca,0xdd,0x62,0xf3,0x68,0xc7,0xae,0x37,0xc1,0x35,0x73,0xb2,0x5d,0x99,0xe4,0xae,0x27,0x55,0x5e,0x6a,0xae,0x6f,0x1a,0x95,0x51,0xb1,0x3b
+.byte 0xd7,0xb4,0x4d,0x3d,0x88,0x54,0x01,0xbe,0x2c,0x12,0x17,0x29,0x4f,0xf3,0xed,0x5a,0x1f,0xa9,0xf0,0x67,0xbd,0x7c,0xad,0xe5,0x58,0x52,0xd4,0xd1,0xfe,0x1e,0x1b,0xd6,0xce,0x7c,0xc3,0xa2,0xa9,0x72,0x9b,0x6a,0xe5,0xf9,0x39,0x22,0xaa,0x7f,0x2e,0xa2,0x53,0x75,0xf0,0x99,0x2e,0x36,0x86,0x83,0x10,0x63,0xd7,0xac,0xa3,0x52,0xa6,0x23
+.byte 0x80,0x46,0xe4,0xa9,0x07,0x79,0xe1,0x61,0x75,0xbf,0x08,0x31,0x6c,0xdd,0xe1,0x30,0xd0,0x35,0xc2,0xbd,0x30,0xb8,0x85,0xf3,0xd2,0x2c,0x90,0x7a,0xf0,0xd3,0x80,0xe5,0xf1,0xc2,0x58,0x3d,0xf7,0x3c,0xbc,0xff,0x03,0x4d,0xf7,0xad,0x2f,0xa6,0xfe,0x73,0xde,0xa8,0x60,0xd7,0x89,0x4a,0xcf,0x3d,0xf3,0xab,0x62,0xfa,0x9d,0x46,0xad,0xd0
+.byte 0x97,0x6f,0x89,0x84,0x16,0x9b,0x84,0xb2,0x6c,0x63,0x6d,0x29,0xee,0x8e,0x97,0x3c,0x48,0x19,0x92,0x62,0xdc,0x1d,0x35,0x9d,0xec,0x01,0x00,0x64,0xbf,0x4d,0x8b,0xa3,0x13,0x48,0x9f,0xb4,0x01,0x0d,0xb1,0xc4,0xf2,0xf2,0x6a,0x84,0x1a,0x07,0x3c,0x46,0xa6,0xb5,0x41,0x9a,0x32,0x7e,0xc3,0x4f,0x87,0x95,0x71,0x7a,0xbf,0x74,0xf8,0x0b
+.byte 0xfb,0xa5,0xde,0xa8,0x35,0xf1,0xcb,0x04,0x8d,0x8b,0xd3,0xb0,0xc8,0x1d,0x6c,0xaf,0xb4,0x21,0x79,0x1c,0x34,0x71,0x2f,0xf5,0xc4,0xbe,0xad,0xbc,0xaf,0x2f,0x54,0x81,0xd9,0xf8,0xff,0x59,0xf9,0x4e,0x62,0x9f,0x7d,0x7c,0xe9,0xdc,0x67,0xae,0xa3,0x32,0x4b,0xf7,0x4e,0x53,0x4c,0x55,0x7d,0xc5,0xdd,0xd4,0x5d,0x93,0xb8,0x98,0x3e,0xd3
+.byte 0x15,0x65,0x52,0x78,0x5a,0xd2,0x21,0x84,0x5d,0x28,0xaf,0x44,0x7d,0x18,0xf8,0xdd,0x5c,0xc3,0x6e,0xc8,0x05,0x05,0x30,0xd0,0x82,0xf8,0x00,0x0f,0x3d,0x5c,0x62,0x7e,0xa6,0xd5,0x7b,0x9f,0xb1,0x44,0xb7,0x0d,0x22,0x81,0xe1,0x4a,0x2b,0x79,0x7e,0x39,0x4d,0x8a,0x9a,0xfd,0x94,0x0c,0xf7,0x23,0x10,0x99,0xd2,0xd2,0x8b,0x98,0xe5,0x9d
+.byte 0xb0,0xbf,0xcf,0x06,0x08,0x80,0x32,0x69,0xfd,0x81,0x5f,0xb3,0x66,0x11,0x63,0xeb,0x30,0x1d,0xcd,0x5b,0x5b,0xec,0x0c,0xca,0x30,0x37,0xa0,0x82,0x79,0x75,0x87,0xc1,0xfa,0x5b,0x38,0x4b,0xe3,0xea,0x46,0x49,0x36,0x92,0x92,0xf0,0xc9,0x15,0xa5,0xec,0x9e,0x21,0xb6,0x9f,0xb4,0x6d,0xf6,0xef,0x5c,0x2f,0x7d,0xa4,0xb3,0x25,0xfb,0x13
+.byte 0x40,0xe1,0xa0,0x20,0x4a,0x3a,0xe2,0x3e,0xf5,0xe0,0x68,0x61,0x11,0x9a,0xfb,0x1e,0xe8,0x1b,0xe0,0x17,0x9c,0x8a,0xe5,0x53,0x74,0xdd,0xec,0xc6,0x03,0xc6,0xd0,0x9b,0xc2,0x0b,0x77,0x4c,0x36,0x2b,0xac,0x4e,0x4d,0xd2,0x26,0x70,0x39,0x96,0xb4,0x11,0x1a,0x5b,0xcc,0x3f,0xb9,0xcf,0x0d,0x04,0x55,0x05,0x00,0x66,0x8f,0xa9,0xec,0x31
+.byte 0xe5,0x47,0x4c,0x9b,0xb7,0x6e,0xa5,0xe7,0x9e,0x70,0xf4,0x02,0x2a,0x3c,0xa2,0x03,0x04,0x30,0x9e,0x3f,0x7c,0xaa,0x0a,0x8f,0x55,0x61,0xca,0x50,0x35,0xe6,0xa4,0x24,0x61,0x26,0x31,0x9e,0x9e,0x77,0x0d,0x15,0x3a,0xc0,0x88,0x32,0xb5,0xbb,0x3d,0x3e,0x59,0x25,0x52,0x81,0x2e,0x4b,0xc6,0x5d,0x9f,0x87,0x0f,0x1f,0x5e,0xec,0xdd,0xbe
+.byte 0x32,0x6c,0x71,0xef,0xd2,0x9c,0xfd,0x70,0xc8,0xf6,0x1f,0xb9,0xc9,0xdd,0x4d,0x39,0x61,0x92,0xbd,0x0c,0x48,0x63,0x4b,0xd2,0x2b,0x8c,0x4b,0x35,0xb1,0x8e,0x04,0x44,0x3c,0xe1,0xde,0xfd,0x6e,0xde,0xeb,0x94,0x51,0xea,0x36,0x7b,0xc6,0x87,0x15,0x34,0x68,0xa0,0xb8,0x94,0xb6,0x56,0x33,0xf4,0xab,0x84,0xed,0x1c,0x36,0x91,0xa7,0x1b
+.byte 0x03,0xca,0x48,0x64,0x16,0x5b,0x4b,0x69,0x47,0xae,0xd7,0xc9,0xcf,0x74,0xd2,0xbd,0x60,0x04,0x7c,0x66,0xe9,0x12,0x92,0x40,0x78,0x23,0x0b,0x5b,0xa0,0xda,0xf7,0xe4,0x9a,0xad,0x9c,0x31,0xe7,0xaa,0xad,0x5a,0xc3,0x45,0x00,0x6c,0xd3,0x4d,0x93,0xdf,0xb6,0x68,0x11,0x3f,0x2a,0xbc,0x9a,0x8d,0xeb,0x0f,0xb5,0xa9,0x8e,0xa5,0x2c,0x99
+.byte 0x94,0x8d,0x21,0xa9,0x41,0x6b,0x11,0x2e,0x02,0x21,0xd8,0xc1,0xbc,0xf0,0x2a,0x87,0xae,0x35,0xa9,0x78,0x5c,0x43,0xb8,0xb7,0x63,0x2d,0x09,0x31,0xae,0x6f,0xfc,0x39,0x7b,0x18,0xc3,0xce,0xe3,0xfa,0x51,0x70,0xc7,0x6b,0x5e,0xc3,0xce,0xc8,0xa2,0x3a,0x66,0x9e,0xfe,0x45,0xb4,0xa2,0xaf,0x81,0x03,0x74,0xbf,0x0c,0x65,0x4c,0x30,0x27
+.byte 0xd5,0x34,0x29,0x2d,0x83,0xa8,0xb9,0x1d,0xf8,0x12,0x09,0x51,0xdd,0x0e,0x66,0x95,0xf3,0x94,0xaa,0x83,0x3a,0x6f,0x8a,0x7c,0x3a,0x29,0x82,0xbb,0x80,0xa1,0x37,0x8c,0x79,0xf4,0x4a,0xa8,0xe4,0x17,0x72,0x77,0xee,0xc4,0xaa,0x25,0xd3,0x8f,0x2e,0xaf,0xb9,0xb2,0x3c,0xa6,0xd5,0x72,0x97,0x07,0x23,0x38,0xae,0x9e,0x22,0x08,0x85,0x70
+.byte 0xfa,0xff,0x38,0xe6,0x96,0x9f,0x2c,0x11,0x14,0x16,0x9a,0xfa,0x5a,0x7b,0x05,0x31,0x3e,0x20,0xbf,0x4d,0x87,0xaa,0xba,0x94,0xcd,0xdb,0xeb,0xec,0x29,0x58,0x4e,0x43,0x12,0xe8,0xf9,0x01,0x50,0xc8,0x51,0x7a,0x61,0x12,0xe9,0xed,0xc2,0xd6,0x2e,0xd3,0xed,0x54,0x72,0xf7,0x1b,0x0c,0x8c,0xb4,0x65,0xea,0x22,0x31,0x22,0xeb,0xcd,0x53
+.byte 0x66,0xf1,0xa5,0x34,0xe9,0x81,0x74,0xcb,0xb5,0x6b,0x45,0x71,0x69,0x6d,0x84,0xe8,0xc6,0x86,0xc9,0xdd,0x0c,0xa4,0x30,0x12,0x08,0x42,0x10,0x6b,0xcd,0x65,0x6c,0xfd,0x9c,0xde,0x77,0x3c,0x32,0x09,0xef,0x99,0x27,0x0e,0x4a,0x72,0x03,0x8d,0xb5,0x68,0xa0,0x67,0xf7,0xc2,0xae,0xb8,0xce,0x41,0x70,0x4e,0xdd,0x13,0xcb,0x3f,0x05,0x4e
+.byte 0xf4,0xbc,0x88,0x98,0x2f,0x42,0x4e,0x5f,0x3e,0xcb,0x2c,0xd3,0x2f,0xb8,0x92,0xbb,0xd8,0x95,0xc8,0xaf,0xa9,0x44,0x8b,0xf0,0x2f,0x81,0xd4,0xe7,0x06,0x19,0xf7,0xa7,0x0a,0x73,0x3e,0x30,0xd9,0x00,0xe4,0x2d,0x76,0xb1,0x0d,0xfa,0x12,0x1f,0xbe,0x59,0x4f,0xf7,0xc8,0x5b,0xab,0xd7,0x16,0x3d,0x7e,0x97,0x9e,0xec,0xf8,0xcb,0x31,0x2e
+.byte 0xe0,0x41,0x0b,0x00,0xa6,0x6d,0xe9,0x5e,0xd5,0x4a,0xc5,0xbf,0x1c,0xcc,0xa5,0x71,0x94,0x29,0x3d,0x17,0x43,0x27,0x63,0xc4,0xc7,0x8f,0x1b,0xb7,0x5f,0xcf,0xdf,0x8e,0x6a,0x69,0x87,0xc1,0x29,0xab,0x7b,0x8d,0xdf,0x07,0x95,0x50,0xa3,0x1c,0x8e,0xdc,0x7f,0x8a,0x21,0x37,0x1e,0x26,0xa7,0x67,0x28,0xb2,0xc8,0x23,0x5a,0x1d,0x94,0x46
+.byte 0x1b,0x3e,0x72,0x87,0x73,0x08,0xe2,0x3b,0x46,0x51,0xbe,0x5b,0xa9,0x72,0xb9,0xf8,0x45,0x6d,0x0c,0x89,0x80,0x0d,0x7a,0xfb,0x4c,0x3f,0x7f,0x3d,0x29,0xff,0xef,0xb2,0xec,0x23,0xc2,0x26,0xcf,0x8c,0x2e,0x28,0xbf,0xc5,0x68,0x47,0xd9,0x49,0x95,0xf1,0x67,0x7e,0x3a,0x48,0xe2,0x43,0x5c,0xc8,0x95,0x5b,0xb2,0xf3,0x22,0xc9,0x73,0x91
+.byte 0xb5,0x78,0x96,0x1b,0x9a,0x75,0x5f,0xb2,0x6b,0x8c,0x66,0x8c,0x8e,0xc1,0xe1,0xde,0xd6,0x64,0x31,0xe1,0x7b,0x12,0xd2,0x85,0x8f,0x52,0x68,0xec,0x80,0x26,0x3d,0xcc,0x9b,0xe3,0x57,0xbe,0x19,0x42,0xb9,0xdd,0x7d,0x2b,0x5b,0x6d,0x1b,0x9e,0x96,0xd7,0x75,0x83,0x82,0x3c,0x3e,0x5f,0xf8,0xa9,0x36,0xbe,0x14,0xc7,0xce,0x9d,0x05,0x7e
+.byte 0xd7,0x38,0x37,0x35,0xc9,0x37,0x8b,0x9f,0xc6,0x2d,0xff,0x00,0x41,0xff,0x1b,0x09,0xea,0xd2,0xb0,0x04,0x48,0xff,0xfc,0xb5,0x67,0x54,0x39,0x3d,0x23,0x68,0x0b,0x7d,0x97,0xf3,0x65,0x20,0xa2,0xf8,0x33,0x96,0xd1,0xf4,0xc7,0xba,0x6f,0x00,0x95,0x36,0xf6,0x33,0xd1,0x8d,0xde,0xee,0x1e,0xfa,0x60,0x8e,0x5e,0x4c,0x70,0xbb,0x53,0x79
+.byte 0xc9,0x9a,0xdf,0x3c,0x53,0xe4,0x35,0x87,0xc3,0xe6,0x8e,0x0e,0x1a,0xd0,0xf8,0x57,0x2b,0x33,0x51,0x4d,0x7d,0x43,0x17,0x3e,0x6f,0x0e,0xca,0x86,0xb2,0xc6,0x09,0xf3,0x2f,0xc1,0x5f,0x0e,0x9a,0x5e,0x7d,0x9d,0xf7,0xff,0x09,0x46,0xe5,0x30,0x91,0x61,0x93,0xb5,0x2f,0xc5,0x7f,0x09,0x0b,0x55,0x94,0x17,0x25,0x19,0x9b,0xa9,0x0e,0x68
+.byte 0x71,0x18,0x1b,0x4b,0x1b,0xa3,0x75,0x90,0x56,0x96,0x5e,0x33,0x71,0xf2,0x06,0x69,0x07,0x04,0xcb,0x8c,0x79,0x9b,0xa5,0x17,0xd8,0xd8,0x77,0xc7,0xca,0x95,0x58,0x12,0xec,0xdd,0x41,0xc9,0x12,0x16,0x9a,0xc4,0xf0,0x27,0x7a,0x8e,0xeb,0x19,0x79,0x27,0x7b,0x2e,0x55,0x96,0x57,0x19,0xbe,0x55,0x8c,0x7f,0x97,0x90,0x80,0x40,0x5d,0x5a
+.byte 0xf6,0x07,0xd6,0xb4,0xc5,0xe8,0x0e,0x54,0xde,0x78,0x23,0xca,0x39,0x90,0x42,0xb6,0x8b,0x14,0x22,0x06,0x71,0x77,0xd5,0xf7,0x8d,0x05,0x9d,0xbf,0xfe,0x38,0x91,0xba,0x79,0x85,0x30,0x47,0x25,0xf0,0xa2,0x72,0x55,0x94,0x2a,0x8a,0xc8,0x28,0xc8,0xa9,0x23,0xab,0xf0,0x4e,0x49,0x2f,0x58,0x53,0x35,0xd1,0xb6,0x16,0x81,0xc2,0x25,0x18
+.byte 0xd9,0x71,0x91,0xc4,0x81,0x3e,0xf4,0xd7,0x87,0x9e,0x57,0x78,0xf7,0x7d,0x4b,0xb2,0xfd,0x91,0x9f,0xa8,0x0e,0x77,0xb3,0xc7,0xe5,0x6a,0x95,0x17,0xc3,0xf4,0xcb,0x7f,0x96,0xc1,0xa8,0xee,0x6a,0x0f,0x1f,0x5d,0x20,0x28,0x93,0xe5,0xf3,0x13,0x46,0x53,0x47,0x9f,0x98,0xc6,0xf5,0x29,0x69,0xb9,0x83,0x36,0x03,0xa1,0x9a,0xb4,0xa9,0x4e
+.byte 0xd6,0xda,0x25,0xe2,0x5b,0xbb,0x95,0xdf,0x0f,0x37,0x0b,0x02,0x51,0x03,0xd1,0x0e,0x84,0xef,0xdd,0x85,0xdd,0xae,0x10,0x32,0x65,0x03,0x65,0xf0,0x8e,0x0c,0x69,0x90,0x35,0x26,0x36,0xe8,0x05,0x46,0xe6,0xce,0x52,0x4d,0xb5,0x93,0x9f,0xe3,0xe5,0xb0,0x43,0x57,0x32,0x5d,0xca,0xd4,0xc9,0x89,0x2e,0x5b,0x03,0x8a,0x82,0x78,0x21,0x6b
+.byte 0x41,0xa9,0x0a,0x9f,0xe0,0x50,0xec,0x72,0x01,0x67,0xe7,0x1c,0x92,0xe3,0xe4,0x83,0x4d,0x4b,0xcf,0x01,0x37,0x2f,0x34,0x86,0xcf,0x36,0xf7,0x3a,0x57,0xa3,0x89,0x73,0x0f,0x9c,0x06,0x82,0x75,0x7a,0x4b,0xd8,0x44,0x40,0xf2,0xc5,0xc4,0x22,0xa6,0x99,0x1b,0x73,0x2f,0xad,0x09,0xe9,0x84,0x6f,0xc3,0xca,0x72,0x3a,0x8a,0x55,0x55,0x0a
+.byte 0xcd,0x33,0x51,0xef,0x5b,0x36,0x77,0x6c,0xb4,0x4a,0xae,0xdd,0xbd,0xec,0x65,0x99,0x43,0xd6,0x8a,0x16,0xba,0x89,0x4d,0x0c,0x11,0xb4,0x0d,0x5d,0x3e,0x76,0xcb,0x48,0x9d,0x31,0x40,0x71,0xe2,0xe4,0xa9,0xd9,0x6e,0x3c,0x3d,0xd1,0x6e,0xaf,0xb9,0x28,0x71,0x5a,0x07,0x6f,0xab,0xdb,0xf8,0x4f,0x11,0xbc,0xe0,0x14,0x01,0x43,0x4d,0xe2
+.byte 0xad,0x5d,0x2a,0xb2,0x58,0x66,0x05,0x50,0x66,0xf6,0x2f,0x66,0x11,0xd1,0xd7,0x05,0x85,0xb0,0x7f,0xa8,0x89,0xbd,0x41,0xda,0x35,0x1e,0xbb,0xff,0x70,0x1a,0xe8,0x65,0x96,0xe9,0x50,0x18,0x7f,0x4c,0xb2,0xe2,0x95,0x26,0xf6,0x37,0x09,0x8c,0x8d,0x7b,0x02,0xb0,0x7f,0x32,0xb5,0x70,0x22,0xd6,0x83,0x0b,0x85,0x25,0x00,0xc5,0x55,0x3f
+.byte 0xfa,0x7a,0xc9,0xaf,0x87,0xc1,0x1c,0x11,0x96,0x71,0x18,0xd8,0xdb,0xab,0x86,0x57,0x0a,0x16,0x23,0x32,0x40,0xd3,0xaf,0x17,0x55,0xe3,0xe7,0x01,0x65,0x1f,0x87,0xda,0xb5,0x46,0x67,0x18,0x34,0xcc,0x28,0x77,0xc3,0x12,0x62,0x6c,0x8b,0x8a,0x11,0x7a,0x5a,0xd1,0xdf,0xb3,0x13,0x6b,0x29,0xce,0xf8,0x03,0xba,0xad,0x7c,0x14,0x60,0x42
+.byte 0x17,0xf6,0x7b,0x0c,0xb7,0x5f,0xd6,0xc1,0xb5,0xa5,0x2b,0xb1,0x9f,0x6c,0x65,0x29,0xe5,0xf4,0x84,0x85,0x11,0x82,0xf1,0x4c,0xcd,0xff,0x99,0x29,0x53,0x7b,0x43,0x04,0x60,0xc4,0x6c,0x01,0x5c,0xcb,0x33,0x4f,0xdb,0xc4,0xad,0x8c,0xea,0xff,0xd6,0xcd,0x8e,0x85,0x6e,0x54,0xd5,0x18,0x63,0x84,0x78,0xea,0xff,0x08,0x95,0xdc,0x2a,0x07
+.byte 0xac,0xea,0x44,0x79,0x52,0x07,0xf3,0xf1,0x03,0x7f,0x71,0x53,0xd8,0x85,0xdb,0x70,0xde,0x5e,0xd5,0x9a,0x18,0x9f,0xcc,0x3f,0xc0,0xc0,0x49,0x82,0x70,0x09,0xce,0x29,0x04,0x0a,0x19,0x81,0xd9,0x81,0x22,0x71,0x48,0x8e,0x79,0x08,0x1c,0xb4,0xc8,0x7e,0x60,0x43,0x4a,0xe3,0xd5,0x6b,0x09,0x5c,0x01,0x6e,0x20,0x9e,0xd2,0xaf,0x80,0xb7
+.byte 0xa2,0x0a,0x5b,0x26,0x08,0x32,0x73,0xbc,0xc6,0xfd,0x06,0xaa,0x2e,0x55,0xa0,0x5b,0xa9,0x3c,0x85,0xb2,0x04,0xdc,0x9a,0x94,0x02,0x93,0x96,0x6b,0x3e,0xc3,0x5e,0x37,0x9b,0x6f,0xef,0xb9,0x65,0x52,0x42,0x1c,0xa7,0x84,0x09,0x0c,0x49,0x3a,0x95,0x06,0x94,0xd7,0xc7,0x40,0xf5,0xf1,0x69,0x41,0xfb,0xf8,0x57,0xb5,0x1e,0x0c,0xf3,0xd9
+.byte 0xb1,0x2e,0x58,0x33,0xbe,0xb1,0x3d,0x61,0xc6,0xca,0x01,0xe5,0xda,0x60,0x8f,0x87,0xf7,0x9a,0xb5,0x92,0xb4,0x8c,0x2a,0xaf,0xd4,0x1e,0x9c,0x97,0x39,0x83,0x99,0x4a,0x07,0x54,0x75,0x7d,0xde,0x72,0x06,0xc1,0x8f,0xb4,0xde,0x12,0x43,0xf2,0x62,0xae,0xe7,0xec,0xfe,0xb2,0xe5,0x63,0x35,0xb7,0xee,0xaa,0xf0,0x09,0xb8,0x61,0xf2,0x42
+.byte 0x28,0x87,0xd7,0x47,0xa8,0xfc,0x51,0x85,0x6f,0xa2,0xb1,0xa6,0x82,0xd6,0x0e,0x1b,0x3f,0xea,0xa1,0xe1,0x91,0xc9,0xd2,0x5b,0x3e,0xff,0x18,0x39,0x14,0xe0,0x44,0xda,0x3d,0xd8,0xca,0xdb,0xd9,0xbf,0x3f,0xa4,0xdb,0x99,0x2e,0x31,0x32,0x7c,0xf4,0x61,0x2f,0xa1,0xf9,0xa9,0xbe,0x26,0x94,0xea,0xb4,0xe3,0x25,0x8d,0x93,0x3b,0xa1,0x7e
+.byte 0x1e,0x99,0x87,0x6c,0xaf,0x14,0x54,0xd0,0xc0,0x37,0x39,0x76,0x3c,0x07,0x2e,0xce,0x98,0x25,0x81,0xe4,0x01,0x0c,0x07,0x79,0x4e,0xcd,0x82,0x44,0x83,0x04,0x07,0xa6,0x52,0xb7,0x96,0x7c,0x43,0x12,0xe1,0xc5,0x12,0x18,0x25,0x47,0xe4,0x19,0x6d,0x26,0x1e,0x55,0x66,0xca,0x28,0x4c,0xfa,0xd2,0xd9,0xcc,0x7e,0xad,0x9f,0x2a,0x2f,0xc6
+.byte 0x6c,0x77,0xaa,0x0f,0x5b,0xeb,0x15,0x97,0x62,0x52,0x3c,0x6f,0x4b,0xf3,0xcc,0x80,0x7b,0x1f,0x1d,0x58,0xf8,0xfe,0xc1,0x8c,0x3b,0xe3,0xd7,0x05,0xc3,0xd6,0xa9,0xda,0xcf,0x85,0x1c,0x68,0xd6,0x6d,0x2b,0x06,0x30,0x5f,0x58,0x39,0xea,0xfa,0x99,0xaa,0x04,0x10,0x05,0xaf,0xb0,0xf7,0x32,0x60,0x8d,0xe4,0xd1,0x40,0x32,0xd6,0xa3,0xf2
+.byte 0xba,0x5a,0x79,0x58,0x92,0x75,0xf0,0x3a,0xce,0xb2,0xee,0x66,0x3e,0xe3,0xbe,0x4d,0x53,0x9d,0xbb,0xdb,0x45,0xf0,0x09,0xeb,0xd5,0x83,0x39,0x20,0x06,0xa9,0x44,0x35,0xeb,0x6d,0x9b,0xd9,0xa4,0xda,0x4b,0x9d,0xde,0x3d,0x26,0xa2,0x2d,0xcf,0x8e,0x3e,0xbc,0xb4,0x8c,0x3a,0xbf,0x56,0x7c,0x48,0x50,0xb5,0xc5,0xbe,0x84,0x5e,0x63,0x82
+.byte 0x5f,0x87,0x77,0x4a,0xa7,0xf6,0x66,0x07,0x42,0x6a,0xb0,0xcf,0x19,0xaf,0x6c,0x16,0x85,0x78,0x88,0x3b,0xa5,0xbc,0x42,0xd2,0x4c,0xdf,0x51,0x3b,0xc4,0x0e,0xf5,0xc5,0x70,0x57,0x40,0xf6,0xed,0xd2,0x37,0x3e,0x14,0x0c,0x31,0xda,0x94,0x87,0x6b,0xd9,0x8c,0x15,0x41,0xa9,0xc0,0x2a,0x61,0xd3,0x52,0xe0,0xb6,0x0a,0x83,0x6b,0x75,0x1b
+.byte 0x1e,0xd1,0x7f,0x26,0x19,0x34,0x9b,0x70,0xc9,0xba,0xdc,0xa2,0x03,0x6d,0xc7,0xac,0xbd,0x2c,0x63,0x8a,0x7b,0xb1,0x62,0x51,0xc1,0x1d,0x54,0x0d,0x34,0x0e,0xfb,0xa6,0xb8,0x9d,0x79,0x4f,0xc3,0xaa,0x8d,0xa0,0xcc,0x80,0x96,0x86,0x37,0xd6,0x80,0x9c,0x3d,0x91,0xd0,0xe7,0xe2,0xb4,0x00,0xba,0x86,0xe9,0xeb,0x86,0xea,0x84,0x78,0x81
+.byte 0x20,0x29,0x28,0x02,0x4d,0xd8,0x1b,0x5e,0x4f,0x41,0xfc,0x13,0x3e,0x4c,0x7f,0x64,0x55,0x35,0x41,0x0d,0x74,0xc5,0x6a,0x7c,0x37,0x82,0x41,0xbd,0x67,0x39,0xd9,0x83,0xfa,0x7f,0x8c,0xe1,0x9f,0x23,0x0d,0xe4,0x1d,0x40,0xe6,0x6e,0x94,0x5d,0xec,0x77,0xf7,0x5e,0xb4,0xa1,0x03,0xfb,0xa0,0x0e,0xba,0xf8,0x28,0x50,0x3c,0x38,0x47,0xf7
+.byte 0xed,0x2d,0xe5,0x0b,0xa8,0x7a,0xbd,0xbf,0x7e,0x38,0xc0,0x60,0xe7,0x7e,0xb1,0x03,0xef,0x4a,0x8c,0xc7,0x98,0xf1,0x94,0xf6,0xa0,0x50,0xb2,0x0b,0x7c,0x66,0x0a,0x62,0x10,0x24,0xb0,0xa1,0x69,0x02,0x33,0x79,0xbf,0xd0,0xb5,0xcb,0x17,0x20,0x55,0x02,0x70,0x44,0x5b,0xac,0x20,0x35,0xea,0x05,0x2d,0x68,0x51,0xe7,0x5f,0x1b,0xcd,0x4c
+.byte 0x33,0x4d,0x04,0x21,0xfd,0x06,0x67,0x82,0x60,0x98,0x1f,0x79,0xf4,0x28,0xe0,0xa8,0x18,0xeb,0xf5,0x86,0x58,0xe6,0x9f,0xb5,0x29,0x0f,0xe8,0x37,0xeb,0x09,0xf4,0xc6,0x08,0xf2,0xde,0x4d,0x96,0x48,0x62,0x36,0x63,0x10,0x3f,0x63,0xeb,0x44,0x84,0xc8,0xf5,0x74,0x19,0x03,0x50,0xf7,0x7c,0xd2,0x06,0x20,0x6e,0x9b,0xa2,0x37,0xb0,0x68
+.byte 0x78,0x31,0xb6,0x05,0xfa,0xc9,0xcd,0x1d,0x4c,0xbd,0x33,0xb7,0xf3,0x93,0x38,0x7d,0x5f,0x00,0x85,0x5b,0x10,0x7f,0xc4,0x3f,0x3e,0xfe,0x62,0xca,0x51,0x83,0x95,0xcf,0x00,0x65,0x83,0x0e,0xd3,0x78,0xd0,0x51,0xcb,0x70,0x34,0x42,0xc6,0x3a,0x04,0xb9,0x10,0x92,0xe0,0x09,0x06,0xb0,0x66,0x9b,0x37,0x02,0x8d,0x0d,0x3e,0x2f,0xc5,0x17
+.byte 0x6a,0x87,0x7d,0x48,0xa4,0xcc,0x55,0x20,0x7b,0x77,0x07,0xcf,0x44,0x2f,0x88,0x8a,0xcc,0xf2,0x5d,0xa6,0x3e,0x5f,0xda,0xe2,0xde,0xd2,0x7f,0x7f,0xb7,0x90,0x53,0x64,0x6b,0x79,0x42,0x52,0x69,0xc6,0xd6,0xaa,0x9f,0xf9,0x19,0xbe,0x65,0x10,0x99,0x49,0xaf,0x36,0x49,0x1b,0x8a,0x3d,0x7f,0xdb,0xa2,0x1a,0xb5,0xd6,0x34,0x51,0xc8,0xc8
+.byte 0x06,0xca,0xf6,0xb8,0x76,0xa8,0x9d,0x43,0xae,0xf0,0x51,0xe5,0x9a,0x42,0xa2,0x83,0xed,0x20,0x8d,0xe8,0x1c,0xca,0x15,0x4e,0x37,0x3f,0xd8,0x06,0xa0,0xe1,0xf8,0x05,0xfd,0x42,0xf3,0x7a,0x96,0x44,0x36,0x02,0xca,0x11,0x2a,0xc3,0x24,0x58,0xdd,0x85,0x55,0xb2,0xe5,0x1d,0x92,0xc2,0x2d,0x5f,0x7c,0xb5,0x02,0x37,0x7c,0x07,0x35,0x25
+.byte 0x2b,0x33,0x80,0xe2,0xd4,0xfd,0xc7,0xa7,0x19,0x7e,0xba,0x36,0xaf,0xa0,0x4e,0xab,0x8b,0x28,0x4f,0x3b,0x92,0x72,0x42,0x49,0xaa,0x3b,0x08,0x0f,0x1e,0xff,0x2d,0xbf,0x9c,0x48,0x16,0x72,0xbe,0x28,0x05,0x8b,0x3a,0x20,0x6b,0x38,0x43,0xa2,0x35,0xea,0xf7,0x4e,0x50,0xa0,0x43,0x40,0x5c,0xbf,0xe5,0x75,0x13,0x4c,0x36,0x61,0xa1,0x5d
+.byte 0x46,0xd7,0x7a,0x94,0x06,0x2f,0x63,0x32,0x9c,0x6e,0x54,0x18,0x31,0x79,0xf2,0x83,0xcf,0xb4,0x47,0x40,0xe5,0x9a,0xd6,0x99,0x12,0xb3,0x61,0x3d,0x0f,0x5e,0xc8,0x95,0xa3,0x5f,0xc3,0xd5,0x6b,0x6e,0xa0,0xf2,0x2f,0xeb,0x66,0xd0,0x68,0x67,0x10,0x85,0x64,0x27,0xd8,0xb8,0x68,0x00,0x36,0xa5,0xab,0x3e,0xe1,0x43,0x65,0x81,0x2d,0xb9
+.byte 0x0f,0x87,0xfe,0xa1,0x52,0xe9,0x8d,0x82,0x3a,0xd1,0x10,0x52,0x34,0x48,0x7c,0x1c,0xc6,0xd0,0xfe,0xa0,0x1a,0x92,0x07,0x88,0x57,0x9e,0xd7,0x5e,0x9f,0xc8,0xb0,0x93,0x73,0x03,0x28,0x36,0x8c,0x25,0x8c,0x0f,0x4e,0x0f,0x5b,0x26,0x58,0xed,0x5c,0x33,0x75,0x20,0x08,0x11,0x47,0xe1,0x47,0x85,0x47,0xeb,0x54,0xbf,0x58,0xe3,0xd4,0x5b
+.byte 0xf9,0xc6,0x5e,0x42,0x58,0xe6,0xaf,0x79,0x66,0x3c,0xa5,0xa3,0x30,0x33,0xe3,0xbe,0x21,0x4b,0x42,0x98,0x6e,0x44,0xd7,0x68,0xc0,0xff,0xbe,0x7f,0xc5,0xb3,0x4f,0x4a,0x93,0xb0,0x11,0x88,0xcf,0x36,0xb2,0x03,0xbe,0x30,0x52,0x71,0x20,0x0d,0x16,0xc5,0xbb,0xf5,0x92,0x12,0x67,0x6a,0x35,0x66,0x00,0x09,0xd7,0xc6,0x67,0xb0,0x6a,0x04
+.byte 0x19,0x3e,0xbf,0xe2,0x82,0x74,0x78,0x2f,0x77,0x44,0xdc,0xad,0x0f,0x66,0x2a,0x23,0x62,0x2c,0x5a,0x4e,0x3a,0x82,0x2a,0x75,0x16,0x0d,0x74,0x64,0x35,0x53,0xc5,0xf6,0xda,0x36,0x44,0xba,0xe2,0xfa,0x1e,0xc2,0xcf,0x29,0x01,0x36,0x66,0xc3,0xca,0x40,0xf7,0xc4,0xba,0x67,0xac,0xf6,0x17,0xcc,0xa3,0x96,0x2d,0x08,0x5f,0x0a,0xea,0x5e
+.byte 0x97,0xdc,0xc8,0xf9,0x59,0x24,0x6e,0xc5,0x0b,0x02,0xb9,0x1a,0xde,0xac,0x60,0x1d,0xaf,0x9f,0x5a,0x6f,0xe1,0xa6,0xdf,0x75,0xc5,0x9b,0xb7,0xde,0xa4,0xf7,0xf6,0xa4,0xdc,0xb6,0x96,0x08,0xde,0x2a,0x0e,0xb3,0x9d,0xf5,0x75,0x7d,0x7e,0x96,0x91,0x79,0xd4,0xa7,0x30,0x97,0x3a,0xbd,0x7c,0xe0,0xc5,0x87,0x24,0xb0,0x65,0xb7,0x58,0x00
+.byte 0xd9,0x0e,0x97,0xa6,0xa4,0x6a,0xe8,0x0a,0xac,0xac,0x9f,0x3a,0xe3,0x2a,0x9a,0x43,0x41,0x92,0x6e,0x0e,0xc4,0x63,0xc3,0x18,0xb6,0xe1,0xef,0x3d,0xe8,0x0b,0xb0,0x9f,0x2e,0x19,0xa0,0x98,0x98,0x34,0xf8,0x86,0x6d,0xc5,0x8c,0x41,0x26,0xb7,0xf2,0x1d,0xd4,0x72,0x39,0xeb,0x79,0x06,0xaf,0x53,0xaa,0x34,0x80,0x53,0xf8,0x1b,0xf4,0x53
+.byte 0x19,0xfa,0x16,0x8b,0x39,0xea,0x63,0x7f,0x38,0xc4,0x66,0x1d,0xd1,0x90,0xe4,0x2f,0x20,0x43,0x0d,0x5f,0x98,0xcc,0xae,0xef,0x86,0xc8,0xe5,0xf6,0xd2,0xa5,0x49,0xd0,0x3f,0xb5,0x7e,0x42,0xb5,0x6e,0x5e,0x13,0xa5,0xb4,0x71,0x2c,0x5d,0x57,0x24,0x06,0xd2,0x29,0x7c,0x4c,0x90,0xb6,0xea,0xdb,0x62,0xa4,0x2c,0x6c,0x38,0x57,0x97,0xbd
+.byte 0xfd,0x41,0x6e,0x26,0xc1,0xe1,0x6b,0xbb,0xf0,0xe7,0x71,0xf1,0xcf,0x6a,0x7f,0xfa,0xe7,0xfb,0x17,0xe7,0x81,0x19,0x9a,0xf2,0xf6,0x86,0x22,0x4f,0x62,0x59,0xd6,0xc2,0x33,0xbd,0x11,0xe7,0x07,0x3a,0xfe,0x74,0x0d,0xf8,0xd9,0xdb,0xbd,0x05,0xf4,0xf4,0xb1,0x41,0xc9,0xb3,0xf8,0x6a,0x7b,0x98,0x08,0x6c,0xce,0x4c,0x28,0xbf,0x8c,0x77
+.byte 0x68,0xdc,0xee,0xf7,0x11,0xde,0xfc,0x5a,0x58,0x4f,0xf4,0x74,0x9d,0x5b,0x78,0xc3,0x78,0xe5,0x5e,0x26,0x83,0x40,0x17,0x80,0x2a,0x02,0xa4,0xf1,0x0f,0xa0,0xc8,0x22,0xe6,0x09,0x3a,0x52,0x74,0xf0,0xb9,0xb9,0x60,0xaf,0x20,0xa6,0x7e,0x88,0xf4,0xc2,0x38,0xa2,0x21,0x73,0xa9,0x18,0x3f,0x7a,0x04,0x7b,0xc4,0xcd,0x68,0xd9,0x83,0xa4
+.byte 0x8e,0x54,0x0d,0xbc,0xee,0x8b,0x39,0x93,0x66,0xa2,0xd6,0x76,0x4a,0xb2,0x33,0x4f,0x61,0x53,0xde,0x3b,0xff,0x47,0xcb,0x87,0xd9,0x21,0xd0,0x82,0x64,0x54,0xdf,0xf2,0x67,0x62,0x40,0x33,0xc7,0x0d,0xea,0x98,0xaa,0x95,0xfb,0xa9,0x0e,0x90,0xa5,0xd9,0x54,0x81,0x86,0xad,0x9e,0xa4,0x4d,0x36,0xe1,0x77,0xf2,0xe3,0x0a,0x54,0x1a,0x57
+.byte 0x9d,0x62,0x5e,0x0e,0x00,0xc8,0xa6,0x1e,0xf3,0x43,0xe6,0x20,0x0d,0x6a,0x8e,0x90,0x1d,0x4d,0xac,0x2f,0x9f,0x1c,0xb7,0x30,0xec,0x5c,0x99,0x78,0x6f,0x3b,0xe7,0xe0,0x28,0xb9,0x97,0xc5,0x6a,0xf2,0x17,0xc2,0x11,0xac,0x1a,0xe2,0xca,0x57,0x49,0x64,0xc8,0xc7,0x66,0x43,0x8d,0xc8,0xa7,0x0e,0xfc,0xcf,0x05,0x2f,0xae,0x4b,0xfe,0xe4
+.byte 0xbe,0x9c,0xe7,0xe6,0xa8,0x36,0x49,0x0d,0x9c,0x60,0x39,0x0c,0xfd,0x41,0x5b,0xc7,0xa4,0xa5,0x30,0x89,0xe5,0x10,0xf6,0xea,0xf8,0x2c,0xf2,0x3e,0xb1,0x96,0x81,0xa7,0x32,0x8b,0x39,0x14,0x15,0x36,0xfc,0x55,0x3c,0x22,0xcf,0xa3,0x98,0x90,0x68,0x13,0xd8,0x3f,0xf2,0x53,0x19,0x3e,0x9a,0x0c,0x1f,0xc6,0x29,0x43,0x46,0x23,0x58,0xea
+.byte 0x49,0x49,0x15,0x46,0x8e,0x63,0x30,0x1f,0x3e,0x2a,0xa0,0x18,0xfd,0x28,0xc5,0x32,0x77,0x75,0xac,0x6e,0x5d,0x39,0xa9,0x44,0xce,0xfe,0x39,0xa6,0xec,0xde,0x69,0xde,0xfa,0xc8,0x40,0x44,0x34,0x29,0x15,0x19,0xa7,0xbe,0xd6,0x5b,0xfd,0x1f,0x7b,0xb9,0x88,0xf1,0x14,0xcf,0x42,0xc5,0xa7,0xa7,0x0e,0x6b,0x6e,0x86,0xb2,0x7c,0x23,0x8e
+.byte 0xf6,0xae,0xde,0x3c,0xd7,0x26,0x5e,0xde,0x31,0x94,0xc1,0x19,0x65,0x55,0x03,0x73,0xba,0xdc,0x69,0x95,0x9c,0x9d,0x8e,0x59,0xd8,0x51,0x61,0x9f,0x8f,0xf4,0x29,0x43,0x4b,0x6a,0x75,0xb3,0x4b,0x9d,0xcc,0x46,0xd2,0x6e,0x00,0x49,0x4f,0xf0,0xac,0x80,0x55,0xc0,0x0c,0xbf,0x18,0x52,0x75,0x76,0x3b,0xac,0x92,0x83,0x69,0x1b,0xb4,0x15
+.byte 0xe5,0x9e,0xde,0x10,0x30,0x30,0x0e,0x85,0xc7,0xf9,0xae,0xbc,0x9e,0xaf,0x4b,0xee,0x27,0x6b,0xa5,0x6d,0xe4,0x8e,0xed,0xdd,0x95,0xaa,0x85,0xe2,0xf5,0x38,0x15,0x50,0xd3,0xcd,0x2c,0x88,0x6c,0x2b,0x14,0x37,0x74,0x2d,0x6d,0x30,0xec,0x96,0x78,0xae,0x80,0xb3,0xd9,0x84,0xc1,0xd6,0x71,0x90,0xe4,0x8d,0x3a,0x7c,0x9c,0xc4,0xf5,0xa0
+.byte 0x20,0x7e,0xa2,0x0e,0x75,0x7c,0x25,0x7a,0x7e,0x2b,0x2e,0xdb,0x12,0x23,0x73,0x6a,0x8e,0xe3,0xd7,0x47,0x94,0xfb,0xcc,0xe4,0x5a,0x8c,0xfb,0xdc,0x46,0xb3,0x4a,0x42,0x15,0xe0,0xaf,0x6e,0x81,0x72,0x72,0x04,0x52,0x09,0xc5,0x8b,0x6e,0xdd,0x7d,0xff,0x27,0xa8,0xc1,0x94,0xb5,0x33,0x59,0xc2,0x7d,0x59,0x6c,0x3c,0xaa,0xd9,0xd8,0x05
+.byte 0x43,0x7e,0x8a,0x47,0xdd,0x76,0x36,0xe3,0x05,0x49,0xd1,0x8f,0xdf,0x45,0x46,0x63,0xff,0x17,0xb4,0x52,0xc8,0xee,0x4d,0xf5,0x74,0x65,0xc6,0xca,0x19,0xfd,0xb9,0x51,0xc8,0xc9,0x96,0xd4,0x06,0xd4,0x09,0x1e,0xab,0x6d,0x1b,0x26,0x61,0x80,0x5b,0xa8,0xcb,0x62,0x92,0x5a,0x1a,0x8e,0xa4,0xb7,0x25,0x19,0x96,0x63,0xd5,0xc3,0xc9,0xdc
+.byte 0x04,0x83,0x62,0x31,0xe3,0x76,0x00,0x4d,0xf8,0xb3,0x98,0xae,0x4d,0x1a,0x38,0xe3,0xa1,0x27,0x52,0x87,0xbe,0x2c,0x93,0x45,0xd1,0xab,0x56,0xc6,0xf5,0xbc,0xb5,0xe6,0x9c,0xe1,0x1b,0x37,0x42,0x08,0xe7,0x71,0xb5,0xa4,0x67,0xf9,0x48,0xd4,0xc4,0x10,0x25,0x53,0x9c,0x03,0xfc,0x6d,0x5e,0x62,0x5e,0x6d,0x56,0xbc,0x78,0x11,0x0a,0x6d
+.byte 0x1b,0x7a,0xdc,0x62,0xb5,0x58,0x86,0x15,0x71,0xff,0x11,0x33,0x94,0x2b,0xa6,0xc7,0x68,0xd5,0x68,0xda,0x5b,0xd5,0xb7,0x38,0x6c,0x1c,0xf4,0x07,0x39,0xef,0x1f,0x72,0x0a,0xb3,0x12,0x13,0x25,0x86,0xd3,0xf8,0x9f,0xb5,0x40,0x58,0xe7,0x5e,0x9f,0xa0,0xbc,0xd7,0xab,0x4f,0xf3,0x94,0xcf,0x0f,0x5a,0x4c,0x98,0xb4,0x70,0x35,0x62,0xee
+.byte 0x33,0x24,0x72,0x31,0xd4,0x06,0xd9,0xb4,0x1c,0x1e,0x0f,0xa7,0x48,0xc7,0x75,0x45,0x40,0x02,0xd0,0x60,0x32,0x29,0x4d,0x61,0x7a,0xee,0x65,0x35,0x2b,0xe5,0x50,0xac,0x82,0xdb,0xf7,0x9c,0x8f,0x82,0xe4,0xf0,0xbd,0xdb,0x00,0x3d,0x3a,0x3d,0xa2,0xc3,0x2d,0x0e,0x51,0x20,0xdb,0xdb,0x8d,0x15,0x03,0xbd,0xcb,0xcb,0x24,0x81,0xc5,0xdb
+.byte 0x05,0x39,0x48,0xb8,0x3c,0x93,0x35,0x10,0xef,0x19,0xba,0x09,0x9e,0xff,0xf9,0x3f,0x0c,0xdc,0x96,0x98,0x32,0x26,0x76,0xe7,0xfa,0xaa,0xdf,0xdc,0xb9,0x15,0x44,0x42,0x9a,0x8c,0x6c,0x88,0xea,0x43,0x63,0xb5,0x79,0xb6,0x50,0x30,0x78,0xea,0x70,0xba,0x33,0x36,0x8f,0x8c,0xe5,0x78,0xfd,0xbc,0xc0,0xbd,0xde,0x3a,0x3d,0xe6,0xe6,0x57
+.byte 0x0f,0x29,0xf2,0x82,0x05,0xf2,0x5c,0xfd,0x33,0xc1,0xb2,0x2e,0xc2,0xc0,0x42,0xa2,0xc8,0xa5,0xf9,0x70,0x05,0xff,0x7b,0x8d,0xb9,0x68,0xc3,0xf6,0x74,0x00,0xcd,0x9d,0x70,0xfa,0x62,0x34,0xe5,0x05,0xe8,0x5f,0x53,0x9b,0x69,0x01,0x86,0xb9,0x1d,0x68,0x80,0x89,0x51,0x52,0x0d,0xe8,0x28,0xa1,0xdd,0x62,0x2b,0xf3,0x53,0x74,0xaa,0x98
+.byte 0xdb,0x7e,0x74,0x44,0xeb,0x25,0xe7,0xde,0xc4,0x29,0x14,0x11,0x7b,0xc6,0xef,0x14,0xe4,0x04,0xd0,0xf4,0x11,0xca,0xdc,0xdc,0xe6,0x3f,0x9a,0xc9,0xe2,0x0e,0x67,0x30,0x78,0x65,0x94,0x5a,0xa1,0x24,0xd6,0x90,0x2f,0x1c,0x13,0x46,0xf5,0xb5,0xf9,0x74,0x56,0x3e,0xd5,0x1b,0x09,0xb3,0x04,0xbe,0x89,0x00,0xbd,0xe0,0xba,0x13,0x05,0xd1
+.byte 0x98,0xa7,0x93,0x09,0xc5,0x96,0x46,0xb5,0x5a,0x05,0xac,0x1e,0x66,0x03,0xf0,0xaa,0x3d,0xc2,0x54,0xa3,0xc4,0x2b,0x0d,0xa3,0xe4,0x92,0xd6,0xd0,0x44,0xa6,0x37,0x30,0xa5,0xac,0xc2,0xc8,0x58,0x2a,0x2c,0x18,0x68,0x8d,0x9b,0x4f,0x99,0xd0,0x55,0x41,0xf4,0x84,0x3c,0x69,0xda,0x3c,0x6d,0x43,0xb3,0x85,0x15,0x1f,0xdb,0x58,0x0b,0x71
+.byte 0x33,0x24,0xbb,0x21,0x43,0x19,0x16,0xeb,0x83,0xde,0xe5,0xb7,0x68,0x9e,0xb9,0xd9,0xf6,0x2e,0xae,0xdd,0x88,0x2c,0x18,0xd7,0xc3,0x72,0x8b,0xbe,0xaf,0x8d,0xfd,0xcd,0x2f,0x8e,0x3e,0x2b,0xa4,0x20,0x11,0x9d,0x00,0x4f,0xea,0xf0,0xaa,0x2d,0xf3,0x9d,0xfd,0x11,0x7b,0xac,0x2c,0x66,0x74,0x03,0xe5,0xcc,0x70,0x9f,0xfb,0xb7,0x5a,0x16
+.byte 0xc3,0x05,0x61,0x7c,0x8c,0x73,0xcc,0x9c,0x6a,0x2f,0xee,0xae,0x85,0xc9,0x51,0x91,0x13,0xa4,0x09,0x82,0x4d,0x62,0x09,0x24,0x25,0x35,0x1f,0x82,0x88,0xbb,0xdd,0x16,0x5e,0x8d,0x98,0x5f,0x07,0x49,0x32,0x96,0xb7,0xee,0x85,0xb0,0x7b,0xfd,0xf5,0x35,0x4b,0xa9,0xd4,0xee,0xf2,0x37,0xd1,0xfe,0x62,0xf5,0x52,0x13,0xb4,0xb2,0xce,0xc4
+.byte 0xe0,0x09,0x78,0x48,0xd5,0xc6,0x5d,0x36,0x1b,0x90,0x3a,0x6a,0x3c,0x21,0x50,0xf0,0x0a,0xe9,0x46,0x24,0x45,0xc1,0x5e,0x76,0xa3,0xf9,0x70,0xb8,0x62,0x4d,0x0e,0x92,0x87,0x4a,0x6a,0xf9,0x46,0x91,0x64,0xfe,0x7f,0x53,0x24,0x7e,0xc7,0x3e,0xb0,0x37,0x1a,0xc8,0xd6,0x33,0x0b,0x5f,0xa5,0x30,0x03,0x0e,0x85,0x3d,0x7b,0xc1,0xa1,0x18
+.byte 0xb3,0x8c,0xfe,0xca,0x3e,0x71,0xd8,0x92,0x46,0x49,0x60,0x54,0xd9,0x7b,0xf7,0xc3,0x99,0x2f,0xb5,0x79,0xcc,0x32,0x40,0x7d,0x3d,0x0b,0xc6,0x6f,0x04,0xd9,0xf1,0xdd,0x64,0xf5,0xc4,0x60,0x14,0x04,0x5c,0x3a,0xa4,0xda,0xdc,0xad,0x8f,0xc2,0x44,0x37,0x96,0x63,0x00,0xf7,0xb1,0xc0,0x7c,0x8c,0x12,0xb5,0x3a,0xec,0xc0,0x16,0xd8,0x24
+.byte 0xe9,0xc0,0xc4,0xfa,0xb1,0x85,0x5b,0xe3,0x62,0x24,0xa1,0x75,0x92,0x82,0x04,0x59,0x10,0x50,0x4b,0x51,0x51,0x3e,0x39,0xba,0x6d,0xa0,0x65,0x2d,0xfc,0x23,0x1c,0x9d,0x69,0x22,0xe7,0x15,0xfa,0xba,0x76,0xbf,0x53,0x62,0xb0,0x0d,0x0d,0x5d,0x55,0x00,0xbc,0x58,0x01,0xed,0x37,0x53,0xb9,0xa6,0x0d,0x71,0xab,0xec,0x42,0xbf,0x3b,0x52
+.byte 0xfd,0xae,0xe9,0x6d,0x65,0x07,0xf3,0xd9,0x32,0x66,0xc1,0x66,0x1a,0x18,0x73,0x86,0x01,0xaf,0x1d,0xd1,0xd0,0xcf,0xb1,0xea,0x54,0x23,0xdf,0xf2,0x4d,0x7d,0xc7,0xfe,0xfe,0x7d,0x1d,0x2c,0x1b,0xb6,0xa7,0x7a,0x9e,0x90,0x3a,0x3b,0xb0,0x6c,0xb0,0xd2,0xd1,0xd0,0x6a,0x94,0x4c,0x84,0x1c,0x45,0xae,0xda,0x16,0xa9,0x2e,0x63,0x19,0x26
+.byte 0xf6,0x74,0xd3,0x6f,0x9b,0x9c,0x0c,0xb8,0x85,0x9f,0xeb,0x99,0xbc,0xab,0xff,0xc3,0x75,0x86,0xe5,0x3a,0xa0,0xf9,0xfc,0x6b,0x3d,0x5a,0xad,0x46,0x7f,0x17,0x0e,0x94,0xb7,0xa4,0x43,0x61,0x54,0x76,0x29,0x78,0xe4,0x41,0x91,0xbe,0xa5,0x36,0x39,0xdf,0xdc,0xcc,0x8e,0x42,0x40,0x08,0x51,0x26,0xb0,0x53,0x5d,0xb4,0x7a,0x18,0x8e,0xb3
+.byte 0xae,0xf2,0xe0,0xef,0x63,0x51,0x3a,0xbe,0x4c,0x2d,0xce,0xc7,0xe2,0x1b,0xc2,0x40,0xf3,0x82,0x61,0xf0,0x1b,0x05,0xdd,0x1e,0xae,0xed,0x87,0x2c,0xe5,0xad,0xc7,0xec,0xb5,0x63,0xf7,0x3a,0xf9,0xb7,0xd8,0x4e,0xa7,0xef,0xac,0x6d,0x9c,0x27,0xd9,0xcc,0x66,0xf4,0x75,0x40,0x94,0x8b,0x78,0x4f,0x61,0x4f,0x31,0x49,0x5c,0x96,0x72,0x58
+.byte 0xcf,0x55,0xb2,0x66,0x16,0x29,0x27,0x24,0x39,0xc3,0x64,0xb1,0xdf,0x69,0x87,0x85,0x46,0xe3,0xd0,0x82,0x53,0x1a,0xc2,0xf1,0x3a,0xab,0xdf,0xe5,0x29,0x17,0xdd,0xfe,0xbf,0xf9,0x3d,0x7a,0xfb,0xe7,0x74,0x49,0xa9,0xef,0x61,0x93,0x4c,0xfa,0x30,0xea,0x65,0xa7,0x61,0x32,0x88,0x74,0x12,0xc1,0x91,0xf1,0xc2,0x1f,0x38,0x6a,0xfd,0x0d
+.byte 0xc8,0x6f,0x87,0xe6,0x15,0x55,0x26,0x13,0x86,0x13,0xb9,0x01,0x98,0x34,0x1c,0x2d,0x1d,0x30,0xae,0x7d,0x8e,0x07,0x7d,0x4d,0xe9,0xfd,0x58,0x18,0xc3,0xa6,0x8e,0x87,0x98,0x33,0xcc,0x80,0xd7,0x70,0x07,0x6a,0x4a,0x97,0xef,0x56,0xf3,0x9d,0xf9,0xef,0x6f,0xa8,0x71,0x7f,0x61,0x07,0x1d,0x9d,0x51,0x06,0x86,0x4a,0x35,0x9e,0xab,0x2c
+.byte 0x66,0x8d,0x61,0x62,0xbd,0xed,0x6c,0x76,0x7c,0x67,0xe0,0xe1,0x6e,0x90,0x74,0xb1,0xa6,0x26,0x0d,0x01,0x1f,0xe9,0xb4,0x30,0x9a,0x7e,0x37,0xd1,0xea,0x97,0x9a,0x0f,0x9e,0x8d,0x52,0xd4,0x96,0x36,0x5b,0x6f,0x40,0xbb,0x9e,0x44,0xb4,0x6e,0xee,0x15,0x70,0xef,0x66,0x81,0xf5,0xb4,0xe7,0x69,0xb0,0x40,0x44,0xdc,0x70,0x1e,0x4d,0x3c
+.byte 0x9b,0x19,0x2a,0x97,0xbd,0xb2,0xd2,0x9b,0x98,0xac,0x36,0xf1,0x05,0x48,0xdc,0x5d,0x21,0xfb,0x17,0xe3,0x9c,0x3c,0xbf,0xfd,0x1d,0x39,0x1e,0x5b,0x2a,0xa2,0xb3,0x7d,0x4f,0xdf,0x3a,0x41,0x7a,0x31,0x01,0xc2,0xe5,0xd0,0x06,0x50,0x29,0x05,0xce,0xb8,0x28,0xb7,0xdd,0x83,0xc8,0xaa,0x39,0x78,0xc7,0x7d,0x9e,0xcd,0x9a,0x07,0x71,0x7e
+.byte 0x20,0x92,0x82,0xce,0x49,0x90,0xce,0xef,0x53,0xa7,0x48,0x2a,0x69,0x86,0xa1,0x5e,0x35,0xe8,0x7d,0x10,0xb8,0x5e,0xa6,0x9a,0x69,0x6f,0x32,0x75,0xf3,0x4a,0xee,0x9c,0x06,0x5c,0xdd,0x84,0x7e,0x38,0x00,0x67,0x39,0x42,0xed,0x72,0xda,0xe3,0x6b,0x5a,0xf4,0xc9,0x80,0x3e,0x0e,0xda,0x39,0xfa,0x83,0x2c,0x60,0x69,0x87,0x85,0x05,0xfc
+.byte 0xf4,0x2b,0xd4,0x0a,0xad,0x86,0xca,0xd5,0xf0,0x92,0x1f,0x43,0x3c,0x0e,0xac,0x99,0xf3,0x67,0xa3,0x41,0x6d,0xb9,0x29,0x70,0x57,0x62,0x9f,0x45,0x91,0x72,0xe5,0x53,0xcc,0x89,0x80,0x3f,0xbc,0x1c,0x66,0x21,0xdd,0x90,0x2b,0xa4,0xca,0x2f,0xf0,0x0f,0x9f,0xd0,0xe9,0x28,0xe2,0xd9,0x36,0xaf,0xf9,0x01,0x81,0xce,0xb4,0xe7,0x71,0xfd
+.byte 0x92,0xf8,0x56,0x2e,0xc3,0xc8,0x8b,0x54,0xc8,0xc7,0x40,0x79,0x27,0x06,0x18,0x4a,0x7b,0x88,0x3f,0xd6,0x4f,0xd4,0x66,0x1e,0x1f,0x9a,0x14,0x1a,0x0a,0x98,0xc7,0xd6,0x25,0x83,0x37,0x8a,0x5d,0xb2,0x88,0x39,0x68,0x7b,0x1f,0x4e,0x0a,0xed,0x11,0x1a,0x77,0x9b,0xcb,0xb6,0x7d,0x5c,0x36,0xac,0x07,0x07,0x9f,0x05,0xcf,0x90,0x8f,0x3f
+.byte 0x4b,0xc5,0xf9,0x42,0x90,0xb4,0x42,0x26,0xa1,0x2c,0x66,0xc6,0xb8,0x98,0x80,0x8a,0xbb,0x9b,0x41,0xe4,0x44,0x8c,0x5e,0x56,0x33,0xe3,0xba,0xcf,0x31,0x8e,0x28,0xd7,0xc5,0xd1,0x3b,0x68,0x47,0x10,0xae,0xda,0xc3,0xbd,0x20,0xe7,0xac,0xe2,0xe1,0xe0,0x7a,0x4b,0x83,0xb1,0xab,0x72,0xf4,0xc4,0xe7,0x0d,0x02,0xaf,0x5b,0x74,0xac,0xda
+.byte 0x9d,0xce,0x26,0x1f,0x79,0x05,0x67,0x7e,0xc4,0x98,0x3f,0xde,0xa6,0xf3,0xfe,0x59,0x65,0x88,0xfb,0x14,0x3a,0x43,0x91,0x04,0x1a,0x78,0x7e,0x08,0xba,0x55,0x50,0xc7,0x65,0xd3,0x8e,0xda,0x0a,0xee,0x8e,0x11,0xa9,0xf6,0x9e,0xd3,0x23,0x97,0x05,0x0c,0x98,0x2a,0x36,0x25,0xec,0x5e,0x0b,0xf9,0x31,0x80,0x00,0x8a,0x70,0xf1,0xaa,0x7c
+.byte 0x73,0x02,0x98,0x8d,0x42,0x27,0x53,0xf1,0x83,0x37,0xd0,0x2d,0xfa,0xc7,0x4b,0xa5,0xb3,0xc9,0xb8,0xd4,0x56,0x94,0x5a,0x17,0x2e,0x9d,0x1b,0x46,0xaa,0xb6,0xd9,0x2a,0x3a,0x6c,0xaf,0x24,0x59,0xfd,0x08,0xc5,0xca,0x0c,0x79,0x3f,0xe7,0x91,0x8d,0x9d,0x59,0x91,0xd8,0x5f,0xda,0x6d,0x35,0x7b,0x52,0x47,0x35,0xf9,0x81,0x86,0x2c,0xee
+.byte 0x1a,0x14,0xc5,0x1f,0xb6,0x85,0xb5,0x74,0xe9,0xb7,0x4f,0xde,0xcd,0x93,0x2d,0xf3,0x10,0xbe,0x34,0xfa,0xca,0x15,0x9f,0x02,0x9d,0x19,0x72,0x7c,0xd6,0xfd,0x81,0x43,0x49,0xb5,0x2b,0x52,0x31,0xd6,0x2c,0x28,0x2e,0x83,0x6d,0xd3,0x0f,0x6e,0x03,0x65,0xf0,0x8a,0xdd,0x0a,0xec,0x58,0x10,0x45,0x5d,0xac,0xda,0xf5,0x32,0x5d,0x18,0x26
+.byte 0xcc,0x2e,0xcf,0xd3,0x41,0x2d,0x1d,0xba,0xdf,0xd8,0x96,0x8f,0x18,0x0f,0xa7,0xec,0x8e,0x6e,0x84,0x2c,0xd6,0x1f,0x4e,0x76,0xfe,0xf3,0x14,0x27,0x4b,0x5b,0x3d,0x7c,0x1c,0x59,0x46,0x97,0x1b,0x59,0x5a,0x2d,0x57,0x80,0x17,0x98,0x7d,0x92,0x5d,0x2f,0x98,0x53,0x10,0x59,0x8e,0x7f,0x55,0x64,0x15,0x62,0x2c,0x16,0x0b,0x8d,0x48,0x54
+.byte 0xaf,0x96,0x17,0xa9,0x8e,0x2c,0xcf,0x41,0x8c,0x8a,0x37,0x55,0xe4,0xf9,0x20,0x3b,0x21,0x5c,0x86,0x8d,0x3f,0xa6,0x5e,0x43,0xf3,0x3b,0xf7,0x7c,0x27,0x88,0x8e,0xa5,0x15,0xca,0x0e,0x9e,0x85,0x30,0x17,0x0d,0xcf,0xf0,0x82,0x87,0xd6,0xe8,0xd2,0xad,0xe9,0x4d,0x3f,0xc9,0x58,0x19,0xf9,0x99,0x4d,0xf9,0x6b,0x1b,0xd3,0xf9,0xdd,0x52
+.byte 0xd1,0x3c,0x64,0x46,0xfd,0x4f,0x2e,0x63,0x39,0xd8,0xe4,0xeb,0xfc,0x07,0xf1,0xa5,0xff,0x84,0xa8,0x92,0xfe,0xbc,0xc5,0x36,0x91,0x2b,0xec,0x2c,0xad,0xf0,0xac,0xc5,0xb0,0xad,0x8a,0x0d,0x6a,0xd9,0x29,0x7a,0xb0,0x87,0x0c,0xaf,0xda,0x75,0x84,0x25,0xbe,0xee,0x0d,0xfd,0x4c,0xf5,0x2d,0x46,0xe9,0x17,0xb9,0x9d,0x3d,0x4b,0x8f,0x3a
+.byte 0xe9,0x49,0xb6,0x32,0x99,0x27,0xe2,0x4d,0xff,0x2f,0x2e,0xd5,0x69,0x52,0x56,0x20,0x0a,0xbf,0x62,0x14,0x34,0xfb,0xbf,0x95,0xe8,0xfe,0xb1,0x9f,0x43,0x30,0x02,0x03,0x9e,0xa8,0xe2,0x68,0x64,0xdd,0x37,0xfc,0xb9,0x0f,0x85,0x8c,0x36,0x45,0xdb,0x7c,0x8b,0x97,0x50,0xc3,0x75,0xa1,0xcf,0xf4,0xc2,0x46,0xd8,0xa1,0x8c,0xab,0x8d,0x3a
+.byte 0xde,0xe7,0x9e,0xd2,0x1e,0x2d,0x8b,0xe4,0x31,0xe3,0x12,0x3f,0x9f,0x0b,0x2c,0x95,0x75,0x8d,0xf1,0x24,0xb9,0xdf,0x1e,0x64,0x35,0x45,0x2a,0xc2,0xf9,0x96,0x5d,0x10,0x64,0x32,0xae,0xe9,0xf8,0x71,0xd4,0x2d,0x6b,0xc6,0xde,0x08,0x1e,0x5d,0x51,0xf1,0xe7,0xfd,0x3c,0x22,0x43,0x59,0x82,0x83,0x13,0x75,0x36,0xef,0x81,0xe4,0xcf,0xa8
+.byte 0xb8,0x30,0x16,0x44,0xae,0x55,0x06,0xdd,0xb9,0x60,0x3f,0x75,0xc6,0xd1,0x73,0xa9,0xea,0xc9,0x64,0x2b,0x8a,0xde,0x44,0x4b,0x3d,0xc3,0x31,0x12,0x84,0x9a,0xe3,0xda,0x24,0x82,0x99,0x00,0x6d,0x8e,0xb8,0x26,0x82,0xa6,0xc2,0x37,0x6c,0x2a,0x1d,0xcf,0x6d,0x18,0xc7,0xee,0x27,0xca,0xe7,0xad,0x95,0xed,0x7d,0xe0,0xe0,0x6f,0x45,0xc3
+.byte 0x8a,0x2f,0x08,0x49,0x7e,0x09,0x9e,0xc1,0xb7,0x1e,0x8f,0x57,0x61,0xf8,0x3e,0xea,0xd7,0x47,0xfb,0xd0,0xda,0xaa,0x04,0xf9,0x06,0xbb,0xa3,0x80,0x68,0x89,0xb0,0x7f,0x18,0xf3,0xd2,0xeb,0xee,0x48,0x30,0x6a,0x24,0xc8,0x71,0x43,0xc3,0x50,0xcc,0x85,0x68,0xf5,0xca,0x44,0x34,0x43,0xaa,0x2e,0x4f,0x02,0x1b,0x23,0x4f,0xe9,0x07,0x02
+.byte 0xa2,0xfa,0x24,0x57,0x70,0x4e,0x1a,0x78,0x03,0xa2,0xdd,0x53,0x50,0x82,0x05,0xb1,0x0f,0xcb,0x9e,0x2e,0x58,0x04,0x62,0xc8,0xac,0x71,0x31,0x56,0x0f,0xc7,0x70,0x32,0x53,0xda,0x51,0xc3,0x15,0x78,0x82,0xb6,0xe8,0x6e,0x32,0xeb,0x39,0xab,0xba,0x67,0xcc,0xbc,0x99,0x58,0x88,0xc4,0x60,0x0d,0x0b,0xc1,0xfa,0x6f,0x40,0x85,0x04,0xdf
+.byte 0x5f,0x17,0x69,0xf1,0xbd,0x44,0x97,0xc8,0x62,0x19,0x49,0x1f,0x23,0xcb,0x3d,0x17,0x04,0xf2,0xbd,0x58,0x15,0xa6,0x37,0x3a,0x3f,0x77,0x98,0x32,0x40,0x8a,0x72,0xf0,0x41,0x0b,0xad,0x88,0xba,0xd3,0xae,0xdc,0x3b,0x9a,0x37,0x89,0xa5,0x09,0xe5,0xbb,0xf2,0xf8,0x5d,0xa5,0xed,0xe8,0x39,0x7b,0xed,0x2b,0x90,0xd6,0x6c,0xd3,0xfa,0x69
+.byte 0xa7,0xca,0x09,0x83,0x15,0x8d,0xd8,0xe3,0x81,0x03,0x4e,0x2d,0xd8,0x96,0x3b,0x4b,0x18,0x91,0xac,0x5f,0x22,0xe6,0x9d,0x4b,0x09,0xaf,0xf0,0xdf,0x16,0xa2,0xf1,0x2c,0xd9,0x35,0x8a,0x6e,0x85,0x7a,0xbc,0xc7,0x10,0xd1,0x5f,0x8a,0x53,0x9c,0x8e,0xbc,0x8c,0x15,0xb3,0x8a,0xb0,0x0b,0x74,0x40,0x2a,0x5f,0x46,0x71,0x1c,0x0b,0xee,0x08
+.byte 0xae,0x17,0x26,0x1e,0xcf,0xbf,0x3d,0xa0,0x5e,0x3a,0xdb,0x39,0x6b,0x4a,0x82,0x53,0x02,0xf4,0xa2,0x15,0x5c,0xb6,0xdb,0x20,0x30,0xa2,0x7d,0xcb,0x9a,0xf7,0x88,0x69,0xb5,0xc8,0xe6,0xcd,0x9e,0xa4,0xaf,0x27,0x0e,0x61,0x41,0xcd,0x8e,0x71,0x83,0x11,0xce,0x5e,0x6c,0xaf,0xa4,0x50,0x81,0xb6,0xf2,0x36,0x05,0xbb,0x36,0x4e,0x4a,0x1b
+.byte 0x09,0x9f,0xca,0x1b,0x12,0xb0,0x01,0xc0,0xbf,0x7e,0x3f,0x81,0x60,0x9f,0xfd,0x56,0x81,0x54,0x99,0x2b,0x7f,0x1e,0xb1,0xbf,0xd4,0xb7,0xe1,0x7c,0x71,0xf9,0x00,0x72,0x5f,0x10,0xab,0x60,0x03,0x9d,0x13,0xf1,0xba,0x48,0x93,0x1c,0x1d,0x11,0x04,0x40,0xf6,0xde,0x3b,0xef,0x6c,0x47,0xb3,0x0d,0xcf,0x53,0xbd,0x45,0x7e,0xd7,0x8c,0x34
+.byte 0xd0,0xcb,0x85,0x4b,0x1e,0xd1,0xc5,0xfd,0x5b,0x1a,0x18,0x8a,0x27,0xe3,0x16,0x3c,0x25,0x12,0xf2,0xf1,0xa1,0x40,0x53,0x68,0x27,0x2c,0x81,0x0e,0x20,0x12,0xe3,0xde,0xe2,0x9f,0x08,0x75,0xc0,0x25,0x79,0xf0,0xc4,0xaa,0x10,0xad,0x41,0x3f,0x0b,0xc7,0xb2,0xe0,0x50,0xde,0xec,0x24,0x09,0xeb,0xb5,0xd3,0xbc,0xd3,0xdf,0x44,0x6d,0xc8
+.byte 0xf1,0x79,0xf8,0x33,0xb7,0x75,0x09,0x18,0x04,0x59,0x0f,0x15,0x5e,0xf9,0xca,0xe0,0xa9,0x2a,0xe1,0x1b,0xf0,0x49,0x5f,0xca,0xa3,0x80,0xd5,0x9b,0x1e,0xc1,0x1f,0x98,0x18,0x0a,0x24,0xc3,0x3f,0xfb,0x43,0xfd,0xa3,0x01,0x59,0x50,0xea,0x21,0xe0,0x92,0xfd,0xe1,0xd5,0xe4,0x38,0x24,0x88,0xf3,0xb0,0xc9,0x79,0xfd,0x4e,0xd3,0x3e,0xbf
+.byte 0xc6,0xb8,0x9e,0x7f,0xab,0x65,0x79,0xd9,0xb9,0x83,0x38,0xe1,0xf7,0xd0,0x37,0x04,0xb3,0x0c,0x48,0x82,0x74,0xe1,0x0c,0x80,0x13,0x59,0xc4,0x72,0xf9,0x2d,0x88,0x06,0x46,0x08,0x7a,0x6b,0xb4,0xfc,0x5f,0x63,0x31,0x2f,0x4f,0xfd,0x4b,0x1f,0x8e,0x21,0x3c,0x67,0x83,0xdd,0xa9,0x65,0x68,0xc6,0xd0,0xb8,0x1d,0xcd,0x60,0xc5,0xb9,0x3b
+.byte 0xea,0xe9,0xc7,0xa5,0x1a,0x98,0x8a,0x87,0xb7,0x73,0x29,0x3a,0x6a,0x3a,0x75,0xbf,0xa4,0x79,0x64,0xcb,0x94,0x68,0x93,0x56,0x55,0x1e,0xd5,0x61,0xda,0x87,0xe1,0x28,0xf0,0xa5,0x64,0x9a,0xd7,0xa0,0x91,0xfd,0x46,0x20,0x6c,0x87,0x1f,0xe8,0x9e,0x7e,0x95,0xc4,0x60,0xdb,0xf4,0xe2,0x3e,0xb2,0x6a,0x4a,0xe7,0x46,0x3f,0xca,0xf3,0x72
+.byte 0xb5,0xe8,0x06,0x3a,0x1b,0xeb,0xcb,0x81,0x46,0x44,0xf6,0x97,0xa0,0x79,0xe4,0xa4,0x8a,0xba,0x5e,0x1b,0x6d,0xf4,0xcf,0x7c,0x12,0x7a,0xec,0xdd,0xf6,0xc8,0xab,0x5f,0x30,0xb3,0xf9,0x8e,0x31,0xfd,0x51,0x95,0x8b,0xa1,0xe9,0xe8,0x2d,0xec,0x86,0x12,0x4a,0xf8,0x8b,0xa5,0xdd,0xb2,0xe4,0xad,0xdd,0xcb,0xf5,0xcd,0x9c,0x9f,0x0a,0x42
+.byte 0x5f,0x83,0x9d,0xa6,0x4f,0xbe,0x11,0x75,0x3c,0xde,0x67,0x6b,0x95,0xcd,0xcf,0xdc,0xfd,0x1f,0x1a,0x14,0x01,0x27,0x68,0xaf,0x9b,0x82,0xd6,0xae,0x29,0x8a,0x1f,0xc8,0xf1,0x1f,0xb8,0xa9,0xa2,0x1d,0x81,0xbb,0x19,0xda,0x06,0xe3,0x34,0x7b,0xce,0x99,0x3c,0x5b,0x0c,0x9b,0x8b,0x35,0xc0,0x6c,0x88,0xef,0xeb,0x9f,0x64,0xe3,0xc3,0xbf
+.byte 0x37,0xd7,0xf6,0xdf,0xad,0x28,0xf4,0xd7,0x19,0xb0,0xf2,0xa7,0xd4,0x71,0xbc,0xd3,0xa3,0x09,0x5c,0x1a,0x45,0x30,0x2d,0x53,0xa5,0x19,0x2f,0xb0,0x5d,0xae,0x04,0x28,0xe6,0x16,0x3e,0x75,0x9f,0xcc,0x76,0xc4,0xc2,0xa0,0xfb,0xff,0xdd,0x4c,0xa3,0x8b,0xad,0x05,0x73,0x26,0xf0,0xef,0x48,0xd5,0x25,0x22,0x90,0x78,0x21,0xfd,0xc6,0x23
+.byte 0x14,0xbc,0xed,0x13,0x29,0x76,0x17,0xa6,0x93,0x09,0x6e,0xa7,0x42,0xdd,0x11,0x9e,0x05,0xa3,0xb7,0x48,0x84,0x85,0xf8,0x4e,0xed,0x3d,0xdb,0xfc,0x68,0xd2,0xec,0xec,0x69,0x2b,0x60,0x38,0xd1,0x99,0x44,0xf9,0x60,0xd3,0x5a,0x9e,0xe4,0x26,0x9d,0x12,0xf8,0x6a,0x53,0xde,0x76,0x78,0xa7,0x68,0xb0,0xb4,0xdc,0x33,0x7b,0x8a,0x73,0xa0
+.byte 0xa5,0x5f,0x8f,0x81,0x0e,0x51,0x06,0x13,0x6b,0x56,0x16,0x91,0x1f,0xf5,0x6b,0x68,0xe6,0x8b,0x69,0xda,0x0a,0x9c,0xb1,0x74,0x8f,0x1c,0xb3,0xbf,0x52,0x59,0xaa,0xb1,0xb6,0x3a,0x81,0xc2,0x04,0x54,0x12,0x46,0xa2,0xd5,0x21,0xdf,0xe0,0x57,0x1f,0xe8,0x36,0x56,0x87,0xbf,0xcb,0x7d,0x06,0x6c,0xd5,0xc9,0x4e,0xca,0x47,0x47,0x11,0x91
+.byte 0x7a,0x14,0x13,0x5d,0x5d,0x46,0xd5,0x3a,0xe4,0xa4,0x4d,0x99,0x3a,0x54,0x99,0x62,0xb4,0x70,0xa0,0xf5,0x8a,0xda,0x05,0x75,0xf1,0xa5,0xa1,0x5d,0x9d,0xc4,0x7f,0x83,0x8a,0x5b,0x09,0x54,0x0e,0x69,0x28,0xef,0x66,0xfb,0xe4,0xc4,0xe4,0xc4,0xda,0xb0,0xda,0xe2,0x19,0x33,0x3c,0x76,0xa0,0x35,0xdc,0x31,0x4e,0x40,0xfe,0xb8,0x20,0x26
+.byte 0x8f,0x6f,0x7d,0x02,0x54,0x86,0x1d,0xca,0xa6,0x10,0xa6,0x89,0x87,0x3a,0x5a,0xd5,0x3d,0x0f,0xb5,0x81,0x7d,0xab,0xb6,0xc6,0x36,0x87,0xce,0xd7,0xe4,0xc3,0x9e,0xc2,0x9c,0xf6,0x75,0xd5,0x9a,0x69,0xd2,0x13,0x89,0x5a,0xe9,0x29,0xc9,0xf5,0x6e,0xcc,0x05,0x87,0x0a,0x61,0x49,0xd7,0xa5,0x76,0xd0,0xaf,0x96,0xe0,0x2f,0x91,0xf4,0x45
+.byte 0x70,0x5a,0xdc,0x9f,0x07,0x7f,0x86,0x02,0xa4,0x83,0x8d,0x4a,0x6d,0xfc,0x1b,0xd8,0x9b,0xc2,0x42,0x4f,0xcb,0xdf,0xcb,0xe0,0x55,0xb4,0x8f,0xf7,0x27,0x73,0xd9,0x7e,0xf8,0x3a,0x5c,0x4f,0x29,0x64,0xd8,0x39,0xfa,0xf2,0xc4,0x6b,0xeb,0x55,0xc3,0x13,0x22,0x15,0xdf,0xc5,0x91,0x6d,0xd7,0xf3,0x11,0x34,0x08,0xce,0xe5,0xbd,0x16,0x14
+.byte 0x60,0x14,0x8a,0xed,0x4d,0x38,0x98,0x15,0x5d,0xee,0x70,0xff,0x05,0xd2,0x74,0x3a,0x5f,0x78,0x1a,0x70,0x61,0x2a,0x42,0x4a,0xf3,0x15,0x6f,0x9e,0x33,0xca,0xb8,0x46,0x22,0x64,0xd6,0x24,0xe8,0x10,0x1a,0x89,0xab,0x74,0xdf,0x56,0x35,0x41,0x57,0xe1,0xd9,0x4b,0x67,0x60,0x89,0x6f,0xbf,0x73,0xac,0x6b,0xf9,0x78,0x3f,0xbc,0xf3,0x2a
+.byte 0xb5,0x8c,0x1f,0xda,0xe7,0xe2,0xac,0x60,0xbf,0x41,0x96,0xbb,0xd5,0x35,0x9c,0x56,0xe7,0xfd,0x95,0xc7,0x4d,0x32,0xa1,0x07,0x34,0xbc,0x99,0xca,0xcc,0x42,0x71,0xfb,0xec,0x5c,0x1e,0xf9,0x8b,0xde,0x43,0x65,0x84,0x16,0x52,0x0a,0x5e,0x92,0x20,0xd8,0x26,0x4b,0x97,0x71,0xde,0xd2,0x1f,0x2e,0xd1,0xb2,0xb6,0x29,0x6a,0x6d,0x41,0x00
+.byte 0x20,0x3d,0x03,0xf8,0x43,0x7b,0x57,0x87,0x4e,0xf1,0x8e,0x6f,0xd3,0xf4,0x6c,0x6c,0x29,0xf6,0x99,0xe3,0xd3,0x1d,0xd3,0x26,0x21,0x3b,0x02,0xa2,0xc1,0x06,0xcf,0x31,0xec,0x7f,0xc6,0x80,0xbc,0xab,0x86,0x01,0xff,0x11,0x8a,0x24,0xfd,0x1b,0x41,0x49,0xd4,0xbe,0x15,0x34,0x82,0xc5,0x02,0x51,0x67,0x5c,0x41,0x8e,0xbf,0x94,0x12,0x15
+.byte 0x64,0xea,0x00,0x0c,0x51,0x40,0x57,0x66,0x1e,0x6d,0x3e,0x41,0x8e,0x84,0xdf,0x71,0xb8,0xd7,0xfa,0x12,0x17,0x22,0x17,0x05,0xdc,0x82,0xfd,0x7c,0x5e,0xfa,0x62,0x23,0xa8,0xbe,0x14,0xdc,0x84,0x42,0xf0,0x90,0xc5,0xb0,0x68,0xbe,0x64,0x74,0xc3,0xa5,0xd1,0x10,0xcf,0xe3,0xd1,0x09,0x98,0x3b,0xb9,0x19,0xf2,0x9b,0x5d,0x90,0x99,0x3d
+.byte 0x30,0x67,0x55,0x34,0x50,0x78,0x3b,0xd2,0x70,0xb1,0xd2,0x91,0x4e,0xfa,0x98,0x7d,0x93,0xad,0x7f,0xb1,0x89,0xb0,0x61,0x4c,0x95,0x3f,0x51,0x95,0xd7,0xc6,0x87,0x7a,0xc5,0x53,0xb6,0x6d,0x61,0xec,0xbe,0x40,0x1f,0xa5,0x7f,0x73,0x4a,0x78,0xd2,0x58,0x1e,0x41,0x8e,0x9a,0x08,0x49,0xce,0x39,0x52,0xf9,0xd1,0xcd,0x41,0xb6,0x39,0x99
+.byte 0xfa,0xfb,0x1c,0x38,0xe1,0xe5,0xe1,0xd6,0x16,0x0f,0xc8,0x12,0x0b,0x88,0xdc,0x00,0xd4,0x7b,0x24,0x69,0x16,0x27,0x37,0xa3,0xd5,0x39,0x27,0x34,0xda,0x23,0x24,0x50,0x13,0xd8,0x02,0x48,0x14,0xd7,0xc9,0x28,0x1b,0xba,0x66,0xa8,0xc8,0x9a,0x7b,0xed,0x92,0x5b,0x78,0x46,0x79,0x5a,0xd1,0xf2,0x75,0xf0,0x98,0xd3,0x9f,0x4c,0x72,0x51
+.byte 0xed,0xe5,0xce,0x83,0xac,0xe1,0xc8,0x2b,0x7f,0x77,0x6a,0x70,0xdd,0x80,0x88,0x62,0x58,0x94,0x15,0x72,0x53,0x34,0x48,0x17,0xb2,0xe8,0x4a,0xab,0x2d,0x4e,0xef,0x93,0xb7,0xba,0xd1,0x1c,0x53,0x69,0xd5,0xac,0xa1,0x61,0x7c,0x44,0xec,0x81,0x72,0xcc,0xe8,0x6f,0x5d,0x67,0x1f,0x65,0x9a,0x34,0xf5,0x95,0x89,0x1c,0x2e,0x54,0x42,0xc0
+.byte 0x85,0x79,0xb0,0xfa,0x44,0x0d,0x28,0xc4,0x20,0x2f,0x2e,0x85,0x73,0xfb,0xf6,0x44,0x0e,0xbc,0xab,0x4f,0x42,0x5c,0xdb,0x1f,0x11,0x6f,0x9a,0x23,0x75,0x70,0x78,0x1a,0xd2,0xb8,0x83,0x72,0xf5,0xf6,0x40,0x48,0x3f,0xc8,0xd5,0xe3,0x2c,0x08,0x5c,0x0c,0x2a,0xb0,0x8e,0x69,0xe6,0xdf,0x4b,0x4a,0x95,0x9c,0x4c,0x5e,0x09,0x24,0xc3,0xd0
+.byte 0x4c,0x20,0x0c,0x9a,0xce,0x95,0x53,0x6a,0x7b,0x54,0x0a,0x7e,0x73,0xa7,0x95,0xe7,0x7c,0x67,0x9d,0x05,0xbc,0x26,0x3a,0xa1,0x43,0x99,0x7a,0xee,0x04,0xcf,0x94,0x02,0x36,0x26,0xb3,0x81,0x74,0x22,0xee,0x1e,0x9e,0xe2,0x82,0xd4,0xe0,0xca,0xf2,0xec,0xd2,0x9e,0xf8,0x3f,0x9f,0xc4,0x5b,0xe8,0xfc,0xbd,0x93,0xaa,0xc3,0x2f,0xce,0xf2
+.byte 0x32,0xa9,0x23,0xf3,0xe1,0x06,0xae,0x7d,0x87,0xe9,0xe7,0xe0,0xc1,0x7c,0x74,0x9c,0xdf,0x86,0x6d,0x5c,0x8a,0x51,0x45,0x9d,0x43,0x49,0x87,0x45,0x75,0xfb,0x40,0x55,0xab,0x9a,0x52,0xf1,0x32,0x5e,0xde,0x8b,0x52,0x50,0x9f,0xb8,0x7a,0xe5,0x1c,0x40,0x4f,0xc7,0xb1,0x29,0x90,0xcc,0x98,0x99,0xa0,0x4e,0x1c,0x43,0x6e,0x91,0x61,0x9c
+.byte 0xf7,0xa7,0xf7,0x43,0x89,0x15,0x8c,0x56,0x22,0x9d,0x66,0xac,0x71,0x19,0xdc,0xb9,0xf8,0xd3,0xaf,0x2e,0xd7,0x7b,0xc3,0xe4,0x25,0x0d,0x2c,0xaf,0x15,0x8c,0xea,0x2b,0xdb,0x8c,0x71,0xff,0x55,0x29,0x11,0x35,0x11,0xef,0xb0,0x97,0xb2,0x95,0xab,0xeb,0x4a,0x40,0x1c,0x92,0xc4,0x13,0x36,0x74,0x53,0x78,0x51,0x6c,0xca,0x37,0xcb,0xda
+.byte 0x5e,0x6b,0x8c,0x69,0xc5,0xd0,0xf9,0xdb,0xbe,0xd9,0x30,0x42,0x16,0xcf,0x40,0x63,0x87,0x10,0x28,0x7d,0xae,0xa9,0x8c,0x14,0x99,0xe1,0x4f,0x11,0x98,0x7e,0xe9,0x14,0x9c,0x2e,0xe2,0xed,0x20,0x15,0x7c,0xb5,0xf4,0xc9,0x16,0x30,0x8d,0x7c,0x61,0x45,0xf4,0x23,0xf5,0xdb,0x81,0x8f,0x6b,0x41,0xaf,0xa9,0xf8,0x51,0xbe,0xc4,0x5d,0x8c
+.byte 0xda,0x5e,0x07,0x62,0x7c,0xc6,0xd1,0xae,0x91,0x5e,0x05,0xa8,0xc6,0xc5,0xfc,0xb7,0x12,0x2e,0x7f,0x85,0xef,0xbd,0x2b,0x56,0x57,0x32,0xad,0x3d,0x97,0x5b,0x26,0xcf,0xd3,0xe7,0x48,0x4e,0x9b,0x15,0x98,0x77,0xb4,0x3e,0xf1,0x3e,0x1c,0x21,0xb0,0x98,0xe2,0x69,0xee,0xd8,0x29,0x10,0x93,0xd5,0xc9,0x71,0x8f,0x28,0xbd,0xe3,0xd9,0x54
+.byte 0xf3,0x72,0xb6,0x85,0xe9,0x2b,0xdc,0x96,0x52,0x53,0x5c,0x61,0x54,0x96,0x4a,0xf5,0x3f,0xee,0x53,0xc3,0x63,0xc9,0x67,0x14,0xdf,0x3a,0xfe,0x46,0x8a,0xa6,0xec,0x06,0x0c,0xea,0xb8,0x82,0x49,0xb5,0xed,0x94,0xf2,0xac,0x76,0xd5,0x87,0x79,0x15,0x4f,0xa1,0x34,0x90,0x8e,0x7b,0x02,0xf7,0x02,0xb0,0x07,0xa5,0x7c,0x6b,0xc2,0x34,0x84
+.byte 0xd4,0xaa,0xbf,0x32,0x81,0xf7,0xed,0x1f,0x61,0xd7,0x6e,0x40,0xa0,0xdc,0x4c,0xb5,0xb7,0x36,0x3a,0x87,0x09,0x82,0xd5,0x5a,0xc8,0x1f,0xe6,0x77,0xa6,0xaa,0xcf,0x3c,0x7b,0x23,0x46,0x58,0x95,0x7f,0x84,0xba,0x4a,0x05,0x0b,0x36,0xdb,0x58,0xf9,0xa4,0x2b,0x24,0xd4,0x8a,0xbc,0xb2,0xb7,0x04,0xac,0x64,0x0e,0x88,0x25,0x9a,0x69,0xe7
+.byte 0x87,0x70,0x0b,0xa6,0x43,0xe9,0xb2,0xbb,0x4e,0x4c,0x10,0x19,0x44,0x4d,0x12,0x4c,0x58,0x2a,0x49,0xe2,0x01,0xd2,0x65,0x23,0xee,0xe9,0xca,0x0b,0xa1,0x28,0x02,0x8d,0xcf,0x37,0x06,0xbc,0x5d,0x35,0xba,0xec,0x97,0x95,0xcc,0xfe,0x7b,0xc9,0x1c,0x0d,0x89,0x4e,0xe1,0x8d,0x9b,0x5e,0x5b,0xb9,0x6c,0x24,0x73,0x9a,0x62,0xd7,0xc5,0xfa
+.byte 0x54,0xeb,0x05,0x22,0xd9,0xe7,0xc4,0x68,0x88,0x20,0x43,0xd9,0x14,0x47,0xd7,0xa5,0xd0,0xce,0x10,0x77,0xe8,0x5c,0x85,0x39,0x99,0x3f,0x72,0x88,0x4f,0x22,0x15,0x87,0xa0,0xa3,0x47,0x10,0x81,0x64,0xff,0x94,0x77,0x5d,0xce,0x6d,0xd8,0x29,0xb1,0x9c,0x8e,0xce,0xa8,0x39,0x4f,0xfc,0x36,0x3c,0x50,0xb2,0xf1,0x08,0x66,0x1a,0xf0,0x22
+.byte 0x65,0x1f,0x4d,0x17,0xd3,0x63,0x10,0x64,0xd1,0xc6,0x5a,0x3e,0x82,0x72,0x0c,0x48,0x5e,0x07,0x9c,0x07,0xa0,0x40,0x60,0xab,0x74,0x9a,0x00,0xdf,0xd7,0x7d,0xd4,0x11,0x4e,0xce,0x5a,0xaf,0x12,0x4f,0xe7,0x12,0x36,0x1a,0x12,0x11,0x16,0xb7,0xad,0x4b,0x28,0x84,0x7b,0xd8,0x30,0x0d,0x85,0xb8,0x76,0xde,0xa3,0x78,0x8c,0xb7,0x7c,0xbc
+.byte 0x97,0x33,0x53,0x95,0xf8,0x14,0x5f,0xf8,0x0d,0xc1,0x6b,0x79,0xa2,0x42,0x49,0xab,0xae,0x8e,0x78,0xf3,0x51,0x01,0xcc,0x20,0x36,0x80,0xbd,0x32,0x0b,0x1b,0xd2,0xcd,0x27,0x52,0x69,0x1b,0x4a,0x37,0xba,0x31,0xe4,0xc2,0x03,0x8d,0x00,0x48,0x4b,0xcd,0x39,0x2e,0xec,0x94,0x2e,0xe0,0x81,0xfd,0x94,0xd9,0x86,0x39,0x23,0x87,0x3c,0x2f
+.byte 0x25,0xe1,0x5b,0x22,0xe0,0x2e,0x37,0x6d,0x9b,0x97,0x9c,0x94,0x37,0x01,0x26,0xb8,0xb1,0x73,0x7c,0xfc,0x0a,0x64,0xe7,0x54,0xf1,0x0f,0x71,0xa1,0xd6,0xc7,0xc8,0xb4,0x86,0x2d,0xfe,0x30,0x8b,0xca,0xb2,0x18,0x21,0xc0,0xc7,0x7d,0x60,0xcf,0x2e,0x25,0xb0,0xa4,0x1a,0x28,0x19,0xa9,0xa9,0x15,0x32,0x5e,0x21,0x89,0x3a,0x99,0x5f,0x50
+.byte 0x86,0x37,0x3b,0x10,0xb8,0xa5,0xad,0x8e,0xbf,0xfc,0x8c,0x85,0xf1,0x76,0x5c,0xe7,0x4d,0xac,0xe7,0x21,0xb3,0x45,0x87,0x3b,0x05,0xc8,0x41,0xf4,0x99,0x83,0x28,0x40,0x6b,0x30,0x37,0x31,0xd2,0xb3,0xdd,0x43,0x3b,0x3f,0xec,0x50,0x58,0x7d,0x20,0xc6,0xb2,0xa9,0x3c,0x22,0x38,0xea,0x16,0x32,0x01,0xc4,0xb0,0x9f,0x7d,0x12,0x91,0x82
+.byte 0x0c,0xd8,0x36,0xfc,0xa4,0xec,0x06,0xb2,0xc2,0xce,0x9b,0xa4,0x53,0x71,0x77,0xdd,0xc3,0xfc,0x34,0x6f,0xd9,0x5c,0xfc,0x36,0xdd,0x63,0x19,0x06,0xfb,0x3c,0xf3,0x3f,0x82,0x28,0x6d,0x00,0xf9,0xfd,0x8d,0x6b,0x79,0x06,0x8a,0xe7,0x6f,0xcc,0x39,0x12,0x80,0x71,0xcb,0x71,0xb3,0xb6,0xa4,0xa8,0xbe,0x61,0x9d,0x1f,0x48,0xa2,0x15,0xa1
+.byte 0xb5,0xf5,0x16,0x70,0xc5,0x39,0xce,0x43,0xa3,0x09,0xe5,0xf4,0x8b,0x77,0x18,0x5e,0xa0,0x77,0xa3,0xa4,0x17,0x2c,0x3e,0x50,0x73,0x2f,0xaa,0x5d,0x58,0x5e,0xdc,0xec,0xaf,0xca,0x6e,0x57,0x80,0xa3,0xd5,0x94,0x30,0x7c,0x11,0x75,0xc4,0xbb,0x9d,0x18,0xc1,0x5a,0x58,0xc7,0x04,0x56,0xb1,0x3a,0x21,0x55,0x02,0xea,0xad,0x58,0x19,0x72
+.byte 0xdc,0x7d,0x0e,0x41,0x62,0x1b,0x5c,0x48,0x97,0x3f,0xed,0xd7,0x4e,0x30,0x1f,0xf5,0xde,0xc5,0x23,0xf2,0xd7,0x22,0xde,0x2f,0x3e,0x80,0x06,0x81,0xf6,0x24,0xb7,0x91,0x09,0x56,0x91,0x00,0x1a,0xea,0xaa,0xa6,0xc2,0x8b,0xc9,0x78,0xd7,0xde,0xf6,0x87,0xb1,0x04,0xcc,0xbb,0xc1,0xc6,0x48,0x43,0xc8,0x03,0xb2,0xdd,0x70,0xc0,0xe3,0xf5
+.byte 0xc0,0xf5,0x13,0xd5,0x11,0x41,0x7f,0x1a,0xdc,0x48,0xf5,0xd6,0x1b,0x0a,0x84,0xd2,0x84,0xcd,0x10,0x4f,0x0a,0xd7,0xcb,0x41,0x61,0x1c,0xcc,0x5c,0xa9,0xbd,0x6e,0x6a,0xf3,0x81,0xd8,0xaa,0x3a,0xff,0x39,0x90,0x8e,0x33,0xe6,0x58,0x13,0x5f,0xec,0x58,0x74,0x35,0xe0,0x06,0x38,0x0f,0xd0,0xbf,0x8d,0xf7,0x26,0x99,0xea,0xdd,0xfb,0xdf
+.byte 0x5b,0xcc,0xf1,0x3d,0x9b,0x84,0x8b,0x5b,0xe8,0xc4,0xc6,0x3e,0x0a,0x55,0xec,0x73,0xf7,0x70,0xb1,0xc8,0xfa,0xf8,0xd6,0x72,0x2c,0x6d,0x8d,0xc1,0xa3,0xb2,0x9a,0xe7,0x80,0x6d,0x09,0xa6,0x76,0x06,0x71,0xf9,0x95,0x9a,0xa9,0x2f,0x4b,0x7c,0xad,0x64,0x01,0x01,0x91,0xe4,0x87,0x1d,0xe1,0x46,0xf5,0x4a,0x96,0xc6,0x58,0xd9,0xe0,0xa9
+.byte 0x2f,0x80,0x1e,0xd6,0xe9,0xa6,0xeb,0xfe,0x5a,0xb6,0xd3,0xe8,0x76,0xd2,0x51,0xc6,0x68,0x34,0xc9,0xed,0x76,0x29,0x7e,0x63,0xb1,0x09,0xdf,0x23,0x47,0x41,0x2f,0x70,0x46,0x4d,0xbb,0x36,0xc8,0x84,0xe9,0x58,0x20,0x6b,0x04,0xb2,0xa4,0x1c,0x4d,0xe0,0xa5,0xa2,0x59,0xc9,0xed,0x63,0x25,0x5f,0x3f,0x24,0x18,0x59,0x29,0xe3,0x79,0xbd
+.byte 0x35,0x50,0xee,0x81,0x59,0xff,0xd4,0x0e,0x62,0xd3,0x52,0x30,0x81,0xa2,0xe6,0x9e,0xc3,0xc9,0x7a,0x10,0x57,0x36,0x27,0xb7,0x3c,0x61,0x38,0x89,0x70,0xa0,0xc5,0xdf,0x78,0x05,0xa5,0x81,0xe2,0x8a,0x93,0xda,0x7c,0xaf,0xbf,0x6d,0x42,0x09,0x1b,0x43,0x9d,0xf9,0x26,0x87,0xc3,0x84,0x6c,0xb7,0x25,0x31,0x50,0x00,0xd8,0x13,0xc0,0xc0
+.byte 0x6c,0x21,0x82,0x6d,0xf9,0x2f,0xef,0x40,0xe8,0xf8,0xae,0x4d,0x9e,0x1d,0x4a,0xda,0xa0,0x0d,0x77,0x36,0x8b,0xed,0xaf,0x6e,0x2a,0x3d,0xa8,0x36,0xe4,0xff,0x37,0xc2,0xa3,0x11,0x5e,0x68,0x58,0xa8,0xa3,0x19,0xf3,0xc1,0x33,0xea,0x39,0x49,0xfe,0x51,0x87,0xb6,0x31,0x6a,0x61,0x47,0xe7,0xb1,0x46,0xde,0x5a,0xf7,0x93,0x06,0xa7,0x72
+.byte 0xa9,0x2e,0x9e,0x2e,0xc9,0x7f,0xe1,0xb2,0x86,0xb4,0xc9,0xff,0x3b,0xf7,0xaf,0xef,0x91,0x47,0xc2,0xfa,0x42,0x0a,0x4e,0xbb,0x10,0x0d,0xea,0xa4,0x11,0x54,0xa9,0x53,0xde,0xc4,0x01,0xde,0xc7,0x2d,0x1f,0x18,0x40,0x79,0xd1,0x44,0x7d,0x51,0x1d,0xf6,0xdc,0x6f,0xad,0xa2,0x5d,0xd9,0xbe,0x5d,0x11,0x57,0xb7,0x68,0x0d,0x96,0xad,0xb3
+.byte 0x32,0xf7,0x99,0xcc,0x0e,0x03,0xa2,0x79,0x9b,0x63,0xce,0xee,0xf9,0x0c,0xfd,0xfa,0x9a,0x82,0xc9,0x43,0xd3,0xd5,0x23,0xfa,0xac,0x75,0xbe,0x61,0x85,0x18,0xb6,0x75,0x72,0x8d,0x17,0xdd,0xde,0x3f,0x6d,0xb4,0xe8,0x47,0x09,0xe1,0xa7,0xe0,0x4c,0xce,0x93,0x7b,0xc3,0xa3,0x3f,0xc0,0x81,0x21,0x6f,0xe8,0xce,0x68,0x61,0xde,0x1a,0x58
+.byte 0x48,0x7f,0xb4,0xae,0xfd,0x7c,0x80,0x63,0x43,0x5a,0xfc,0xf9,0xf9,0x4d,0xb4,0x8c,0x85,0x27,0x12,0x4f,0x7d,0xe8,0x69,0xc3,0x7d,0x57,0x63,0x0d,0x5f,0xd2,0x85,0x4e,0x0c,0x9a,0x0d,0x1c,0x4d,0xdf,0x3f,0x9a,0x16,0x2f,0x34,0x43,0xc3,0xf0,0xf1,0x16,0x16,0xd2,0x9f,0x2e,0x78,0xd8,0x3c,0x63,0xa0,0x7e,0x02,0x8e,0x65,0xd2,0xb0,0x61
+.byte 0xb0,0x1d,0x7a,0x8f,0xf7,0x30,0x45,0x05,0xf7,0x15,0xc3,0x69,0x24,0x98,0xc3,0x74,0x20,0x16,0x09,0x57,0x39,0x16,0x68,0x23,0x33,0x62,0x4c,0xf5,0xd6,0x34,0xe3,0xad,0x7a,0x14,0x64,0x8c,0x2b,0x48,0x96,0xf9,0x85,0x39,0x19,0x73,0x27,0x04,0xa6,0x55,0x66,0x15,0x8c,0xf1,0x47,0xcd,0x53,0xaf,0x31,0x3a,0xd9,0xfa,0xf9,0xac,0xbd,0xb8
+.byte 0x27,0xe0,0xaa,0xa5,0x62,0x85,0x9f,0xbb,0x4e,0xaf,0xa5,0x72,0x42,0x98,0xa6,0x7f,0xa1,0xb6,0xac,0x17,0xc2,0x2c,0xf3,0xd6,0xc0,0x14,0x4b,0xb3,0x86,0x88,0x89,0x81,0x83,0x7d,0x9d,0xf7,0xe3,0xe4,0x27,0xba,0xa8,0x03,0xb4,0xe3,0x97,0x74,0x1c,0x0d,0xab,0xb4,0x6e,0xc6,0x9e,0x58,0xdd,0x15,0x95,0x2f,0xa6,0xd6,0xaa,0x5a,0x96,0x71
+.byte 0x69,0xca,0xe0,0x5f,0xd2,0x3c,0x66,0x1b,0x58,0x25,0xd6,0xec,0xc0,0x46,0x3e,0x56,0xd0,0xe1,0x36,0x44,0x56,0xc0,0xf2,0x15,0x48,0x9e,0x07,0xce,0x5d,0xb9,0xd4,0x4e,0xcc,0x31,0x26,0xaa,0xdb,0x6a,0x87,0x98,0x0e,0x37,0xfc,0xc5,0x91,0x28,0x1b,0xf8,0x70,0xbf,0x30,0x71,0xbe,0xa0,0x81,0x1e,0x30,0x33,0x37,0x37,0xc8,0x07,0x08,0x9b
+.byte 0x8f,0xe4,0x27,0x9f,0x90,0x67,0xb4,0x96,0x08,0xd7,0x30,0x9e,0xa6,0x53,0x39,0xd1,0x9b,0xde,0x02,0x35,0xf3,0xb1,0x19,0x7b,0xd2,0x28,0x5a,0xc3,0x1f,0x69,0x0e,0x48,0xbf,0xa3,0xb4,0x55,0xd1,0x10,0x3d,0x30,0x71,0xc6,0x82,0x2d,0xb8,0x6f,0xe6,0x99,0x6b,0xef,0x9f,0x86,0xed,0x93,0x13,0xb6,0xb0,0x87,0x91,0x77,0x4a,0x00,0xe4,0x5f
+.byte 0x4c,0x7d,0x41,0x3b,0xc9,0xda,0x99,0x6b,0xff,0xec,0xef,0x05,0x3c,0xc6,0x0d,0xec,0x68,0x12,0x44,0x31,0xac,0xc9,0x0b,0x9c,0xf5,0xea,0xed,0xda,0x88,0xec,0x6e,0x6e,0x73,0xda,0x85,0x52,0x69,0xa1,0x13,0x52,0xcf,0xc3,0x4d,0x95,0x88,0xec,0x1f,0x53,0x81,0x6f,0xac,0x53,0x60,0x48,0x20,0x9a,0x4d,0x88,0x2c,0x4b,0xb0,0x69,0x5f,0x07
+.byte 0xf9,0xa7,0x2c,0x9a,0x13,0x91,0x86,0xa2,0x98,0x20,0xa9,0x80,0x1e,0xaa,0x8e,0xbc,0x3c,0x3d,0x51,0x34,0x3d,0x5b,0x80,0xe4,0x39,0xfe,0xc8,0xb1,0x6d,0xfe,0x36,0x9d,0x9b,0xde,0x22,0x39,0x41,0xe9,0xff,0xda,0x67,0x67,0xd4,0xeb,0x60,0x44,0xd5,0xc1,0x74,0xcd,0xa0,0x98,0x06,0x34,0x76,0xf8,0xe5,0x0d,0xc8,0x52,0xca,0x83,0xd2,0xdd
+.byte 0xf2,0x12,0x36,0x7d,0x3e,0x7f,0xbd,0xa6,0xd8,0x1e,0xc0,0x9d,0x67,0x2a,0x33,0x87,0x86,0x79,0x7a,0x70,0x3a,0x63,0x0b,0x74,0x77,0x89,0xce,0x8f,0x5a,0x3b,0xf3,0x2e,0x52,0x4d,0x1d,0xc6,0xc3,0xc8,0x69,0x98,0xdc,0x81,0x45,0x99,0xfd,0xcd,0x6b,0x6d,0x05,0x33,0x40,0xde,0xb3,0xbd,0x4a,0x27,0xc2,0x9e,0x8b,0xf1,0x4c,0xac,0x92,0x82
+.byte 0x55,0x04,0x79,0xe7,0x28,0x74,0x5b,0x70,0xdc,0xc0,0x4f,0x0c,0xcf,0x3a,0x7f,0x08,0xcc,0x2e,0x1d,0xfd,0x8d,0xd9,0x5c,0xe2,0xa7,0x98,0xc1,0xe8,0x4b,0x96,0xbe,0x27,0xd6,0xfd,0x0a,0x59,0x30,0x33,0x85,0x41,0xc5,0x63,0xab,0xe7,0xda,0x26,0xbd,0xce,0xe7,0x9d,0x50,0xd7,0x2d,0x67,0x7a,0xa1,0x05,0x2b,0x74,0x60,0x5e,0x6c,0x04,0x2b
+.byte 0xba,0xe6,0x2d,0x25,0xc9,0x00,0xd0,0xf0,0xa5,0x4f,0x22,0x59,0x34,0xb8,0x43,0x6b,0xb7,0x67,0x25,0x99,0xff,0x75,0x17,0xb1,0x13,0x7e,0x34,0x1d,0x42,0xa3,0x6b,0xb5,0x9d,0xfe,0xa1,0x71,0x0d,0x90,0x81,0x58,0xfc,0xc7,0x85,0xe6,0xbd,0xc2,0xcc,0xc9,0xc9,0x23,0x6e,0xd6,0xbe,0x4a,0x61,0xd4,0xf5,0x9e,0x37,0x6a,0xb1,0x8b,0x91,0x59
+.byte 0xe1,0x3e,0xac,0x87,0x54,0xa6,0xf9,0xf5,0x90,0xd2,0x7c,0xba,0x4b,0x37,0x33,0x1b,0x88,0x5e,0xbd,0x78,0x3f,0xed,0x43,0x40,0x4f,0x16,0x59,0x29,0xbc,0x27,0x98,0x87,0xfe,0x62,0x56,0x93,0x21,0x0a,0xca,0xc1,0x21,0x99,0xb3,0x32,0xbb,0x5a,0x79,0x40,0xab,0xea,0x00,0xf8,0xe9,0x90,0x0d,0x59,0xbd,0x6e,0x7f,0x74,0x01,0x50,0x67,0x3a
+.byte 0x8e,0x24,0x1d,0x6c,0xc8,0xd6,0x93,0xca,0x71,0x95,0xec,0xac,0x78,0xe9,0x1f,0x38,0x0d,0xa2,0xe5,0x32,0x90,0xa2,0xaf,0xef,0x15,0x06,0xd6,0x52,0xa4,0xd2,0x94,0x0f,0xbd,0x86,0x81,0x82,0x12,0x9b,0x3a,0xc4,0x0b,0xdf,0x8a,0x5f,0xc6,0x3b,0xb4,0x13,0x9b,0xeb,0xed,0x2d,0x06,0x46,0xa3,0xbe,0xbb,0xe1,0xe1,0x93,0xa1,0xab,0x46,0xf3
+.byte 0xd0,0xd9,0xce,0xb6,0xfb,0xd0,0xd5,0xb6,0xde,0x0c,0xed,0x90,0x18,0x6c,0x1e,0x46,0xb0,0x36,0xa7,0xf1,0x29,0xbe,0x9a,0xa0,0xcf,0xed,0xd6,0xaf,0xb8,0x89,0x9b,0x83,0xa8,0xa0,0x8d,0x26,0xaf,0x8f,0x48,0x66,0xfc,0x22,0x1a,0xc0,0xcf,0xf8,0x90,0x57,0x7e,0x25,0x5f,0xe4,0x0c,0x68,0xd2,0xaa,0x59,0x09,0x2f,0x6d,0x3f,0x80,0x8d,0xe0
+.byte 0xfa,0x25,0xb0,0xe0,0x85,0xe9,0x13,0x39,0x3d,0x1f,0xed,0xd1,0x94,0x9b,0xb5,0xc2,0x65,0xda,0xec,0x7a,0x1f,0x2f,0xe2,0x0a,0x42,0x09,0xbd,0x79,0x7d,0xcb,0xb8,0x4a,0x02,0x2b,0x72,0xaf,0x33,0x85,0x72,0x1b,0x18,0x0c,0xa3,0xec,0x39,0x0e,0x30,0x21,0x41,0xf8,0x2e,0xc7,0x8e,0x5c,0x4c,0xda,0x22,0x49,0x8c,0xa7,0xfb,0x89,0x76,0x2e
+.byte 0x45,0x90,0x6c,0xeb,0x70,0x78,0x6d,0x6e,0xee,0x12,0x6c,0xb9,0xb9,0x8d,0xe7,0xf3,0x4d,0x86,0xc4,0x58,0x49,0x55,0xa6,0x86,0xaf,0x39,0x03,0x21,0xfa,0xa7,0xdd,0x51,0x80,0x79,0x6d,0x5b,0xa5,0x58,0x0f,0xfd,0x57,0xb3,0x83,0xe6,0x0d,0x25,0xec,0x55,0xdc,0x0a,0x6f,0xbc,0x7d,0xfd,0x94,0x16,0xdd,0x60,0x9f,0x2a,0x4b,0x6c,0x82,0x03
+.byte 0x4b,0x44,0xbb,0x84,0xdc,0xcb,0x97,0x8e,0x58,0xe7,0xc1,0x79,0xa9,0xf3,0x53,0x78,0x1f,0xf1,0x3e,0xdd,0x94,0x24,0x6d,0xb1,0xd2,0x99,0xbc,0xa1,0xbe,0x7d,0xdd,0xff,0xa8,0x5d,0xd2,0xc2,0xba,0xad,0x60,0x6b,0x40,0x5d,0x7b,0x99,0xd2,0xea,0x45,0x66,0x80,0x6c,0x47,0xf2,0xeb,0x94,0xb8,0xe8,0xe8,0xa0,0x46,0x05,0xe1,0x4f,0x40,0x23
+.byte 0x34,0xdf,0x91,0x63,0xae,0xc9,0xe7,0x32,0x20,0x9a,0x95,0x1e,0xcd,0x5a,0x60,0xe1,0x3d,0xe0,0xf1,0x16,0x3d,0x6e,0x8b,0x96,0x23,0xe0,0xaa,0x1d,0x1a,0xde,0xed,0xc6,0x63,0xb5,0x46,0x8b,0x78,0x71,0x9a,0x14,0x88,0x79,0x61,0x68,0x6b,0xcf,0x80,0xd8,0x9c,0xaa,0xfb,0xb1,0xc0,0xf3,0x39,0x07,0x26,0x56,0x80,0xba,0x9d,0xf5,0xe7,0x95
+.byte 0x99,0xac,0x90,0xea,0xe7,0xe1,0xc9,0x0d,0x40,0x94,0x83,0x58,0xd2,0xc3,0x2b,0xce,0x1e,0xae,0x2a,0xa6,0xfa,0xc7,0x89,0x44,0xcb,0xe2,0x9e,0x74,0x33,0xaa,0x70,0xe5,0x28,0x3a,0x51,0x74,0x53,0xe2,0xfb,0x7c,0x47,0x76,0x22,0xdf,0x46,0xa6,0x01,0x17,0xef,0x88,0x43,0x46,0x3f,0x1a,0x26,0x0c,0xad,0xf4,0x31,0x55,0xf2,0xe7,0xc9,0x35
+.byte 0x6f,0x7c,0x0c,0x5c,0xfd,0x43,0xa4,0x6c,0x6c,0x74,0xf0,0xa4,0xec,0x1d,0x83,0x97,0xc1,0x6c,0x9c,0xd7,0x97,0x90,0x7c,0x07,0x88,0xc0,0xb4,0x79,0x2c,0x7a,0x9c,0x93,0xa2,0x15,0x6c,0xd2,0xa9,0x45,0xa5,0xc1,0x16,0xfe,0x72,0xf4,0x01,0x32,0xe4,0x51,0xdd,0xdb,0x50,0xe3,0x61,0x4e,0x29,0x1e,0x27,0x10,0xe9,0x5e,0x30,0x2b,0x30,0x27
+.byte 0x99,0xff,0x92,0x23,0x04,0x8d,0x28,0x68,0x28,0xd3,0x0f,0xec,0xbb,0xf9,0xfb,0x44,0x1c,0xaa,0x8b,0x38,0x95,0x67,0x1e,0xf5,0x42,0xc9,0xec,0x05,0xeb,0x94,0xe5,0x1c,0x8a,0x2a,0xef,0x3b,0x74,0x46,0x89,0x4f,0xd5,0x6f,0xa0,0xe5,0x74,0xae,0x24,0x8d,0x81,0xae,0x9d,0x3c,0x3e,0x3d,0x41,0x54,0x8f,0xd9,0xc2,0x98,0xf4,0x84,0xeb,0x30
+.byte 0x6a,0x06,0x67,0x11,0x2d,0xb0,0x55,0x70,0x26,0xdf,0x19,0x5f,0x81,0xe9,0x39,0x69,0x3a,0xd6,0x09,0xa4,0x40,0x22,0x1f,0x5c,0xbf,0xd5,0xa6,0xea,0x69,0x99,0x0d,0xea,0x70,0xed,0xfe,0x3a,0xba,0x23,0x8b,0xab,0x08,0xfe,0xfb,0xe9,0x1a,0x88,0x80,0x13,0x45,0x9c,0xca,0x2e,0xda,0x4a,0xc8,0x5d,0x15,0x52,0x87,0x36,0x9b,0x87,0x8a,0x76
+.byte 0x5d,0x31,0x24,0x4a,0xcb,0xf5,0xd3,0xd3,0xc1,0xec,0xde,0x1e,0x48,0x99,0xd5,0xcb,0x93,0xf7,0xca,0x2d,0xa4,0x66,0x5e,0xa4,0xcf,0xc6,0x15,0x20,0x10,0xb1,0xe2,0x8e,0xb9,0x44,0xa7,0xc3,0x54,0x14,0x86,0x08,0xb7,0x89,0x52,0xd5,0x72,0xc5,0x62,0x4d,0x82,0x96,0x23,0xcf,0x6e,0x52,0x3a,0x92,0x53,0x48,0xa2,0xa5,0x9d,0xa4,0xcc,0x32
+.byte 0x45,0x5a,0xdf,0xe2,0xbe,0xce,0x28,0xc8,0xb1,0xb7,0x0f,0x6a,0x38,0x28,0x14,0x66,0x55,0x7a,0xab,0x35,0x56,0xd0,0xc7,0xe5,0xa1,0x8a,0x84,0xf7,0xc5,0xa9,0xdb,0x2a,0x45,0xe9,0x34,0x2d,0xf2,0xed,0x2b,0xa9,0x9e,0x49,0x1b,0x23,0x10,0xeb,0x0e,0x01,0x46,0x6f,0x7a,0x50,0x09,0x5f,0xc3,0xb6,0x1e,0x2f,0x1a,0x3e,0x89,0x32,0xaa,0x5a
+.byte 0xaa,0xef,0x23,0x45,0xdc,0xb5,0x7e,0x5f,0x87,0x77,0xde,0x50,0xab,0xbf,0x9e,0x62,0xa8,0xe0,0xf0,0xc8,0x4a,0xf1,0x4e,0xaf,0xe4,0x50,0x8a,0xfe,0xc9,0x68,0xdd,0x19,0x1d,0xc6,0x54,0xe5,0x38,0x0a,0x6f,0x36,0xe4,0x85,0xe8,0xab,0xc4,0x06,0xef,0x07,0x29,0xce,0xea,0x9d,0x2e,0x22,0x97,0x18,0x7e,0x59,0x89,0x92,0x31,0xc5,0x87,0x50
+.byte 0xa8,0x23,0x22,0x58,0x47,0x27,0x1c,0x89,0x5f,0xec,0x94,0x1d,0xb2,0xc8,0x61,0x1e,0x0a,0x80,0xd3,0xe9,0xbf,0x65,0xb9,0x66,0x32,0x56,0xde,0xd2,0x13,0xee,0xea,0xc4,0xc9,0xbf,0x4c,0xb7,0xa4,0x1c,0xc0,0xbf,0xcf,0xa4,0x58,0x1f,0x98,0x1d,0x25,0x4e,0x51,0xd9,0xbe,0x89,0x32,0xdb,0x7a,0xa6,0x39,0xa9,0xbf,0xed,0x65,0x6b,0x92,0xc4
+.byte 0x8d,0xcd,0x63,0x18,0x65,0x44,0x95,0xcf,0x17,0x72,0x8f,0x27,0x79,0x83,0xda,0xe3,0xe7,0xd9,0xca,0x57,0xff,0xa3,0x15,0xbf,0xb6,0xd8,0xc2,0x8c,0xe8,0xdb,0x8c,0xdc,0x54,0x6a,0xc8,0x57,0x6e,0x24,0xc3,0x3c,0x1f,0x33,0xdd,0x68,0xbd,0x7a,0xa3,0xbc,0xa9,0x9a,0xe8,0xfc,0x97,0xa5,0xbe,0x59,0xfb,0x77,0xcd,0x22,0xc6,0x3d,0x95,0x21
+.byte 0xcb,0xf7,0x8d,0xc1,0x77,0xc6,0xe0,0x06,0xb2,0xdb,0xec,0x54,0x19,0xad,0x02,0x25,0xe0,0x0f,0xda,0x4c,0xa5,0xf2,0x47,0x3f,0xc9,0xa0,0x91,0x21,0x39,0xe9,0x74,0x2a,0x9a,0xc1,0x57,0x86,0x3c,0x32,0x27,0x4c,0xc2,0x2d,0x50,0xbd,0x7a,0x04,0x9c,0x45,0x0d,0x7e,0x06,0x1d,0x3e,0xc1,0x6f,0x06,0x7f,0xd4,0x71,0xd3,0x5c,0x66,0x74,0xa7
+.byte 0x33,0x75,0x64,0xa8,0x7d,0xc0,0x23,0xda,0xb0,0x6d,0x12,0xbe,0x83,0x98,0xe7,0x65,0x38,0x4d,0x39,0xc3,0xd7,0x33,0xfb,0x58,0x64,0xfc,0xde,0xd7,0xbf,0x9e,0xdb,0xcc,0x7a,0x35,0xac,0xdf,0x13,0x08,0xbc,0x0a,0x55,0x82,0x5f,0xc3,0x74,0xc5,0xb2,0xdb,0x89,0xdc,0x9c,0x60,0xfa,0x02,0x1c,0xba,0x5b,0x7e,0x0f,0xb1,0x0f,0xad,0x43,0xe1
+.byte 0xe1,0xbe,0x1e,0x06,0x05,0x0f,0x39,0x80,0x3d,0x7d,0xbe,0x8f,0x38,0x25,0x46,0x5e,0xea,0x47,0x36,0x65,0x4c,0x3c,0x6c,0xd6,0xaa,0x46,0xaa,0xb0,0x95,0x1d,0xff,0x67,0x6c,0x70,0x9d,0xec,0x3d,0x3d,0x4c,0x2f,0xd9,0x2b,0xb0,0xbd,0x8c,0x6a,0xca,0xac,0x0c,0x53,0xa1,0xda,0xd8,0xc1,0x3c,0xaa,0xcc,0x50,0x85,0x41,0xa1,0xa7,0xe9,0x7f
+.byte 0xf7,0xa8,0x28,0xb1,0x5f,0xd6,0x77,0xc9,0xb5,0xae,0x33,0xa7,0x2d,0x16,0xe0,0x13,0xe8,0xd4,0xf9,0x4e,0x62,0x2e,0xc2,0x9a,0xf3,0x83,0xe0,0x45,0x43,0x68,0x40,0x5a,0x56,0xf3,0x31,0xc8,0x5b,0x46,0x0b,0x38,0x1f,0xa5,0xff,0xe6,0xa1,0x81,0xc0,0x91,0xe5,0x5a,0x63,0x8f,0x47,0x9a,0xe7,0x26,0x0d,0x78,0x8d,0x11,0x7d,0xc8,0xd4,0x9f
+.byte 0xc1,0xf7,0x8f,0x93,0xfa,0x2f,0xb5,0xfd,0x6d,0xa4,0x34,0xcf,0x3c,0x6c,0xf6,0x64,0xae,0x5c,0x60,0xa2,0xb4,0xcc,0x18,0x3e,0x08,0x8e,0x36,0x88,0xab,0xc3,0xea,0x53,0x4f,0x1c,0x9e,0xe6,0xef,0x2d,0x9c,0x78,0x4a,0x3a,0x5a,0x60,0x8e,0xf7,0xeb,0x0b,0x36,0xb1,0xbb,0x59,0xe2,0x5e,0x64,0x60,0xe5,0xd6,0x3d,0x2a,0xe1,0x1b,0x03,0x40
+.byte 0x8d,0xde,0x2e,0xd0,0x76,0x0a,0x6b,0x63,0x2a,0x53,0x2d,0x39,0xe0,0x53,0xee,0x7d,0xc4,0x8a,0x39,0xc5,0xda,0xfc,0x31,0x7e,0xa2,0x1b,0x11,0x1d,0x8a,0x8e,0x66,0xf4,0x00,0x17,0xd3,0x78,0x1b,0x94,0xad,0xcf,0xdd,0x56,0xce,0xaf,0xf6,0x34,0xe4,0xb6,0x47,0xe0,0xda,0x1b,0x36,0x4f,0x86,0x26,0xc1,0x65,0xec,0x85,0x8c,0xa9,0xfe,0x96
+.byte 0x75,0x0d,0xe3,0xeb,0x9a,0xa6,0x3f,0xb3,0x10,0x03,0x85,0x24,0xf2,0xb5,0xcd,0x69,0x7d,0xba,0xa2,0x5c,0x8a,0x6d,0x45,0xf4,0xc8,0x4f,0x69,0x8e,0xd4,0x69,0x82,0x42,0xfd,0x00,0x59,0xfd,0x20,0x7a,0x63,0x58,0x56,0x30,0x21,0x73,0xbd,0xd4,0x49,0x84,0x3f,0x51,0x0e,0xfb,0xd3,0xfc,0x93,0x17,0x7f,0x23,0x75,0x25,0xea,0x78,0x79,0xf7
+.byte 0xec,0x22,0xef,0x86,0x91,0x0a,0x90,0x10,0x71,0x3b,0xb8,0x8e,0xb7,0xc9,0xd1,0x26,0x98,0x7d,0x1a,0xab,0x74,0x3e,0x5f,0x10,0xa8,0x47,0xdf,0xc9,0x0a,0x03,0xbb,0xe2,0xbb,0x34,0xbe,0x87,0x1a,0x3e,0x13,0x4b,0xd5,0xdd,0x53,0xb7,0x65,0xb4,0x16,0x38,0xd3,0xfd,0x01,0xde,0xe8,0xba,0x1d,0x33,0x5b,0x7b,0x9b,0x9f,0xfb,0xe7,0x8d,0x82
+.byte 0x21,0x78,0x9e,0xb2,0xf5,0x16,0x37,0x88,0x47,0x9d,0x1a,0x2c,0xfe,0x6a,0xac,0xde,0x3e,0xc4,0xa8,0xed,0x64,0x46,0xdd,0x05,0x07,0x60,0xef,0x99,0x96,0xf0,0x84,0x27,0x38,0x58,0xe5,0xc0,0x53,0x7d,0x07,0xe3,0xa5,0x31,0xb5,0x8a,0xe7,0x50,0x94,0xbb,0x29,0xf9,0x58,0x13,0x91,0x5b,0x54,0x77,0xf6,0x91,0xb8,0x75,0x05,0x3d,0x70,0x3e
+.byte 0x07,0x95,0x7d,0x37,0xbd,0x1d,0x29,0x4d,0x33,0x07,0x13,0x2b,0x54,0x70,0x9c,0x31,0xf1,0xcd,0x2d,0x28,0x09,0x43,0x90,0x24,0x8c,0x82,0xb0,0x08,0x71,0x08,0x97,0x7e,0x1a,0xbc,0x82,0xd8,0x31,0x0a,0x13,0xe9,0x22,0xf0,0x8d,0x2b,0x91,0xe5,0x2e,0x34,0x56,0x97,0x86,0xc9,0xbd,0x45,0x1e,0x32,0x03,0xcb,0xa1,0x29,0x00,0x81,0xd4,0x6e
+.byte 0x5d,0xbc,0x0f,0x01,0x8d,0x5c,0xb9,0x80,0xcc,0xfe,0x0d,0xa3,0xef,0x8e,0x85,0x59,0x37,0xf7,0x64,0xa7,0xe5,0x2a,0xd5,0x44,0xee,0x91,0xcf,0x6c,0xf5,0x0a,0x9b,0xc7,0xdf,0xb6,0x02,0x2d,0xa4,0xf1,0x22,0x2a,0x97,0xfe,0x1d,0xb7,0x4c,0xc7,0x4f,0x2f,0x0b,0x38,0xd2,0xbf,0xfe,0xe3,0x94,0x55,0xae,0x85,0x0c,0x34,0x59,0x67,0x23,0x7b
+.byte 0x4a,0x87,0xd9,0xd2,0xca,0xd5,0x38,0xd2,0x9d,0x05,0x2e,0xd8,0xe3,0x26,0x51,0xa4,0x14,0x66,0xfb,0x38,0x40,0x18,0x3b,0xda,0x43,0x85,0xc9,0xf5,0xf4,0xe7,0x22,0x82,0x45,0xa1,0xdf,0x98,0xa0,0xab,0x5f,0x7a,0x50,0x84,0x75,0x7a,0x70,0xa6,0x3b,0x04,0x20,0xed,0xa8,0x68,0x6d,0x3f,0x43,0xf8,0xb8,0xac,0xc7,0x32,0xa0,0xff,0x47,0xd5
+.byte 0xb3,0x92,0x6a,0x15,0x5a,0xf1,0x7c,0x32,0x30,0xda,0x1e,0x5d,0xab,0xcc,0xd0,0x3a,0xdc,0xcf,0x70,0xd8,0x4d,0xa3,0x50,0xac,0x50,0x42,0x53,0xc6,0xe0,0x3a,0x26,0xdc,0x77,0x30,0x31,0x59,0xa1,0xfc,0x4d,0x48,0x00,0x0d,0xe0,0x66,0xb3,0x9b,0xd3,0x38,0x45,0xbb,0x0c,0x57,0xc5,0x78,0xee,0x8c,0x96,0xea,0xa2,0x16,0xa3,0x12,0xb1,0x06
+.byte 0xd0,0x2a,0x70,0xf7,0xce,0x42,0xae,0x17,0x64,0xbf,0x13,0xa0,0xe9,0x62,0x57,0x1d,0x55,0x78,0xfa,0x72,0x19,0x58,0x15,0xea,0xe5,0xdf,0x72,0x0e,0xc6,0xd3,0xb4,0x3d,0x60,0xee,0x32,0x2a,0xce,0xdc,0xad,0xd0,0x34,0xe6,0xb4,0xcf,0xce,0x5a,0x4a,0x9f,0xaf,0x01,0xb3,0x2a,0xed,0x46,0xa0,0xad,0xaa,0x62,0x8b,0xa4,0xf7,0x4b,0xce,0x32
+.byte 0x35,0x29,0x1e,0x7a,0xda,0x74,0xf8,0xe5,0xda,0x52,0x66,0xaf,0x3d,0x1a,0xff,0x42,0xc0,0xcc,0xb1,0x32,0x36,0x10,0x44,0x34,0x6a,0x16,0xc2,0x5b,0x9a,0x35,0x3f,0xd2,0x29,0xc5,0x76,0x3c,0x24,0xc7,0x2b,0x92,0xae,0xe0,0xe2,0x04,0x6c,0x3b,0x97,0xda,0xfd,0x49,0x43,0x6d,0x35,0xf5,0xc3,0xc1,0x93,0xf8,0x2f,0x25,0xef,0x3e,0xd8,0xf2
+.byte 0xc0,0xb3,0xb5,0x71,0x01,0xe0,0x07,0x11,0xd5,0xf1,0xd3,0x54,0x59,0x93,0x77,0x2e,0x77,0xdc,0x57,0xd7,0x9b,0x0a,0xe2,0xde,0x29,0x04,0x81,0xa1,0x81,0x6f,0x94,0x86,0x39,0xd7,0x29,0x69,0x3f,0xfa,0xe4,0x02,0x01,0x85,0x04,0x21,0xd3,0x17,0xf5,0x68,0x85,0x6e,0x74,0x15,0x56,0xe6,0x5e,0x12,0x1c,0x0d,0x2f,0x7a,0x8d,0xe1,0xc8,0x47
+.byte 0x7b,0xdc,0x35,0x64,0xf1,0x00,0xc0,0x7b,0xd8,0x2c,0x8c,0x60,0x10,0x53,0x11,0x2c,0x5c,0xa2,0xb6,0x05,0xa3,0xcd,0x14,0xb6,0xd0,0x36,0xe9,0x74,0x78,0xc3,0x84,0x6b,0x51,0xa9,0xf9,0xf1,0x05,0xe2,0xd4,0xa3,0x57,0xec,0xb1,0x5e,0xd5,0x75,0x64,0xe3,0xb0,0xf9,0x8f,0x88,0x60,0xdf,0x8e,0x75,0xf9,0x32,0xfc,0x58,0x5b,0x4b,0x17,0xdb
+.byte 0x41,0x04,0x6f,0x17,0x7a,0xf8,0xd0,0x47,0x8e,0xeb,0xd1,0xf9,0xa6,0xa8,0x52,0x7e,0x07,0x6b,0x5b,0x4d,0xb9,0xda,0x91,0x40,0x51,0x25,0x67,0x4b,0xf1,0x95,0x12,0x07,0xa9,0xa5,0x33,0x96,0x92,0x5e,0xb4,0x0e,0xf0,0x85,0x2e,0x70,0xd8,0xaf,0xae,0x9a,0x3d,0x0c,0xb0,0xee,0xe1,0x80,0x5a,0xb9,0x17,0xe6,0x00,0xa8,0x82,0xd0,0x9b,0xf5
+.byte 0xe3,0xa0,0x12,0xc4,0x15,0xd6,0x5e,0x57,0x5c,0xd2,0xb9,0xa7,0x8e,0xfd,0x09,0xc3,0xd2,0x66,0xfd,0x86,0xb4,0xdc,0xa3,0xc2,0xfe,0x16,0x86,0xc4,0x98,0xa3,0x2e,0x4c,0xc9,0x2c,0xd6,0x87,0x83,0x1b,0x6f,0xe2,0x44,0xd6,0x72,0x94,0x1d,0xba,0xaf,0x34,0x1f,0xf2,0x40,0x40,0x33,0x24,0x63,0xc1,0x26,0xef,0xbc,0x0f,0x3b,0x3c,0x65,0x2b
+.byte 0xa7,0xc7,0xdf,0x96,0x67,0xab,0x92,0x0e,0x04,0x8c,0x82,0x9e,0xbe,0x52,0x61,0x40,0xdf,0x77,0x00,0xc5,0x01,0x9a,0xe9,0xde,0xe1,0xe2,0x45,0xb8,0xed,0x94,0xd5,0xf0,0x28,0x29,0xef,0x0d,0x91,0x07,0x9b,0xfe,0x69,0x78,0x26,0xd7,0xf9,0x51,0xf1,0x9c,0xf2,0xbb,0x83,0x2d,0x79,0x1e,0xff,0x97,0x13,0xdc,0x28,0x93,0x26,0x7c,0x54,0x52
+.byte 0xc0,0x92,0xeb,0x4a,0xa2,0xe3,0x01,0xfc,0x07,0xb9,0x26,0x11,0x03,0xe0,0x19,0xa8,0x9c,0xff,0x3a,0x95,0x26,0x3a,0x17,0xf1,0x7d,0x6a,0x6a,0xb2,0xb5,0x5a,0x07,0x43,0x2b,0xb7,0xdd,0x19,0x14,0xe0,0x05,0x91,0xc5,0xee,0x49,0x35,0x7b,0x1a,0x2d,0x34,0xda,0xa2,0x45,0x7e,0x0d,0x64,0x98,0xb6,0x2e,0x47,0xaa,0x6c,0x73,0x66,0x55,0x01
+.byte 0x27,0xb0,0xa9,0x13,0xa6,0xe0,0x74,0x38,0xb3,0x97,0xfe,0xaf,0xdc,0xc0,0x6a,0x4f,0xd8,0xdb,0x07,0x62,0x61,0x05,0xbb,0xa0,0xa8,0xc5,0xb3,0x89,0x13,0xbb,0x09,0x01,0x6f,0x09,0xcb,0x47,0x62,0x46,0xf0,0x4b,0xf0,0xb7,0x7c,0x39,0x8d,0xe5,0x7b,0x64,0x49,0x32,0x93,0x1e,0x94,0x0a,0x98,0xe0,0xca,0xc6,0x67,0x5b,0xdf,0x88,0x0a,0x26
+.byte 0x83,0x77,0xc3,0xd0,0x11,0x66,0x3d,0x25,0x91,0x61,0x80,0xfc,0x9c,0x50,0xfb,0xe8,0x81,0x6f,0xd8,0xfa,0x77,0x78,0x4c,0x2b,0x44,0xd0,0x92,0x52,0xa4,0x50,0x50,0x7e,0xa2,0xb9,0xe7,0x79,0x33,0x95,0xfe,0x29,0x1c,0x1d,0x43,0x9d,0xa7,0x12,0xfe,0xa1,0x45,0xf4,0xd9,0x1c,0x7e,0x5a,0x67,0x99,0x7f,0x22,0x7c,0xa3,0xb1,0x2d,0xb7,0x1d
+.byte 0x6b,0xf6,0xb4,0x94,0xf2,0xd1,0x5c,0x28,0x56,0xe9,0x4f,0x21,0x81,0x96,0x37,0x7c,0x25,0x74,0x0f,0xf9,0xc5,0xf5,0xc6,0xe8,0x8f,0xbb,0xfb,0xe4,0xaf,0x23,0xac,0x4c,0x20,0x35,0x7d,0xb4,0x4a,0xde,0x90,0xec,0x16,0x30,0x95,0x1b,0x79,0xf6,0x77,0xfe,0x80,0x10,0xba,0xd2,0x49,0xda,0xca,0x9e,0x6b,0x63,0x2f,0x24,0x38,0xf9,0xee,0x20
+.byte 0x38,0x5c,0xeb,0xf5,0xbc,0x07,0x7a,0xeb,0xde,0xc4,0x97,0xcf,0x48,0x9b,0x80,0x40,0xfa,0x81,0xf5,0x24,0xa7,0xf3,0xf7,0x16,0xe9,0xba,0xae,0x9f,0xde,0xa1,0x00,0x34,0x74,0x36,0x9f,0x47,0xce,0xcf,0x35,0xdb,0x30,0x7e,0x72,0x81,0xc5,0xe1,0x59,0x07,0x3e,0xc7,0x5b,0x7b,0xd3,0xc6,0xeb,0x4e,0x71,0x9c,0xeb,0x41,0x37,0xd9,0x9e,0x34
+.byte 0x0b,0xc1,0x9c,0xf7,0xfd,0x56,0xb0,0xd6,0xa6,0xe4,0x1d,0xdf,0x43,0xc6,0xf3,0x26,0x0f,0x01,0x07,0x29,0x57,0x9c,0x8f,0xe1,0x31,0xc9,0xa6,0x98,0x0f,0x0e,0x27,0xfd,0xa0,0x59,0xdf,0x92,0x7b,0x0a,0x4c,0x42,0x4b,0x03,0x98,0x2a,0xea,0xcb,0xd8,0x0f,0x6d,0x19,0x0b,0x22,0x69,0x8b,0xaa,0x3b,0xc8,0x41,0x66,0x81,0xc3,0xaa,0x64,0x6d
+.byte 0x44,0xdd,0xb9,0xe2,0xc4,0x47,0x6d,0xdf,0x61,0xe0,0xf3,0x26,0x40,0x23,0x2f,0xf9,0x2a,0xb3,0xfa,0xe2,0xe8,0x36,0xc0,0xd9,0x89,0xb0,0x05,0x47,0x36,0x20,0x3b,0x03,0x0c,0xd1,0x46,0x9b,0xc9,0x65,0xfa,0x14,0xba,0x68,0x49,0xfc,0x2a,0xb9,0x04,0x47,0xbb,0x64,0xe1,0x7f,0x5a,0xd3,0x70,0x19,0x0f,0x14,0x09,0xc0,0xbe,0xc3,0x9b,0x2f
+.byte 0xd1,0x05,0x90,0x56,0x09,0x47,0xb3,0xc5,0x08,0x6f,0x89,0x59,0x8c,0xf3,0xd4,0x1c,0xaf,0x68,0x00,0x32,0x58,0xe2,0x66,0x55,0xe2,0xc3,0x46,0x73,0xfd,0x4b,0x63,0xc5,0xdd,0x48,0xa8,0x14,0xe9,0x07,0x94,0x8f,0x51,0x6e,0x2d,0x7c,0x62,0x97,0x73,0xa5,0x42,0x7d,0xad,0x43,0xcb,0x65,0x56,0xf0,0x23,0x28,0x72,0xdb,0x1f,0xcf,0x34,0x9a
+.byte 0x62,0x06,0x8d,0xc9,0x86,0x40,0x6d,0xee,0x58,0x72,0x02,0xbb,0xce,0x33,0x6a,0xe4,0xcb,0x46,0x25,0xda,0x2f,0x8d,0xc9,0x8e,0xfe,0xcf,0xbb,0xfc,0xb0,0xe8,0xec,0xf2,0xf9,0xff,0x5d,0x70,0x9e,0x2e,0x22,0x0e,0x9a,0x4d,0xb8,0x26,0x7a,0x48,0x3f,0xba,0x5c,0xcd,0x10,0xf4,0x6d,0x89,0x3d,0x5d,0x87,0xd4,0x69,0xb8,0x4a,0x20,0xc6,0xf8
+.byte 0x03,0x6c,0x60,0x1e,0x9c,0xc6,0xe3,0x39,0x9b,0xa1,0x16,0x64,0xed,0xc6,0xd7,0x54,0xfd,0x8d,0xa0,0x2f,0xcf,0xc6,0xde,0x43,0xe4,0xc5,0xb7,0xd6,0x00,0xaf,0x95,0x7a,0xc6,0xde,0x26,0x59,0x39,0xb0,0x12,0x6b,0xe1,0x3c,0xa9,0x09,0xb6,0x15,0xb0,0x62,0xad,0xa9,0x11,0x4f,0x86,0xde,0xc6,0xe8,0x32,0x46,0x78,0xeb,0x60,0x81,0x6b,0x8f
+.byte 0xac,0x80,0xbf,0xa4,0xc4,0xb7,0x5f,0x3b,0x2f,0xf8,0xe4,0x05,0xcf,0xbf,0xa3,0x14,0x6f,0x16,0xbc,0x6c,0x4e,0x31,0xd7,0x79,0x09,0xcf,0x9c,0x58,0xa3,0x0b,0x1a,0x31,0x4b,0xda,0xcb,0x11,0x35,0xb1,0xf5,0xbb,0xfb,0x00,0x46,0x6d,0x70,0x5e,0x4a,0x85,0x19,0xdf,0xb5,0xd0,0x03,0x2e,0x5d,0x01,0x95,0x4e,0x5a,0x59,0x99,0x24,0xac,0x3f
+.byte 0x2d,0x64,0xaf,0xef,0x40,0x16,0x2a,0xcc,0x6a,0x6c,0x0f,0xe3,0x45,0x15,0x74,0x3d,0xea,0xdb,0xa7,0x3f,0xd2,0x50,0x4d,0xc7,0xc6,0x19,0x36,0x84,0xf4,0xbd,0x09,0xff,0xe7,0xf3,0xc0,0xa5,0x34,0x49,0x8a,0xfe,0x83,0xcd,0xe4,0x80,0x7d,0xe3,0xff,0xc9,0x8a,0xb9,0xd6,0x34,0x01,0xd1,0x47,0x16,0x5e,0x7c,0x16,0xf5,0x7c,0xf8,0xb5,0x53
+.byte 0x26,0x84,0x89,0x73,0xf3,0x7f,0x9c,0xb0,0x2f,0x07,0x9e,0xf2,0x12,0xdf,0xba,0xc0,0x15,0xd0,0x3a,0x59,0x9d,0xde,0x67,0x5e,0x1c,0x2b,0x4b,0x84,0xb8,0x89,0xfb,0x62,0x90,0xe9,0x89,0xd9,0xdb,0xb7,0x21,0x4a,0x9f,0xbd,0xc0,0x02,0x01,0xda,0xb3,0x4c,0x9d,0xfb,0x46,0xa1,0xd0,0x3c,0xf5,0x27,0x6f,0x70,0xb5,0xa9,0x74,0xdc,0xa0,0x76
+.byte 0xb7,0x3a,0x53,0x18,0xdd,0x80,0x5e,0x43,0xb5,0x35,0xe4,0x0e,0x26,0x27,0x0a,0xab,0xe8,0x4d,0x2e,0x89,0x20,0xc3,0xff,0xe4,0x7f,0x03,0x2c,0x5f,0x25,0xc7,0x70,0x53,0x27,0x4c,0xc8,0xb9,0xb1,0x81,0x10,0x7a,0xa2,0x65,0xe4,0x0b,0x65,0x8e,0x3d,0x2f,0x96,0xa0,0xa5,0x7b,0x4f,0x09,0xe9,0x9d,0x10,0x06,0xf7,0x18,0xad,0x2d,0x7f,0xb8
+.byte 0x8f,0x08,0xa7,0x2c,0xda,0x82,0xbe,0x5c,0xd6,0x1d,0xb6,0xe2,0x9b,0xa2,0xfc,0x18,0x8c,0x8d,0xf7,0x81,0xf4,0xc6,0x1e,0xcb,0xe5,0x73,0xa6,0x74,0x06,0x20,0xf3,0xa9,0xcb,0x80,0x01,0x55,0x7e,0xc0,0x6a,0x1f,0x5a,0x5b,0xb1,0x56,0x5d,0xd8,0x2a,0xd5,0xf5,0x57,0xe8,0x48,0x6c,0xfb,0x9e,0x93,0xa7,0x0e,0x13,0x2b,0x68,0xc5,0x6b,0x17
+.byte 0x43,0xb0,0x58,0x04,0x65,0x3d,0x46,0x57,0xa7,0x3d,0x99,0xb8,0xa1,0x48,0x17,0x44,0x67,0x2a,0x0d,0x44,0x87,0x9f,0x63,0xd7,0x92,0x56,0x7b,0xab,0xd3,0x6a,0xbd,0x4f,0xc0,0xc3,0xd2,0xee,0xd1,0x3d,0xd1,0x18,0x2e,0x6a,0xf5,0x3b,0x67,0xa0,0x0a,0xf3,0x11,0x49,0xc5,0x4b,0xef,0xcf,0x00,0xfd,0x22,0x8f,0xa0,0x9c,0x99,0x32,0x2f,0x58
+.byte 0xf9,0x97,0x98,0x13,0x4a,0x88,0x50,0xcc,0x58,0x1e,0x27,0x02,0x34,0x7d,0xec,0xf6,0x88,0x3a,0x74,0xb5,0x34,0x6d,0x6f,0x52,0x2d,0x20,0x02,0x70,0x22,0x27,0xdf,0x7a,0xff,0x30,0x36,0x66,0x1a,0xa0,0x51,0xc3,0x75,0x9a,0x06,0xe5,0x3f,0x6c,0x74,0x0d,0x15,0xa2,0xb6,0xe5,0xcd,0x55,0x4d,0xea,0x65,0x8f,0xbb,0xb2,0xd4,0x95,0x73,0xa4
+.byte 0xcd,0xb9,0xc8,0x82,0x60,0x49,0xe9,0x36,0xc9,0xb1,0xe9,0xcb,0x52,0xae,0xa7,0x7a,0x64,0xab,0x75,0x84,0x03,0x4b,0x37,0xf7,0x07,0x75,0xf7,0x1c,0x32,0x19,0xb6,0x8b,0xca,0x7c,0x43,0x15,0xe8,0xec,0x57,0x89,0x1d,0xe2,0xa0,0x80,0xc5,0xb6,0x02,0x29,0xfd,0xda,0xe0,0x14,0x93,0xb4,0xb3,0x44,0x2e,0x17,0x2f,0xed,0x3b,0x38,0x6e,0x8f
+.byte 0xe0,0x3d,0xc6,0x77,0xe9,0xa7,0x76,0xcb,0x98,0x2d,0x08,0x61,0xcf,0x1b,0x25,0x3f,0xfb,0x1d,0x99,0xb1,0x5a,0x3c,0x53,0x96,0x4e,0x09,0x11,0xf6,0x5b,0x09,0x31,0xe1,0xad,0xb0,0xaf,0x7b,0xec,0xf9,0xa8,0x68,0xb7,0x93,0x57,0xf7,0x17,0x77,0x87,0x2b,0xdb,0x00,0x28,0xc6,0x48,0xac,0xff,0xcd,0x26,0x4a,0x8a,0x76,0x9a,0x2a,0x1d,0x37
+.byte 0x4c,0x70,0x4f,0xf6,0x52,0xe3,0x7a,0x78,0x94,0x5b,0x0b,0x50,0xb4,0x48,0x03,0xcd,0x78,0xd0,0x5d,0x89,0x6d,0x76,0xaf,0x9d,0x67,0xc3,0x75,0x6f,0x6a,0x2d,0xe2,0xb7,0x58,0x51,0x10,0x0d,0xef,0xa0,0x1a,0x74,0x28,0x3a,0x97,0x19,0x4f,0x3c,0x8a,0x86,0x3d,0xe4,0x66,0x3d,0x57,0xb4,0x66,0xb3,0x0b,0x4f,0x57,0x57,0x34,0x2e,0xc7,0x0c
+.byte 0x11,0xdf,0x3c,0xb4,0x9f,0xe1,0xd5,0x27,0x41,0x08,0xec,0xca,0x18,0x88,0x48,0x5e,0x88,0x55,0x89,0x71,0xe6,0xa5,0x90,0x7c,0x3b,0xe5,0xf3,0x2a,0xd7,0xf5,0x0b,0x3d,0xbb,0x47,0xad,0xd7,0x78,0x41,0xa8,0xef,0xd4,0x36,0x31,0xd1,0xe4,0x9c,0x87,0x9e,0xb1,0x11,0x0e,0xff,0x8f,0x4d,0x79,0x65,0xc4,0x83,0x75,0x33,0xc9,0x89,0xe2,0xc3
+.byte 0x41,0x68,0x11,0xe7,0xe4,0x58,0xb9,0xf1,0xee,0x06,0x48,0x4d,0xc3,0xc7,0x76,0x60,0x42,0x94,0x8f,0x0d,0xb9,0x53,0x46,0x78,0x06,0x97,0x94,0x36,0xf4,0x3e,0xf3,0xdd,0x5b,0x46,0xe1,0x9d,0x3f,0x9e,0x78,0x00,0x9e,0xe7,0xcb,0x9e,0xc8,0x30,0x87,0x4a,0x52,0x91,0xd5,0xe2,0xa3,0x65,0x98,0xb2,0xc9,0x6c,0xfb,0x4e,0x54,0x5a,0x9f,0x57
+.byte 0x2c,0x4a,0x76,0xe4,0x97,0x88,0xd5,0x6a,0x0e,0x6c,0x7c,0xef,0x78,0x2a,0x7c,0x26,0xa3,0x25,0xf6,0x33,0x82,0x46,0x6d,0x91,0x0d,0xe4,0x83,0xec,0xf1,0x24,0xf8,0x0a,0x34,0xec,0xfc,0x7e,0x47,0xda,0x9a,0x17,0x1b,0x33,0xd0,0xf1,0x70,0xe4,0x0b,0xc7,0x70,0x58,0x1d,0x76,0x20,0x89,0xce,0x4f,0xd1,0xcb,0x3b,0x26,0xd1,0x98,0xd9,0x51
+.byte 0xb1,0xd0,0xaa,0x4a,0xd5,0x10,0xf2,0xae,0xaa,0x14,0xa7,0x72,0x99,0x3d,0xc8,0xbf,0xfb,0xec,0x6a,0x14,0xdd,0x97,0x7b,0x2f,0x16,0x96,0x0f,0x41,0xb8,0x33,0x15,0x1b,0xa2,0x6a,0x7e,0x64,0x0d,0xab,0xe7,0x62,0xf5,0x6c,0x56,0x69,0x09,0x46,0x32,0x24,0x60,0x4e,0x21,0xc7,0x5b,0xee,0x0a,0xe2,0x94,0x7c,0x20,0xe2,0x06,0xa0,0xa2,0x36
+.byte 0xa0,0x7d,0xb5,0x37,0x2a,0xee,0x20,0x25,0x4c,0xba,0x9a,0x06,0x4c,0x07,0x9b,0xea,0x55,0xac,0x2a,0xf7,0xb9,0x5c,0x23,0xac,0x43,0xda,0x9d,0xad,0x76,0xe2,0x5f,0xe0,0x27,0xaf,0x0a,0x5e,0x3d,0x54,0x84,0xfc,0x19,0x75,0x8c,0x62,0x4d,0x37,0x17,0x1a,0x90,0x55,0xb8,0x7e,0xa1,0xad,0x31,0x1a,0xc0,0x91,0x96,0x51,0xa9,0x5f,0xbb,0xb9
+.byte 0x95,0xbf,0xe2,0xd5,0x7e,0x31,0xba,0xc4,0x1e,0x63,0x98,0xd3,0xe2,0x7d,0x87,0xa5,0x46,0xe3,0xae,0xe1,0xe8,0x4e,0x74,0x29,0x0e,0x4b,0x10,0xa8,0x7f,0x3a,0xe5,0x60,0x0f,0x49,0x6a,0xcd,0x3d,0x5a,0x8e,0xf1,0x48,0xd0,0x80,0x7b,0xa3,0x7f,0x06,0x47,0x2b,0x60,0xf2,0x17,0xc3,0xe1,0x26,0x1e,0xb7,0x0f,0x2b,0x7c,0xc7,0xb8,0x3a,0x4f
+.byte 0xad,0x05,0x97,0x88,0x93,0x82,0x8e,0x06,0x77,0x44,0xd1,0x65,0xfd,0x18,0x48,0xd6,0x88,0xcd,0x5c,0xbd,0xe4,0xaa,0xea,0xf1,0xed,0x16,0x5f,0xb3,0x58,0xe2,0x69,0x82,0xbe,0x9e,0xfc,0xcb,0xf6,0x17,0xa9,0x70,0xeb,0x08,0xd7,0x06,0x86,0xf6,0x5a,0x43,0x68,0x7b,0xcf,0xa3,0xfa,0x26,0x5e,0xe5,0x42,0xd3,0x5a,0xc8,0x1c,0x3b,0x8d,0x2d
+.byte 0xf1,0x45,0xb0,0x97,0x90,0x0b,0xe7,0x2d,0xab,0xd7,0xd8,0x8a,0x16,0xf9,0x5f,0xa6,0xcf,0xc5,0x60,0x2c,0x34,0x5a,0x2e,0x2b,0xb9,0xb4,0x9c,0xa7,0x09,0x77,0xd2,0x3f,0x8c,0xf3,0xf6,0xf7,0xe0,0x27,0x79,0xc3,0x4e,0x61,0x7d,0x09,0x50,0x05,0x01,0x35,0x1b,0x33,0x54,0x6f,0x90,0x9a,0x19,0xcd,0x86,0x45,0x23,0xcd,0x6f,0x1b,0x62,0xc5
+.byte 0xce,0x4e,0x8e,0xff,0xe7,0x12,0x32,0x85,0x9a,0xc4,0x11,0x83,0xcf,0x78,0xd7,0x41,0x99,0x64,0x20,0xa6,0x69,0xdd,0xe3,0x53,0x98,0x6b,0xc7,0x98,0x51,0xc5,0xf8,0x3e,0xa3,0x5f,0x0d,0x78,0x2f,0xa7,0x05,0xff,0xe5,0x3a,0x0f,0x7c,0x09,0x58,0x3f,0xaa,0x0d,0x9a,0x9d,0x8d,0xe7,0xbf,0x6b,0x7d,0xfe,0x3a,0x4f,0x5c,0x50,0xb2,0xe7,0xc5
+.byte 0xa5,0x13,0xde,0xc8,0xe8,0x59,0xac,0xb0,0xdd,0xc0,0x81,0xa7,0x0b,0x78,0x32,0x23,0x76,0x85,0x11,0xef,0xe3,0x88,0x6f,0x7f,0xa9,0x09,0x7b,0x0c,0x6f,0x34,0xb2,0x67,0x5e,0xd6,0x11,0xad,0xd7,0x3b,0xf2,0xbb,0x66,0x5b,0xde,0x22,0xfc,0x55,0x26,0xa1,0x89,0x80,0x2e,0xb8,0xf3,0x3c,0xf8,0x1e,0xba,0x99,0x1c,0x24,0x33,0xb4,0xe6,0x17
+.byte 0x2b,0x9c,0x80,0xe5,0x9b,0x58,0x54,0x70,0xcd,0x15,0x81,0xcd,0x51,0x48,0x75,0x24,0x27,0xf5,0x30,0x79,0xc1,0x16,0xff,0x89,0x70,0x12,0x74,0x07,0x9d,0x39,0xf2,0x9c,0xc6,0x89,0x8d,0x94,0x41,0x01,0x04,0xf5,0x16,0x99,0xf3,0xf0,0xd1,0xf5,0x6d,0xd3,0x11,0x19,0x29,0x36,0xfb,0x41,0xf9,0x32,0xb9,0x0f,0x13,0xaf,0xac,0xfb,0x30,0x75
+.byte 0x62,0x8c,0x04,0x5b,0xf1,0xce,0x52,0x9b,0xbe,0x8c,0xf9,0x86,0x5d,0x7d,0xc1,0x8e,0x41,0x76,0x42,0x63,0xd7,0x74,0x8e,0x2c,0x46,0xa1,0x0a,0x51,0xb5,0xec,0xe9,0x91,0x56,0xbc,0xdc,0x32,0xfc,0x10,0xb5,0xca,0x5b,0x4b,0x72,0x99,0x07,0xff,0x01,0x11,0x2c,0xa4,0x60,0xf5,0x6b,0xd4,0xa8,0x96,0x21,0xee,0xbe,0x14,0x8f,0x69,0x99,0xdc
+.byte 0x43,0x7f,0x13,0x3d,0x17,0x1e,0xa3,0x1b,0x21,0x23,0x26,0x7e,0xff,0x80,0x6b,0x66,0x3e,0xb2,0x48,0x1a,0x77,0x3c,0x50,0xe2,0xca,0x4d,0xc6,0xdb,0xfd,0xd1,0x23,0xcc,0xcb,0x01,0x25,0xc0,0x62,0x8d,0xe5,0x9c,0xb7,0x13,0x97,0xf5,0x49,0x01,0x19,0x45,0x45,0x83,0x17,0xff,0x8e,0x94,0x8c,0xb0,0xc0,0xaf,0x46,0x62,0x0e,0x62,0xb7,0x8c
+.byte 0xd5,0xcf,0xb9,0x82,0x6e,0x8a,0xb9,0x22,0xbc,0x30,0xf9,0x65,0xc2,0x7f,0xce,0x6b,0x4d,0xad,0x87,0xcb,0x23,0xab,0x57,0x36,0x6a,0xb7,0x8c,0x63,0x17,0x60,0x13,0xa1,0x1f,0x3d,0xa4,0xd4,0xab,0x5d,0x97,0xc7,0x18,0xaf,0xf8,0xae,0x13,0x64,0x2a,0x19,0x34,0xe2,0x28,0x28,0x4f,0x32,0x2a,0xd8,0x43,0x79,0xaf,0x1e,0x56,0xfc,0x97,0x51
+.byte 0x67,0x8c,0x63,0x80,0x32,0x63,0x71,0x5c,0x78,0x00,0xeb,0xfd,0xa2,0x96,0x58,0x21,0x36,0x13,0x02,0xe5,0xa4,0xb7,0xcd,0x5a,0x30,0xa0,0x5b,0x7b,0x23,0xa4,0xcc,0x54,0x64,0x6f,0x6d,0x9b,0xaf,0xea,0x49,0x69,0x9e,0x2f,0x51,0x5c,0xe7,0xa3,0xa3,0xb8,0xac,0xed,0x47,0x23,0x7a,0x37,0x38,0xe3,0x15,0x98,0x6f,0x50,0x6c,0x8d,0xa7,0xe6
+.byte 0xa8,0x39,0xcc,0x63,0x08,0xeb,0x8f,0x8c,0xfd,0x83,0xaa,0x34,0x75,0x19,0xc0,0xf4,0xd6,0x25,0x18,0x94,0x9d,0xa1,0x7e,0xc8,0x6b,0x19,0x76,0xc0,0x8d,0xaf,0x51,0xe5,0x7c,0x8a,0x98,0x17,0x80,0x90,0xc0,0xb6,0xed,0x5c,0x8f,0x33,0x56,0xba,0xce,0xbe,0x83,0x87,0x5d,0x51,0x2e,0x64,0x84,0xa6,0x9d,0x49,0x27,0x5b,0x92,0xe0,0xe7,0xac
+.byte 0x37,0x3d,0x22,0x5e,0x25,0xe7,0xca,0x2f,0x5d,0x2f,0xa0,0xd5,0xcb,0xe9,0xac,0x84,0x5b,0x19,0x72,0x1c,0x2c,0x0a,0xd1,0xb7,0x73,0x24,0x8a,0x0f,0xe0,0x07,0xd8,0x49,0x4d,0x23,0x1b,0xac,0xb8,0xd1,0x42,0xd4,0xdf,0xf8,0x4d,0x85,0xa2,0x37,0x30,0x46,0x38,0x88,0x55,0x1d,0xea,0x37,0x54,0x8c,0x43,0xb0,0xed,0x01,0x53,0x75,0xe6,0xf7
+.byte 0x9b,0xe6,0x10,0x91,0x6e,0x80,0x11,0xf9,0x96,0x29,0x4f,0x08,0x77,0x2b,0x7e,0xdb,0x5b,0x14,0xbd,0x77,0x37,0xe8,0x36,0x07,0x4a,0xe4,0xd8,0xa2,0x4e,0x38,0xea,0xeb,0xc2,0xd6,0x43,0x59,0x20,0x0c,0x12,0x31,0x6c,0x27,0xc5,0x7b,0xfc,0xfc,0x54,0x94,0x1d,0x5f,0x82,0x73,0xd7,0x1f,0x43,0x3a,0x73,0xc4,0xf3,0xb3,0xbb,0x53,0xfe,0x22
+.byte 0xc0,0xa4,0x7e,0x2b,0x84,0x1b,0xef,0x6d,0x83,0x9d,0xb3,0x8b,0x2a,0x6c,0xea,0x1e,0xfa,0x77,0x01,0x35,0xd2,0x5b,0xc4,0xd3,0xe7,0x1e,0xca,0x73,0x8b,0xb9,0x1f,0xfb,0x67,0xf2,0xdd,0x03,0xe6,0xca,0xfe,0x3b,0x61,0xd7,0xb5,0x96,0xe0,0x85,0xc2,0x23,0xa7,0xea,0x38,0xbf,0x6e,0x29,0x9e,0x8e,0x18,0xd4,0xbf,0x16,0x73,0xf9,0x18,0xef
+.byte 0xc9,0xaf,0x6c,0xe2,0xdc,0xa4,0x58,0x9c,0xf5,0x6d,0x4a,0xc8,0xb4,0x8f,0x16,0x02,0xb7,0x65,0xd3,0x32,0x3b,0x83,0xfe,0xf3,0xc7,0xba,0x68,0xf4,0x95,0xa4,0xf6,0x33,0x57,0x43,0xbe,0xae,0x83,0xa9,0xe4,0x0d,0x0b,0x23,0xaa,0xbc,0x15,0x53,0x18,0x4d,0xb4,0x35,0xe3,0x8e,0x86,0xfe,0xe4,0x98,0x5d,0x63,0x23,0xce,0x44,0xea,0x4d,0x64
+.byte 0x86,0xf8,0x06,0x8f,0xc0,0x73,0xa6,0x6d,0x04,0x53,0x47,0x95,0x0f,0x6d,0x6c,0x01,0x1c,0x3f,0x7b,0x83,0xe4,0xc2,0x40,0xb8,0x97,0x26,0x9e,0x35,0xb0,0x76,0xee,0xe4,0xc7,0xd8,0xaa,0x22,0x83,0x96,0xe1,0x34,0x7b,0x78,0x31,0xee,0xd3,0x9a,0x50,0xd4,0x05,0xfd,0xd6,0x15,0xca,0x83,0x2f,0x49,0xfd,0x00,0x23,0x82,0x39,0xac,0x46,0x7a
+.byte 0xe4,0xb5,0xcc,0xee,0xbb,0xaa,0x98,0x82,0xb5,0x27,0x45,0xd5,0x96,0x6e,0x89,0x01,0x1e,0x30,0xe4,0x1c,0x3a,0x65,0xcc,0x9f,0xda,0x38,0xf0,0x4c,0x68,0xfa,0xe5,0xf2,0xe2,0xce,0x34,0xc2,0x15,0xfd,0x21,0xf6,0xe2,0x33,0xbd,0xef,0xfd,0x49,0x15,0xdc,0x38,0x3b,0x24,0xba,0x3a,0x80,0x35,0x60,0xbe,0x50,0x17,0x38,0x3e,0xe2,0x96,0x84
+.byte 0x01,0x41,0x6c,0xb2,0x0b,0xc6,0xff,0xce,0xb3,0x37,0xa2,0x46,0x27,0x33,0x8e,0x04,0x44,0x8a,0x7c,0x64,0x0e,0xbc,0xed,0x74,0x4f,0x40,0x58,0xf4,0x8c,0xf8,0xd9,0x92,0xa9,0x0b,0x18,0x7c,0x93,0x95,0xca,0xa7,0x3e,0x1d,0xad,0x68,0x80,0xd9,0xdb,0x81,0x78,0x50,0x37,0x49,0xbc,0x64,0xc2,0x52,0x5c,0x70,0x7e,0x0a,0x26,0x7e,0xc6,0xbf
+.byte 0xd2,0x7f,0x05,0x55,0x7a,0x5a,0x3e,0x9e,0xe3,0x8b,0xf5,0x95,0x2b,0xd8,0xb4,0xb8,0xc6,0x5d,0x91,0xb8,0xc7,0x7c,0xe1,0x75,0xf2,0x43,0x6b,0x73,0xb7,0xb1,0x10,0xf2,0xa7,0x1e,0xab,0xaf,0xc9,0xc0,0x3b,0xab,0xbe,0xf7,0x4a,0x43,0x9c,0xca,0x3d,0x00,0x5b,0x02,0xf8,0xa2,0x4f,0x57,0x81,0xb0,0xde,0x1e,0xd1,0x60,0xbe,0x6c,0x0d,0xe6
+.byte 0xcd,0x51,0xb6,0xc7,0x00,0x52,0x37,0x4f,0xfc,0xee,0xe2,0x43,0x5c,0x61,0x76,0xed,0x80,0x72,0x38,0x26,0x94,0xfe,0x28,0x06,0xfb,0x62,0xa6,0x21,0x9b,0x53,0x60,0x1b,0xf0,0x56,0xae,0xba,0x6b,0x52,0x27,0x2a,0xd5,0xed,0x11,0x92,0xa2,0xe2,0xab,0xdd,0x05,0x38,0x38,0xae,0xeb,0x72,0xcb,0x6c,0xa5,0x2a,0x73,0xc5,0xfc,0xb0,0x36,0x83
+.byte 0xd6,0xe6,0xda,0x6b,0x38,0x72,0x5e,0x8d,0xaf,0x11,0x5f,0x5b,0x89,0x58,0x21,0x36,0xf6,0x7d,0x42,0x48,0xdc,0xce,0xaa,0x94,0xf0,0xc3,0xc5,0x2c,0x08,0x2a,0x36,0x35,0x25,0x95,0xc4,0x11,0x09,0xea,0x7a,0xbc,0x2e,0xc6,0x0a,0x5b,0x4f,0x86,0xeb,0xc2,0x38,0x71,0x48,0x8c,0x63,0x79,0x3b,0xe4,0xba,0x14,0x44,0x31,0x28,0x4f,0x9d,0xb4
+.byte 0x26,0xa6,0x3b,0xea,0x3f,0xcb,0x30,0x6c,0x02,0x13,0xdb,0x4c,0x9c,0x76,0xc8,0xd8,0x01,0x52,0x3d,0x2f,0x51,0x70,0x15,0x91,0xec,0x8f,0x80,0xed,0x88,0xb7,0xfa,0x91,0x2c,0x10,0xcd,0x3b,0x92,0x85,0xe7,0xe8,0x11,0xfa,0x50,0x15,0xe2,0xdf,0xf7,0xbe,0xa4,0x2d,0x13,0x75,0xa6,0x00,0x25,0x8d,0xe1,0xb6,0x9b,0xbb,0x64,0xfb,0x5c,0xde
+.byte 0x97,0xcc,0x00,0x51,0xd6,0xac,0x67,0xc3,0x91,0x1e,0x56,0x36,0x2b,0x43,0xed,0x8c,0x67,0x7b,0xf6,0x54,0x6f,0x91,0x44,0x28,0x93,0x60,0xac,0xca,0xb9,0x91,0x7e,0xeb,0x49,0xd8,0xfc,0x12,0x6c,0x40,0x9d,0x0a,0x4d,0xb4,0xab,0xe6,0xad,0x5b,0x8e,0x2d,0x3e,0x53,0xa1,0x88,0xf7,0x41,0x71,0xa7,0xff,0x05,0x46,0x04,0x34,0x1f,0x12,0x89
+.byte 0x92,0xc1,0xf9,0x26,0x16,0x23,0xb6,0x59,0x82,0xdc,0xa7,0xb8,0xa4,0x8a,0x0f,0x1d,0x7d,0x8f,0x44,0xe8,0x4f,0x70,0xbb,0xdb,0x8d,0xe6,0x7e,0x9d,0xd9,0x44,0x10,0x41,0x6c,0x3f,0xb7,0xe8,0x6f,0x39,0x93,0xe1,0xde,0xb8,0x6c,0xba,0x99,0x95,0xb7,0xc8,0xb2,0x2a,0xcd,0x81,0x53,0xc3,0xb5,0x2a,0x8a,0xd6,0x62,0x1e,0x74,0x4d,0xde,0xfa
+.byte 0xff,0x7b,0xed,0x11,0x1e,0x44,0x3e,0x93,0x1c,0xae,0x7c,0x5c,0xed,0x52,0x75,0x5e,0x0a,0xf3,0x95,0xce,0x47,0x86,0x1b,0x7f,0x17,0x09,0x12,0xcc,0x08,0xca,0x16,0x11,0xf1,0xa1,0x39,0x78,0x89,0x5c,0x11,0x25,0xc7,0x39,0x5f,0x97,0x74,0xbc,0xa9,0x2a,0x25,0x5d,0xdd,0x93,0x0d,0x8c,0x74,0x07,0x1e,0xd9,0x9f,0xc1,0x38,0x9c,0xbf,0xe0
+.byte 0x42,0xad,0xb2,0xe7,0xb1,0x84,0x82,0xb4,0x56,0xbe,0x3c,0x42,0xb0,0xce,0x2c,0x94,0xb7,0xe6,0x78,0xc8,0x04,0x06,0x58,0x15,0x3e,0xdc,0xf6,0x9a,0x58,0xc3,0xe3,0x85,0x16,0xc8,0x84,0xba,0x8f,0xbc,0x94,0xa7,0x44,0x04,0x29,0xc4,0xd8,0xec,0x63,0xc4,0x47,0x58,0x22,0x02,0x08,0x20,0x44,0x39,0x52,0xa5,0x33,0xfe,0x1c,0x30,0x27,0x92
+.byte 0xbf,0x42,0x44,0x4c,0x3f,0x3d,0x00,0x7b,0x21,0xef,0xbb,0x25,0x75,0x4c,0xb2,0xe7,0x66,0xc9,0xc1,0xfb,0x1e,0x13,0x04,0xd0,0xcb,0x69,0x51,0x9d,0x9a,0xb0,0xb0,0xec,0xb0,0x12,0x24,0x84,0x57,0x9f,0xef,0xb4,0x19,0x50,0xa6,0xf5,0x03,0xa3,0x93,0x0f,0x77,0xaf,0xe0,0x4c,0xa5,0xd3,0xb0,0xd8,0x5e,0xc3,0x78,0x94,0xd5,0x6e,0x48,0x58
+.byte 0x7a,0x93,0xb1,0x62,0x60,0xea,0xa1,0xba,0x7a,0x86,0x6e,0x87,0xe9,0x97,0xe0,0x7c,0x1e,0xb6,0x63,0x94,0x76,0x5f,0x9c,0x95,0x65,0x00,0xd4,0x14,0x0e,0x4c,0x87,0xe7,0xcd,0x9e,0xb1,0xe2,0x13,0x1b,0xb1,0x8a,0x83,0xaa,0xaa,0x34,0xcd,0xb2,0xf6,0x7f,0x12,0xb0,0x79,0xff,0x1e,0x04,0xc8,0x9a,0xfc,0x41,0x88,0xbb,0x28,0x42,0xeb,0x45
+.byte 0x47,0x8b,0xcb,0x57,0x03,0xcd,0xe5,0x9a,0x84,0xea,0x0a,0xb5,0x0c,0xb8,0x30,0x33,0xd6,0xde,0x66,0xa8,0x57,0xf9,0x76,0x4f,0x0f,0x8f,0x53,0x56,0x57,0x91,0xd4,0x55,0xf5,0x78,0xde,0xa6,0xa2,0x59,0xc8,0xb0,0xf2,0xb9,0xfa,0x6d,0x4a,0x70,0x86,0x3d,0x24,0x1b,0xc6,0xb8,0x06,0xf5,0xea,0x09,0x63,0x9b,0x1e,0x61,0x18,0x85,0xba,0x08
+.byte 0x20,0xaa,0x33,0x66,0xcf,0xa7,0xff,0xf5,0x30,0xfe,0xf8,0x39,0xd3,0x88,0x9a,0x5b,0x3f,0x55,0xa6,0x00,0x4c,0x57,0x0d,0xd1,0xa4,0x0c,0xe7,0x8a,0x95,0xd8,0x64,0xc7,0x93,0x51,0x84,0xa6,0x41,0x2c,0xfc,0xb0,0xfb,0x99,0x9a,0xcd,0x2c,0x62,0x3a,0xca,0x43,0x15,0xf2,0x5a,0x22,0x25,0xa4,0x91,0xa3,0x7c,0x42,0x69,0xc1,0x67,0xe3,0xf5
+.byte 0xd4,0x92,0x54,0xbd,0xb3,0x57,0xe5,0x19,0xca,0x1b,0x9c,0x19,0x79,0x9d,0xbf,0x89,0xfc,0xaa,0x72,0xcd,0xcb,0xc5,0xbc,0xdd,0x0c,0x7c,0x31,0x42,0xb0,0xc2,0x76,0xe5,0x8b,0x9b,0x7c,0x92,0x13,0x20,0x5c,0xdc,0x94,0xfc,0xa1,0x90,0x34,0x27,0x88,0x9f,0xe5,0x97,0x5f,0xc3,0xa3,0x83,0xca,0x8b,0xf8,0xac,0x36,0x33,0x47,0xc6,0x20,0x2f
+.byte 0x04,0x2d,0x13,0xc1,0x3c,0x07,0x6e,0xf0,0xe2,0x3d,0x32,0x5c,0x50,0x41,0xf2,0x92,0x3f,0x25,0x2c,0x80,0x34,0xa5,0x90,0x2b,0x97,0x6e,0xd1,0xa2,0xa6,0xf4,0x4a,0xe0,0x20,0xd9,0xb9,0x2b,0x66,0xe5,0x06,0x73,0x97,0xfe,0x80,0x70,0x28,0xf9,0xb6,0xae,0x93,0x27,0x7a,0x65,0xff,0x23,0xc1,0x78,0x18,0x92,0xc9,0x0b,0x05,0x82,0x93,0xbc
+.byte 0x73,0x3f,0x98,0xe9,0xa0,0x6d,0x20,0x8d,0x13,0xb1,0xf0,0x7e,0xe4,0x07,0x21,0x7d,0x6d,0xea,0x03,0x59,0xf8,0x29,0xc0,0xc8,0x7d,0xce,0xd1,0xf8,0x67,0x82,0x7f,0x84,0xe8,0x77,0xa9,0x9c,0xa2,0x34,0xdf,0xa9,0xac,0xec,0x6d,0x54,0xe5,0x0f,0xcb,0xdb,0x86,0xbc,0x01,0x44,0x91,0x3b,0xc8,0x85,0x4e,0x1d,0xe4,0x74,0x19,0xc6,0x39,0x2e
+.byte 0xdf,0xf2,0x8f,0x3a,0x7f,0xe3,0x1e,0x55,0x45,0xcb,0x7e,0xde,0xcd,0xa6,0x1c,0xef,0x20,0xf7,0x07,0x31,0x94,0x9a,0x3d,0x04,0xd7,0x5e,0x65,0x20,0x6a,0x4d,0x31,0x1e,0x6f,0x89,0x40,0x45,0x1f,0x37,0xc1,0x7e,0x07,0xd5,0xa6,0x38,0x4a,0xf1,0x39,0xae,0x72,0x26,0x60,0xb0,0xb5,0xc7,0xd3,0x9a,0xaf,0x57,0x12,0xe9,0x34,0x28,0x8b,0xaf
+.byte 0xd8,0x62,0x24,0x58,0xe2,0xcd,0xa2,0x9e,0x74,0x23,0x2d,0x52,0xc7,0x09,0xe5,0xb5,0xf5,0xc1,0xd3,0xa3,0x19,0xe5,0x1d,0x8d,0x0c,0xdf,0x13,0x8d,0xa4,0xa7,0xc1,0x41,0xea,0x9e,0x6d,0x61,0xd4,0xa4,0x74,0xe5,0xf8,0x5f,0x9e,0xfd,0x6d,0xf6,0x6e,0x87,0x0f,0xb5,0xa3,0x82,0xac,0x64,0xb4,0xda,0x07,0x49,0x51,0xc2,0xfd,0xcb,0x55,0xa3
+.byte 0x59,0x34,0xdf,0xa1,0xd6,0x90,0x62,0x43,0x1a,0xf9,0xae,0x85,0x5c,0x11,0x40,0xb2,0xbe,0xa5,0x03,0x04,0x4f,0xec,0x2c,0x58,0x2d,0xe9,0xda,0xcf,0xaa,0x2f,0xcf,0x60,0xc3,0x2c,0x6c,0x81,0x4d,0xf2,0x71,0x41,0xe4,0xae,0x4c,0xfa,0x8e,0x05,0x10,0xff,0x40,0xfa,0xea,0x96,0x78,0x6e,0xfc,0x35,0x35,0xec,0x84,0xf6,0x1d,0x24,0x60,0xcd
+.byte 0x96,0x21,0x21,0xa7,0x32,0x90,0x3d,0x51,0x72,0x13,0xa4,0x9b,0x7e,0x94,0x3a,0x9d,0x97,0xf6,0x68,0xd8,0x08,0x42,0x54,0x7a,0xbb,0x9a,0x95,0x83,0xac,0xb8,0xb4,0x68,0xe3,0x31,0xdb,0xe2,0x32,0x8b,0x7d,0x57,0x62,0x1d,0x61,0x81,0xa1,0x36,0x7a,0x25,0x00,0x72,0x24,0x4c,0xa7,0x96,0x3b,0xa5,0x82,0xba,0x8e,0x89,0x1e,0x1b,0x8e,0xf4
+.byte 0xab,0x91,0x85,0x7a,0x32,0x4a,0x47,0x9f,0xce,0xd2,0x51,0x77,0xcd,0xc9,0x02,0x54,0xf2,0x7b,0xcb,0xb8,0x83,0xe0,0xe0,0x1b,0x4a,0xa2,0xe0,0xd9,0x15,0xb6,0x02,0x19,0x75,0xa6,0xba,0xa6,0x98,0xd9,0x61,0x74,0xc6,0x48,0xa5,0x59,0x3d,0xc8,0x47,0xc9,0xe8,0x6b,0xbb,0x6d,0xcf,0x0e,0x8d,0x6b,0x58,0x8b,0x7d,0x4e,0x0b,0x3d,0x67,0xc4
+.byte 0x8e,0x78,0x59,0x40,0x88,0x82,0x33,0x27,0x2c,0xfe,0x2a,0x6c,0xe4,0x80,0xee,0x5a,0xd4,0x5f,0xc8,0xf7,0x82,0x02,0x67,0xfd,0xcb,0x55,0x3e,0xd8,0x41,0xb3,0xce,0x93,0xfe,0xe7,0x56,0xf5,0x63,0xba,0xfa,0x2e,0x79,0xfc,0x11,0x5d,0xb0,0xc6,0x32,0x54,0xed,0x71,0x9b,0x15,0xce,0x62,0x09,0xd4,0x28,0x7f,0x7b,0xa1,0x50,0x5b,0x46,0x24
+.byte 0x0e,0x40,0xa2,0xe2,0x7d,0x93,0xa6,0x2b,0x0b,0x9b,0x40,0x25,0xc9,0xca,0x7a,0x01,0x8b,0x7d,0x68,0xeb,0xd7,0x84,0xc1,0x9d,0xf9,0xfb,0xd0,0x1a,0xec,0xef,0x6b,0x4c,0x78,0x31,0x62,0x8e,0x9d,0xdc,0x78,0x8f,0xcb,0xf8,0xf9,0x41,0xdc,0x9f,0x6d,0x0a,0x27,0x67,0xce,0xbd,0xeb,0x87,0xb3,0x26,0xf3,0x51,0xe1,0xd6,0xd1,0x57,0x46,0xfe
+.byte 0x21,0xb9,0x88,0x7c,0xdd,0xa2,0x49,0x71,0x24,0xfb,0xc4,0xc0,0x6a,0x6b,0x05,0x7f,0x80,0xb0,0x09,0x3b,0x9e,0x6c,0x59,0x31,0x3e,0xac,0x7a,0x2e,0x5c,0x04,0x03,0xa3,0x6e,0xf5,0x66,0xee,0xc2,0x9b,0x65,0x88,0x06,0xbf,0xf5,0xe3,0x23,0x73,0x38,0x88,0x99,0xf1,0x64,0x68,0xdf,0x7d,0x04,0x06,0x72,0x92,0x0b,0x62,0x5d,0x12,0x1e,0x4e
+.byte 0xff,0x60,0x35,0xe3,0x0f,0xd9,0x8c,0xac,0x38,0x5b,0x91,0xc1,0x51,0xbb,0xa5,0x19,0x7d,0xfb,0x79,0xfa,0x42,0x3b,0xaa,0xf8,0xd3,0x0f,0xc3,0xf2,0xb2,0x68,0x91,0xae,0x28,0x83,0x4f,0x75,0xbd,0x20,0x5f,0x20,0xba,0xc2,0x75,0x85,0x74,0x23,0xf3,0x36,0x33,0x99,0x9c,0x64,0x4c,0xd1,0x5d,0xbd,0x06,0x46,0xbd,0x49,0xf0,0x86,0xc0,0xcb
+.byte 0x1b,0xbd,0xec,0x98,0x5b,0xb1,0x80,0xba,0x12,0x42,0x22,0x09,0x9a,0x62,0x3c,0xa8,0x33,0xbf,0xce,0x92,0xd4,0x07,0xef,0x34,0x33,0x8f,0x67,0x1d,0x25,0x60,0xeb,0xd3,0xe4,0x31,0x63,0xa8,0xab,0xe3,0xab,0x70,0x50,0xd8,0x44,0x9f,0x39,0x51,0xd2,0xb9,0x4b,0x16,0xe4,0xfa,0xc5,0x47,0xf3,0xae,0xb5,0xfe,0x7d,0x5d,0x43,0x28,0xa6,0x3d
+.byte 0xcf,0x71,0x23,0x6d,0x8e,0xd7,0x74,0xa4,0x86,0x9f,0x92,0x86,0x3c,0x1e,0x51,0xd4,0xe0,0xe6,0xd5,0xc4,0x53,0x3c,0x96,0x55,0xb9,0xac,0x63,0x5b,0xee,0x5a,0x03,0x84,0xb9,0x43,0x2c,0x0f,0x6d,0xbb,0xb5,0xca,0xf0,0x4f,0x3e,0x8b,0x3b,0x14,0x01,0x0e,0x81,0x0d,0xe6,0x62,0xa9,0x34,0x4e,0x03,0xc9,0x85,0x9f,0xc8,0x4f,0x52,0x3f,0x84
+.byte 0x1b,0xab,0x7e,0xaf,0x93,0x22,0xe2,0x0d,0x41,0x79,0x50,0xb2,0x17,0xa7,0x9a,0x80,0xd5,0x65,0x40,0x3b,0x56,0x9b,0xc9,0x00,0xcf,0x03,0xf1,0xff,0xcd,0x72,0x27,0xdb,0x74,0x94,0x70,0x02,0xdc,0x3a,0xee,0x00,0xcc,0x08,0x0a,0xab,0x40,0x87,0x24,0xaf,0x7d,0x67,0x18,0xd0,0x7c,0xeb,0x91,0x1f,0x7e,0x9e,0x41,0x7b,0x39,0xf2,0xfe,0xaf
+.byte 0xb7,0x6c,0x58,0xe0,0xdb,0xf7,0xf1,0x23,0x0b,0x98,0x08,0xfa,0xde,0xfa,0xf9,0x24,0x23,0xd1,0x7f,0x69,0xd3,0xb1,0x82,0x68,0x03,0x06,0x86,0x7a,0xf4,0x90,0x8d,0xa5,0xbd,0xbe,0x14,0x2f,0xa2,0x5e,0xaf,0x5c,0x1e,0x07,0x68,0x19,0x5a,0xd3,0x53,0x7d,0xe8,0x13,0x6b,0xe3,0x02,0x49,0x0d,0xd2,0x96,0x56,0xae,0x67,0x8a,0x27,0x61,0xa0
+.byte 0x60,0x20,0x2c,0xb4,0x5d,0xdf,0xc3,0x24,0x50,0xa9,0xbc,0x3d,0x5c,0xf3,0x2e,0xb6,0xba,0x71,0xf0,0x04,0x43,0x84,0x4d,0x80,0xe9,0xa5,0xdd,0xb3,0x1e,0x5e,0x56,0x32,0x1a,0xd4,0xe3,0x10,0x57,0x35,0xa8,0xf1,0xe5,0x96,0xc1,0x27,0xef,0xcc,0x21,0x71,0x10,0xd1,0x07,0x7e,0xb3,0xab,0x95,0x64,0x86,0xaf,0xc9,0x15,0xe6,0x98,0x5e,0xb1
+.byte 0xbd,0xde,0x99,0x38,0xfc,0x8d,0xb2,0x5a,0xa4,0x44,0x5b,0x74,0x31,0x31,0x07,0x93,0xf5,0x86,0x78,0xc5,0x82,0x26,0xfc,0x95,0x1f,0x33,0xd8,0xfe,0x70,0x42,0x2a,0xa7,0x3a,0xb1,0xb2,0x63,0xd6,0x5b,0x54,0x9c,0x54,0x45,0x4f,0x1b,0x4a,0xc2,0xb4,0x0e,0x99,0x48,0xde,0x8d,0xa6,0x5d,0xd3,0xdc,0x31,0xa4,0x2b,0x0d,0x44,0x6e,0x1a,0x10
+.byte 0x3f,0x6c,0xa0,0xab,0xcb,0xb4,0xf6,0x18,0xba,0x11,0xd4,0xd4,0x70,0xc4,0xab,0x04,0x4c,0xe7,0xe9,0x53,0xe5,0xd9,0xe7,0xeb,0x21,0xa2,0x2c,0xc4,0xc6,0xc3,0xe7,0x73,0xd9,0xd3,0x84,0xb0,0x12,0x94,0x3b,0xfd,0xd9,0x32,0xba,0xe3,0x37,0xc1,0xb9,0x4d,0xea,0x3e,0x3d,0x31,0x4e,0xa0,0xe7,0x73,0x9d,0x4e,0x26,0xd1,0xdf,0xe6,0x26,0xcd
+.byte 0xd7,0x17,0xd7,0x28,0x2c,0x04,0xe9,0x55,0xd5,0x70,0xaf,0xab,0xc1,0x07,0xbc,0xc4,0xd2,0x89,0xdc,0x22,0x59,0x19,0x0e,0xd8,0x8b,0xdd,0x46,0x7f,0xe4,0xad,0xa5,0x70,0xd7,0x18,0x51,0x30,0xd7,0xbc,0x26,0x45,0xe7,0xea,0xce,0xc7,0xf2,0xca,0xb1,0x9c,0x57,0x1e,0x10,0x5f,0x44,0x8d,0x3d,0xe8,0x55,0xa1,0x22,0x68,0x97,0xe8,0x03,0x9c
+.byte 0x8b,0x63,0x81,0xd9,0xcd,0x4c,0x6c,0xe3,0x68,0xc9,0x35,0xee,0x94,0x13,0x25,0x0b,0x12,0x61,0xbd,0xee,0x6f,0xc7,0xe8,0xb5,0x01,0x7a,0x9e,0xd0,0x5a,0x46,0xc6,0x19,0x1b,0xc2,0xf1,0x2d,0xaa,0x53,0x29,0xcf,0x23,0x1a,0x4d,0x94,0x0a,0x50,0x64,0xf5,0x3b,0x52,0x55,0xac,0xa5,0x21,0x15,0x47,0xd9,0x14,0x8c,0x7f,0x4d,0x79,0x6b,0xc1
+.byte 0x43,0x0a,0xf2,0x42,0xd2,0xb0,0x95,0x19,0x99,0xdd,0x1d,0x8e,0x84,0x8c,0x7e,0x59,0x69,0x93,0x86,0xae,0xf1,0x67,0x35,0x55,0x7c,0x5b,0x38,0x11,0x56,0xec,0x6c,0xbb,0xe8,0xc0,0x54,0xec,0x5f,0x65,0x13,0xe3,0x86,0xa0,0xb1,0xc1,0x5e,0x34,0x4f,0xdd,0x4d,0x00,0xc6,0x29,0x05,0x78,0x64,0x8c,0x19,0xb0,0xfc,0x8a,0xb2,0xc7,0x86,0x57
+.byte 0xa2,0xdd,0xed,0x43,0xc1,0x7f,0xab,0x89,0x19,0xe8,0xa6,0xf5,0x7a,0x15,0xfe,0xd5,0x4f,0x53,0xde,0x78,0x42,0x76,0xf7,0x8a,0x54,0xe8,0x37,0xfd,0xee,0x82,0x20,0xd5,0xe2,0x32,0xb9,0x32,0x67,0xc7,0xff,0xdc,0xf0,0x40,0x07,0x28,0x55,0x16,0x56,0x84,0xe9,0x17,0x25,0x17,0x8e,0x10,0xef,0x9f,0xed,0x33,0x83,0x6d,0x9e,0x87,0x82,0xb8
+.byte 0xa9,0x6b,0xcb,0xe5,0x04,0xfb,0x87,0x51,0x05,0x1a,0x64,0x64,0x51,0x34,0xa3,0x61,0x4a,0xe3,0xa6,0x35,0xa5,0xc9,0xe3,0xde,0xb0,0xcf,0x5f,0x68,0x49,0xbc,0x98,0xf9,0x0b,0x82,0xde,0xb1,0xf9,0x77,0x16,0x7c,0x1f,0x80,0x0c,0xfc,0xbb,0x6d,0x8e,0x92,0x93,0x00,0xc2,0xa5,0xbe,0xde,0x55,0x09,0x9d,0x83,0xa5,0x6c,0x0a,0xb5,0xc4,0x53
+.byte 0xde,0xbc,0x07,0xca,0x0f,0x43,0xea,0x50,0x25,0xee,0x51,0x3b,0xfb,0x7a,0xcf,0x31,0x8a,0x19,0x1c,0xa2,0x2d,0x72,0x79,0x81,0xc6,0xb8,0xe6,0xe1,0xd8,0x3e,0x0f,0xc0,0xae,0x73,0x40,0x30,0x15,0xaa,0xe3,0x72,0xc3,0x36,0xc1,0x42,0x11,0xc5,0x3f,0xf5,0x69,0x78,0xea,0x95,0x54,0x36,0xe8,0x7e,0x9c,0xad,0xbd,0xcd,0x19,0xfe,0x4a,0x04
+.byte 0xb4,0x54,0x14,0x98,0x58,0x6f,0x06,0x8f,0x8c,0x95,0xa8,0xc9,0xe8,0xc4,0x2b,0x03,0xaa,0x42,0x75,0x74,0xa2,0x63,0xdb,0xca,0xd1,0xf0,0x60,0xc3,0x63,0x84,0xfb,0xd7,0x5a,0x7b,0xca,0x45,0x8d,0x14,0xdc,0xf8,0x71,0x40,0x71,0xbb,0xa1,0x1a,0xd3,0x8c,0xfb,0xf6,0xf7,0xfc,0x82,0x72,0x50,0xc9,0xe3,0xc5,0xe2,0xb1,0x57,0xb1,0x24,0x3e
+.byte 0x11,0x4d,0x96,0x1c,0x3a,0xe1,0xb6,0xb7,0x0e,0x55,0x35,0x6c,0xd8,0x2b,0xe3,0x78,0xcd,0xac,0x8f,0x24,0x70,0xc6,0x35,0x5b,0x6e,0x75,0x7a,0xf1,0x7d,0x87,0x53,0xcf,0x0a,0x24,0xb6,0x6a,0xfd,0xef,0x90,0x07,0xcf,0xde,0x30,0xbc,0x8c,0xec,0xda,0x6f,0x45,0xad,0x92,0xb6,0x8d,0x6b,0xb8,0x8e,0xdc,0xe5,0xbf,0x57,0x67,0x5e,0x2f,0x4d
+.byte 0x5d,0xee,0x38,0x0a,0xaf,0xeb,0x62,0x84,0x2b,0x4c,0x30,0x7b,0x91,0x99,0x40,0x6f,0x09,0x2b,0x36,0xcd,0x04,0xeb,0x7c,0x8d,0xa5,0xbd,0xd6,0xb0,0xfc,0x27,0xcf,0x6b,0xdd,0xe1,0x94,0xbc,0x21,0xc6,0xc9,0x55,0x24,0xd4,0xa1,0x6f,0x1e,0xa2,0x81,0x31,0x22,0xb7,0x75,0x9e,0xa7,0x01,0x26,0x01,0x6c,0x12,0x91,0x02,0x87,0x40,0x5c,0x91
+.byte 0x1f,0x0c,0x55,0x07,0x12,0xa7,0x48,0xdd,0xed,0xb6,0xfe,0x38,0x05,0xbc,0xe1,0x2e,0x3b,0x89,0x4f,0x98,0x65,0x22,0x93,0xda,0x09,0x9f,0x04,0x90,0x66,0x81,0xd1,0x56,0x27,0x8b,0x26,0x99,0xbe,0x93,0x08,0xf1,0xfb,0x80,0x5b,0xaa,0xc4,0x96,0x88,0x93,0xb6,0x01,0xae,0xf6,0x69,0xaa,0x6f,0x4d,0xde,0x2f,0xc7,0x24,0xbf,0xe9,0xb8,0xeb
+.byte 0xcd,0xb2,0x0a,0x50,0x5c,0xd2,0x0b,0xfc,0x57,0x3b,0x96,0xf8,0xd9,0xbe,0xd2,0xb5,0x16,0xac,0x7c,0xe4,0x2f,0x46,0x93,0x86,0x48,0x91,0xfa,0xae,0xca,0x05,0x9e,0xfe,0x6e,0xae,0xa5,0x58,0x94,0xc0,0x58,0x1e,0xc5,0x69,0x28,0xe0,0x99,0x12,0x83,0xcf,0x35,0xe4,0x72,0x7d,0x4e,0x8b,0x66,0x56,0xb3,0xa6,0x2a,0x72,0x06,0x03,0x45,0xd1
+.byte 0x95,0xc9,0x93,0xb7,0xf4,0x8a,0x83,0xce,0x17,0x8b,0xf0,0x8e,0x8f,0x4a,0x68,0x55,0xd8,0xfc,0x54,0x8d,0xb5,0x62,0x17,0xa8,0xe6,0x18,0x03,0x53,0x04,0xb8,0xbe,0xd2,0xd0,0x7a,0x84,0xe1,0x39,0x31,0xc5,0x74,0xf2,0x64,0x1c,0x3b,0xd5,0x52,0x9b,0x81,0x8a,0x8f,0x36,0xc8,0xab,0x3d,0xe1,0xa8,0x2a,0xf2,0x84,0x9a,0xca,0x0c,0xcf,0xc9
+.byte 0x45,0x54,0x06,0xe8,0xd2,0x62,0x61,0x4d,0xeb,0x0b,0x38,0x4e,0x43,0x59,0x85,0x3a,0xe4,0xa3,0x25,0x15,0xc2,0xb5,0x7b,0x5e,0x2f,0xe6,0xc1,0x5d,0x2a,0xb7,0x57,0xb8,0x7e,0x61,0x51,0xc3,0x81,0x53,0x45,0x8a,0x6e,0x4c,0x89,0x84,0x2a,0x6b,0xca,0x15,0xff,0x97,0xfc,0x1f,0x8a,0x44,0xbd,0xcd,0x5e,0x32,0x6b,0x5f,0x78,0x7b,0xdf,0xdd
+.byte 0x9d,0x2f,0x21,0xf2,0x14,0x40,0x5f,0x5a,0xd5,0x21,0x27,0x3d,0x0b,0x9f,0x9f,0xb0,0x8e,0xab,0x9e,0x68,0x96,0x02,0xfd,0x4d,0xcc,0x03,0xf0,0x03,0xfb,0x4c,0xac,0xfa,0x00,0x3b,0xea,0x1a,0x53,0x80,0x77,0xec,0x53,0xc3,0x3c,0x6c,0xf8,0xa5,0x3e,0x52,0x34,0xd4,0xa1,0x52,0xb8,0xd6,0x19,0x8c,0xdf,0x85,0x27,0x61,0x22,0xe7,0x43,0xeb
+.byte 0x85,0xc0,0xbe,0x58,0xe6,0x60,0x81,0x4c,0xc6,0xbb,0xc0,0xbf,0x63,0x39,0x9d,0xad,0x2e,0xa8,0x2a,0x83,0x3d,0xfa,0xdb,0x0b,0x98,0x16,0x78,0x18,0x43,0xc7,0x17,0x82,0xb8,0xec,0x32,0x45,0x75,0x0c,0xc1,0x4c,0x84,0xbf,0xce,0x83,0x3b,0xb4,0x91,0xf4,0x0d,0x5d,0x83,0xf6,0xd6,0x10,0xab,0xc6,0x26,0x9b,0x68,0x59,0xec,0x48,0x4b,0x1d
+.byte 0x35,0x2a,0x5b,0x23,0x83,0x22,0x8e,0x7d,0xfa,0xce,0xde,0xb1,0xd9,0x78,0xf6,0x9e,0x08,0xba,0xfb,0xda,0xf2,0x04,0xc5,0x2a,0xac,0xbf,0xb4,0x04,0x05,0x1f,0x0b,0xeb,0xe8,0x2a,0x3c,0x3f,0x4f,0xb6,0xc8,0x6b,0x97,0x5a,0x9e,0xdb,0x4b,0x3c,0x93,0xc1,0x20,0x1c,0x62,0x91,0x74,0x76,0x49,0x92,0xc2,0xd8,0x0d,0xd8,0xfe,0xb5,0x68,0x77
+.byte 0x48,0x9f,0xbe,0xe0,0x78,0x20,0xe7,0xa4,0x3d,0x3e,0xa1,0x4c,0xc7,0xeb,0xd3,0x30,0xd3,0xf0,0x65,0xcf,0x18,0x3c,0xf8,0x25,0xc2,0x99,0xf4,0xec,0xef,0xdd,0xef,0xf3,0x6b,0x28,0x00,0xaa,0xfd,0x76,0xec,0x19,0x67,0xd6,0x79,0xa6,0x01,0x6e,0x20,0x3a,0x7f,0xd4,0xd0,0x05,0xb4,0xea,0xd4,0xde,0x11,0x06,0x44,0x4a,0x6f,0x15,0x2f,0x62
+.byte 0x9a,0xaa,0xeb,0xaf,0xb5,0xb5,0x46,0xb2,0x28,0x2e,0x74,0x26,0x06,0x91,0xeb,0x15,0xef,0xd4,0xfd,0xc7,0x1b,0x65,0x25,0x01,0x24,0xd2,0x44,0x05,0x18,0x1c,0x71,0x36,0x58,0xc4,0x37,0xfe,0x22,0x29,0xc0,0x2f,0xd2,0x4e,0xeb,0x43,0xb9,0xf9,0x4e,0x87,0xd7,0x92,0x77,0xa8,0x4f,0xa5,0x6e,0x5c,0x4d,0x3a,0xe9,0x16,0x62,0x30,0x51,0xbb
+.byte 0x32,0xd8,0x0d,0x86,0x20,0xbf,0x68,0x0f,0x3e,0xef,0x8b,0x0d,0xc5,0xa6,0x94,0x81,0xe9,0x6f,0x85,0xf5,0x22,0x6e,0x9e,0x0a,0x56,0xa3,0x43,0x79,0x50,0xd9,0x45,0x5f,0x5a,0x3f,0x53,0x53,0xb7,0xfe,0xb6,0x1c,0x63,0xab,0x7c,0xed,0x2f,0xc4,0x2b,0xa8,0x53,0xfb,0xad,0x46,0xf0,0x63,0xca,0x7a,0x6e,0xce,0xf4,0xb9,0x34,0xd0,0x9a,0xc8
+.byte 0x0d,0xd2,0x32,0xce,0x26,0x3f,0xcd,0xd9,0xbc,0xa9,0x46,0x65,0x45,0xfe,0x45,0xeb,0x0d,0xab,0xe6,0x31,0xb6,0xb9,0x41,0x53,0x7d,0x55,0xc3,0xfb,0x10,0x46,0x37,0x77,0x1f,0x15,0xf0,0x5f,0xcb,0x8f,0xea,0xc5,0xc0,0xb8,0xc6,0xb1,0x3a,0x06,0x42,0xec,0x38,0xec,0x06,0xd1,0x37,0x3b,0xe1,0x8d,0xad,0xc2,0xce,0x96,0x0b,0xf0,0xab,0xde
+.byte 0x9c,0x3c,0x09,0xef,0x59,0xcd,0x67,0xa7,0x6e,0x0e,0xc7,0xee,0x51,0x6d,0x90,0x40,0x0e,0xdf,0xb1,0x13,0xe3,0x0c,0xb6,0xe8,0xcb,0xf5,0x57,0x50,0xeb,0xdf,0x09,0x45,0x72,0x40,0xff,0xdc,0x5c,0x51,0x42,0x47,0xb2,0x9e,0xca,0xf3,0x1b,0x06,0xb1,0x3e,0x04,0x55,0x96,0x63,0x24,0x16,0xdb,0x3e,0xab,0x98,0x33,0x70,0x6f,0xfd,0x8f,0x7b
+.byte 0x56,0xb0,0x7f,0x28,0x26,0xc4,0x2a,0x9e,0xf5,0xa7,0xba,0x61,0x75,0xa4,0xb1,0x25,0x60,0xe5,0x9c,0x7e,0xb4,0xaa,0x04,0xa1,0x33,0x5a,0x8d,0x88,0x1d,0xc4,0x38,0x58,0x28,0x23,0xc7,0xac,0x20,0xf8,0xaa,0x18,0xf8,0xc7,0x27,0x05,0x07,0xf7,0x12,0xfe,0xe1,0xa5,0x99,0xaa,0x55,0x79,0x72,0xc4,0x14,0x08,0x14,0x4a,0xfb,0xf7,0x66,0x81
+.byte 0x6e,0xed,0x81,0x12,0x5f,0xb6,0x08,0x00,0x37,0xf9,0xdc,0xdf,0x4d,0xcb,0xfa,0xc6,0xf3,0xc2,0x17,0x17,0x52,0x39,0x7b,0xa0,0x3e,0x25,0xc9,0x48,0xd8,0xa6,0x1b,0x8b,0xdb,0xf8,0x74,0xac,0x6b,0x16,0xec,0xa6,0x4a,0x1e,0x7e,0x5c,0x50,0xbf,0x81,0xef,0x3c,0x7d,0x9d,0x21,0x38,0xa9,0x26,0x3c,0x30,0x7a,0xfb,0xab,0xd8,0x6a,0x0a,0xaa
+.byte 0xbb,0x6e,0x91,0x92,0x7c,0x04,0x02,0x0e,0xa2,0x71,0xc7,0xde,0x7d,0x42,0xaf,0xe5,0x92,0xc1,0xb9,0xd7,0x52,0xaa,0x32,0xea,0x39,0x84,0x17,0x40,0xb0,0x83,0x18,0xff,0x46,0xb8,0x59,0xd9,0xa3,0xce,0x82,0x7e,0x65,0x54,0xe0,0xa4,0x6d,0x8a,0xbc,0x6a,0x65,0xb2,0xd5,0x96,0x5b,0x1c,0x9a,0x32,0x72,0xf7,0x81,0x57,0xcd,0xb3,0x22,0xc5
+.byte 0x7d,0x20,0x24,0xea,0xbe,0x51,0x4c,0xb3,0x48,0x36,0x4f,0x73,0xf4,0x3f,0x07,0x92,0x01,0xe2,0x1e,0x78,0x3f,0x8e,0x1f,0x35,0x1a,0xf1,0xe1,0x14,0xd1,0xe7,0xd9,0xfd,0xd8,0xf7,0x20,0xc2,0xf3,0x7a,0x59,0xc9,0x1d,0x13,0x41,0x01,0xf6,0x77,0x69,0xfb,0x0f,0xc7,0xe4,0x58,0x04,0xce,0xe8,0x73,0x87,0x2f,0xef,0xe6,0x36,0x38,0xc7,0x91
+.byte 0x2d,0x17,0xb5,0x56,0x68,0xb1,0x9f,0xbf,0x2e,0x4b,0xe7,0x09,0x7b,0x35,0x33,0x5a,0x6c,0xc1,0x6f,0xb3,0xac,0x6c,0x1e,0xfe,0xc0,0xc9,0xd8,0x77,0xf5,0xcb,0x5e,0xcc,0xd1,0x2f,0xdd,0x23,0x8b,0x3b,0xb5,0x43,0x96,0x1f,0xa9,0xe4,0x84,0x41,0x92,0xe9,0x68,0x47,0x50,0xf7,0xd4,0x85,0x22,0xa1,0x43,0xaa,0xde,0xf7,0xea,0xe0,0x54,0xaa
+.byte 0x0d,0xe6,0xa5,0xb8,0x7e,0xec,0x13,0x9a,0x1e,0x6c,0x10,0x9d,0xa8,0xfb,0x97,0xde,0x24,0xda,0x33,0xbb,0xab,0x17,0x7a,0xb4,0x72,0xaf,0xed,0xc9,0xa4,0x62,0x65,0x0c,0x99,0x3d,0x74,0x7f,0xff,0x59,0xa9,0x8e,0x37,0xb9,0x10,0x30,0x26,0x3f,0x2f,0xfc,0x1e,0xe2,0xc6,0xb8,0xff,0x41,0xb3,0x35,0x3f,0x41,0xf4,0x47,0xbc,0x76,0xc6,0x77
+.byte 0x0f,0xf8,0xff,0xb8,0xd2,0x34,0x40,0xac,0x43,0xcb,0xcf,0x1f,0x57,0xaa,0x1a,0xa7,0xe1,0x4a,0x69,0xd7,0x05,0xa7,0x9d,0xff,0x13,0x43,0x91,0xe3,0x09,0x1c,0xb2,0xb2,0x82,0x06,0xa3,0x3c,0x35,0x85,0x9e,0xd0,0xcf,0x1c,0xb9,0x13,0x09,0x7d,0x3d,0x17,0x0f,0xf8,0x2f,0x61,0x97,0x7e,0x02,0xe0,0x78,0x07,0x69,0x8c,0x91,0xbe,0x96,0x92
+.byte 0x4a,0x03,0xa7,0x31,0x5f,0x6c,0xfe,0x55,0xb2,0x17,0xe8,0x4c,0x64,0x48,0x18,0xde,0x4f,0x5a,0xce,0xd2,0xcb,0x83,0x4d,0x1b,0x2a,0x1f,0xce,0x85,0xf7,0xdc,0x74,0x8c,0x42,0xc6,0x5a,0x3a,0x51,0x22,0x79,0x70,0xa0,0xe0,0x29,0x2a,0x73,0xe4,0x53,0xb4,0x47,0x5f,0x54,0xa8,0x65,0xe4,0x89,0x78,0xf9,0xb9,0x5f,0x5f,0x9d,0xa8,0xf7,0x82
+.byte 0x4e,0x34,0x60,0xfc,0xe3,0x88,0x65,0x73,0x99,0x1f,0x53,0xed,0xe8,0xf0,0xf4,0x5a,0x0a,0x49,0x42,0x6e,0x02,0x3f,0xa8,0x63,0x21,0x02,0x2e,0x8f,0x33,0xba,0x0e,0x10,0xd3,0x4c,0x1a,0x8b,0xf5,0x84,0x8e,0x2b,0x37,0x12,0x23,0x77,0x02,0x45,0xc7,0xc3,0x79,0x06,0xc2,0x8c,0xaa,0x32,0x53,0x7c,0x19,0xa2,0x92,0x7e,0x47,0x40,0x8f,0xae
+.byte 0x8a,0x64,0x51,0x67,0xe1,0xc1,0xc3,0xd2,0x14,0x1d,0x63,0x0c,0x80,0x04,0x30,0x3d,0xee,0x58,0x44,0xe4,0x14,0x63,0xfc,0x95,0x05,0x3e,0xc1,0x8d,0xd3,0xcb,0x5d,0xc1,0x8e,0xf9,0xd7,0xe5,0x9d,0x97,0xef,0x8a,0xaa,0x50,0x31,0xa3,0x01,0x3a,0xb2,0x8d,0x63,0xb6,0xe7,0x34,0xec,0xa1,0x7a,0xff,0x57,0x95,0xbb,0x1d,0xbe,0x0c,0xa5,0x91
+.byte 0x92,0x08,0x06,0x1c,0x67,0x03,0x2e,0xee,0xf6,0x6f,0xa0,0xb7,0x9a,0x7c,0xe3,0x6a,0x8e,0xd8,0x50,0xc1,0xd6,0xa1,0x8d,0xe9,0x66,0x9a,0x1f,0x62,0x15,0x04,0x93,0x74,0xe8,0x04,0x0d,0x27,0x55,0x2b,0x07,0xb1,0xbd,0x69,0xe4,0xc1,0x34,0x8e,0xe7,0xfb,0xa0,0x3f,0x40,0x31,0x47,0xba,0xcb,0x80,0x88,0xf7,0x4f,0x46,0x05,0x31,0xaf,0x23
+.byte 0xdf,0x93,0x09,0x0a,0x15,0xc9,0x95,0x74,0x52,0x72,0xf4,0xbf,0x0d,0x07,0xb6,0xcc,0x4b,0x40,0x12,0xf3,0x87,0xea,0x29,0xd8,0x29,0x31,0x23,0xac,0x29,0x1a,0x89,0x83,0x5b,0x33,0x4b,0x6b,0x69,0xbe,0xb6,0x15,0x7e,0xfd,0xf2,0x95,0xc4,0xbe,0xeb,0xee,0x59,0x01,0x2a,0xce,0xca,0x80,0xda,0xf8,0x1a,0x01,0x23,0xf7,0xa1,0x4f,0xf5,0x83
+.byte 0x5e,0x16,0xd9,0x12,0xa9,0x4e,0xcb,0x59,0x23,0x4f,0x40,0xd7,0xbf,0xaf,0x76,0xf0,0x50,0x31,0x27,0x3a,0x8b,0x1d,0x9b,0xb1,0x1c,0x41,0xb0,0xed,0xe6,0xf3,0xa8,0x5f,0x6b,0x58,0x54,0x92,0xaf,0xcc,0x44,0x5c,0xea,0xdb,0x09,0xc5,0x26,0x5e,0xbe,0x46,0xbd,0x72,0x49,0x5a,0x4e,0x65,0x7e,0x75,0xcf,0xfc,0xf6,0xd0,0x3c,0x4a,0x7e,0xd6
+.byte 0x8e,0x8e,0xb4,0x19,0x45,0x75,0xbf,0xc3,0x5e,0x46,0xff,0xc9,0x46,0x65,0x8d,0x31,0x01,0x5e,0x1c,0x13,0x93,0x56,0x6f,0x28,0xec,0xf3,0x77,0xfa,0x6e,0xb9,0x0e,0xb6,0x8e,0x0e,0x38,0xf8,0x28,0x64,0xa2,0xa1,0x42,0x9a,0xb4,0xf3,0x14,0x8d,0x17,0x80,0x05,0x82,0x7c,0xf1,0xea,0x8b,0x4b,0x62,0xa0,0xde,0xf6,0xd7,0x36,0xb0,0x70,0x8d
+.byte 0x03,0xf6,0xc8,0x2a,0x9e,0xc0,0xbb,0x2f,0xcb,0xef,0x35,0xf7,0x16,0xcd,0xd6,0xd6,0x90,0xd7,0x5d,0x61,0x00,0x33,0x9f,0xd8,0xd1,0xda,0x17,0x67,0x90,0xd1,0xf8,0x59,0xcb,0xf1,0x76,0xc2,0xbe,0x1f,0x5d,0x0d,0xb2,0x02,0xbd,0x19,0x9f,0x5a,0xa0,0x91,0xac,0x51,0xb5,0xf5,0x0a,0x64,0x67,0xf2,0x49,0x30,0x6c,0x57,0x83,0xda,0x90,0xf1
+.byte 0xc6,0xc7,0xe6,0x05,0x13,0x30,0x52,0xfd,0x2a,0x47,0xea,0xae,0xd3,0xed,0xe4,0x64,0x1f,0x6c,0xb1,0xdf,0xca,0x20,0x97,0x2a,0xc8,0xdc,0x00,0x0e,0x5b,0x59,0xc8,0x16,0x95,0x68,0x9a,0x2e,0x44,0xab,0xf6,0x93,0x7c,0x8f,0x66,0x4f,0x07,0x42,0x3f,0xa5,0x81,0xe7,0xab,0x59,0xbb,0xae,0xb1,0x3e,0x9a,0x25,0xf1,0xde,0xac,0x4c,0x1d,0x7a
+.byte 0x54,0xb9,0xa9,0x59,0xaf,0xb0,0xab,0xaf,0x6b,0x76,0x66,0x1e,0xbe,0x1a,0xc1,0x61,0x1b,0x81,0x6b,0xe8,0xe4,0x73,0x6a,0x87,0xe9,0x39,0xcb,0x2c,0xab,0x64,0x36,0x9a,0x11,0x46,0xec,0x9f,0x30,0xb6,0x2c,0x14,0xe0,0xec,0xbe,0x33,0xde,0x60,0xc6,0x00,0x29,0x3c,0x55,0xda,0xfc,0x64,0xff,0xaa,0xbf,0x99,0x58,0xe2,0xe3,0xec,0xde,0xca
+.byte 0xd1,0x3d,0xd2,0xad,0xaa,0xca,0x36,0x8f,0x93,0xa2,0xdd,0xde,0xaa,0x49,0x7f,0xdd,0x39,0x91,0xa0,0x7b,0x33,0xdf,0x36,0xcd,0xc3,0x3a,0xbc,0x53,0xf0,0x07,0x99,0x78,0x4e,0x63,0x47,0x79,0xbf,0x21,0xfc,0x05,0x47,0x69,0xec,0xee,0xf4,0x21,0x97,0x94,0x0c,0x7a,0x9f,0xa6,0xeb,0x5b,0x23,0xed,0x9d,0xc1,0xe1,0x5e,0x10,0xca,0xe0,0x84
+.byte 0x5a,0xdd,0xf6,0xae,0xd8,0x23,0x98,0xea,0x6c,0x43,0x77,0x41,0xf3,0x84,0x5a,0xe8,0xda,0xb3,0x11,0x0e,0x19,0x33,0xe9,0xf9,0x7a,0x90,0x07,0x68,0xf1,0xe4,0x52,0x0c,0x03,0x67,0xb9,0x42,0x41,0x24,0xa3,0x61,0x67,0x75,0xc9,0xb5,0xdd,0x10,0xf1,0x20,0x93,0x54,0xdb,0x0d,0xc7,0x0d,0x25,0x3e,0xda,0xb3,0xe7,0xce,0x97,0x7e,0xdb,0x1a
+.byte 0x8f,0x92,0xff,0xe3,0x44,0x2d,0x6b,0xdb,0xe0,0x69,0x8b,0x16,0xce,0xe8,0xc7,0x93,0xf1,0x19,0xb9,0xd3,0x41,0x45,0x8d,0x95,0xb3,0x03,0xb2,0x66,0x96,0x95,0x91,0x33,0x1c,0xee,0xde,0xd7,0x9d,0xab,0x32,0x2f,0xb8,0x3c,0x7a,0x44,0x8f,0xa6,0xca,0x02,0x03,0x2f,0xa8,0x44,0x85,0x0e,0xf5,0x27,0x90,0x84,0xd9,0x80,0x06,0xf4,0x4f,0xc7
+.byte 0x21,0xc5,0x92,0xa4,0x2d,0x08,0x42,0x4c,0xa7,0x84,0xfa,0x7e,0x2b,0x66,0xfb,0x7c,0x81,0xea,0x5c,0x7d,0xdd,0x86,0xf1,0xf5,0x04,0xef,0xf2,0x50,0x12,0x72,0x42,0x22,0x23,0x74,0x7f,0xe7,0xed,0xd9,0xce,0x78,0x10,0x83,0x37,0xd0,0x81,0x97,0x4a,0xac,0xc2,0xe5,0x13,0x91,0x83,0xe2,0x6e,0xff,0x5a,0x0b,0xc3,0x4d,0xc1,0x3e,0x97,0x16
+.byte 0x96,0x69,0x39,0x9e,0x1d,0x6b,0x16,0x82,0xa2,0x94,0x0d,0x50,0xdd,0xa3,0xda,0x9d,0xda,0x3f,0x46,0xce,0x6c,0xd0,0xdf,0x6e,0x1b,0x17,0x47,0x51,0x74,0x6f,0xe9,0xa4,0x6b,0xae,0xd2,0x6e,0x5b,0xc0,0x26,0xc6,0x0b,0x84,0xb1,0x39,0xcf,0x9e,0x7c,0x18,0x52,0xd7,0x8f,0x33,0xae,0x3d,0xaf,0x3d,0x1a,0xba,0x3f,0x09,0x76,0x22,0x1d,0xf3
+.byte 0x42,0x14,0x4f,0x06,0xc7,0x33,0xc1,0x2d,0x58,0x1b,0x4c,0xc0,0x3a,0x29,0xa6,0x5e,0x19,0x26,0xdf,0x36,0x18,0xa9,0xc5,0xe9,0xd3,0xb1,0xae,0x86,0xa8,0x7f,0xd9,0xb4,0x18,0xef,0x9c,0x46,0xb6,0xf2,0xb2,0xb6,0x6e,0xe2,0xf8,0x5f,0x27,0xea,0x76,0xd3,0x40,0x68,0x94,0x66,0x8a,0xf5,0x9f,0xee,0x0c,0xe5,0xae,0xb6,0xba,0x87,0x42,0x40
+.byte 0xc9,0x83,0xac,0xb4,0x2c,0xec,0x74,0xb7,0x55,0x17,0x0b,0x1e,0x45,0x1a,0x87,0x9d,0x52,0xce,0xb7,0x58,0x2f,0x45,0xc7,0x7d,0xf3,0xd3,0x11,0x2e,0xf4,0xd8,0xc0,0xb8,0xc3,0x31,0x45,0x68,0x40,0xe8,0x8a,0x33,0x20,0x9a,0x06,0xa8,0x18,0x53,0xb2,0x73,0xa1,0x57,0xac,0x8f,0x56,0xeb,0x8e,0xa4,0xfc,0xd6,0x76,0x7e,0x81,0x62,0x2c,0x17
+.byte 0x49,0xb4,0xcc,0x15,0x66,0xcb,0xa2,0x3c,0x29,0xf0,0x73,0x0e,0x9a,0x34,0x16,0x6d,0x43,0x62,0x20,0x89,0x14,0xae,0x8b,0x5d,0x61,0x54,0xa1,0x82,0x49,0x73,0xb9,0x2b,0x48,0xd4,0xe3,0x21,0x37,0x5e,0x4d,0xbf,0xd0,0x72,0xa4,0x23,0xdb,0x7c,0xd9,0x45,0x77,0x8a,0x24,0x23,0x56,0xcd,0x84,0x80,0x44,0x12,0xce,0x99,0x39,0xbd,0x77,0xff
+.byte 0x8c,0x62,0x8d,0x56,0x77,0x24,0x40,0x11,0x22,0xab,0x28,0xd6,0x75,0x2b,0xbb,0xc1,0x51,0xd6,0x5e,0x61,0x1c,0xe9,0xac,0x36,0x99,0x52,0x44,0xa5,0x20,0xdb,0xe0,0x12,0x9a,0x45,0x8f,0x7f,0x47,0xf9,0xa3,0x91,0x18,0x2b,0x51,0x9a,0x9f,0x3f,0x7d,0x36,0xde,0x71,0xae,0xca,0x62,0x62,0x16,0xda,0x19,0x9c,0x84,0xce,0xde,0x93,0x22,0xde
+.byte 0xaf,0xe7,0x91,0x09,0xe8,0xf0,0x0e,0x07,0x71,0xdf,0x48,0xcd,0x8a,0x77,0x19,0x3c,0xd6,0xef,0x8e,0xe0,0x49,0xdf,0xcb,0xd6,0x34,0x78,0x7f,0x42,0xc2,0x6e,0x7a,0x50,0x53,0xee,0xbf,0x73,0x4b,0xd4,0x4f,0x06,0x18,0x26,0x67,0x51,0x54,0xa3,0x40,0xe6,0xb3,0x61,0x4b,0xfd,0xee,0x62,0x00,0x44,0x6c,0x0d,0x8b,0x2f,0x4d,0x06,0x17,0x41
+.byte 0xee,0x8b,0xde,0x1f,0x80,0x36,0x58,0x3e,0x0a,0x53,0x0a,0x83,0xf9,0xba,0xbd,0x91,0x6a,0x20,0x32,0x42,0x6c,0x85,0xdc,0x84,0xfd,0xce,0x57,0xbe,0xf8,0xa5,0x2c,0x7e,0xf9,0x1b,0x07,0xf4,0x32,0x13,0x32,0x79,0xdc,0x91,0xfc,0xc0,0x18,0xe6,0x1e,0xb2,0x67,0x9d,0x08,0xd2,0x89,0xa2,0xb1,0xbf,0x37,0xe1,0x3f,0x9e,0xb5,0x17,0xf7,0x2f
+.byte 0x9a,0x4f,0x3c,0xea,0x5d,0x48,0x56,0x48,0x35,0x17,0xe9,0x5a,0x99,0xa7,0x2e,0x25,0x4f,0x96,0xa6,0x3d,0x3c,0xf8,0xdc,0xe7,0xe5,0x98,0x46,0xf7,0x10,0x16,0x4f,0xb0,0x7b,0x48,0x06,0xbb,0x9a,0x5a,0xad,0x32,0x49,0x92,0x39,0xb2,0xfe,0x01,0x1a,0x5e,0xcc,0xf7,0x0d,0x65,0x1c,0xf5,0x3d,0xb3,0x40,0x28,0x06,0x6e,0xbb,0x74,0x2a,0x95
+.byte 0xe9,0x62,0x2a,0xe2,0x19,0x38,0xc6,0x0d,0x46,0x30,0x6d,0x90,0xa5,0x68,0x4d,0x89,0xf0,0xf4,0xaf,0x52,0x11,0x8a,0x47,0x65,0xc0,0x6d,0xee,0xde,0xbc,0xed,0xf2,0x94,0xf3,0xfb,0xfd,0x2f,0xea,0xd5,0x36,0x89,0x8a,0x22,0xb8,0x75,0x3c,0xda,0x8d,0x3f,0x71,0xe5,0x50,0xb8,0xef,0xfc,0xa1,0x34,0x4a,0xb0,0x56,0x64,0xaf,0x28,0x0c,0x7a
+.byte 0x28,0x3e,0xc8,0x83,0xc2,0xbb,0x89,0xc4,0x29,0x7f,0xc9,0xe7,0x4e,0xcb,0xdc,0x8f,0xe8,0xa4,0xdc,0x0d,0xcc,0xa0,0x16,0xda,0xa9,0x34,0x61,0xec,0x64,0xa7,0xf4,0x47,0xe9,0xee,0xbf,0xc6,0x4b,0xc5,0x01,0x65,0xe4,0xe0,0x12,0xd6,0x27,0xda,0x30,0xb5,0x60,0x72,0xe1,0xee,0x38,0x23,0x6c,0x9d,0xbb,0x83,0x01,0x4b,0x26,0x9a,0x68,0xb3
+.byte 0x89,0xb3,0xe0,0x10,0x22,0x58,0xef,0x2d,0xd4,0x86,0xab,0xab,0xc4,0xd8,0x9c,0x56,0xe8,0x54,0x40,0x86,0x11,0xd2,0x6b,0xc0,0xaf,0xfc,0x4a,0xef,0x24,0x38,0x79,0x32,0x54,0x26,0x8b,0x7e,0x02,0xad,0x86,0x9d,0x40,0x65,0x28,0x28,0xa3,0xa6,0xe4,0x07,0x29,0x3a,0xbb,0x81,0xed,0x17,0x54,0x51,0x35,0xc6,0x88,0x9c,0x63,0x7e,0x73,0x02
+.byte 0x28,0x13,0x4b,0x33,0xc0,0x68,0xbc,0xae,0x8c,0x59,0xd4,0x84,0x1d,0x41,0x86,0x5a,0xf6,0x14,0x50,0x13,0x88,0xca,0xc8,0xb8,0xfc,0x61,0xeb,0xe6,0x69,0x70,0x4a,0xa5,0xa5,0x36,0x4b,0xac,0xca,0x00,0x28,0xae,0xb0,0x03,0xef,0xe3,0x92,0xad,0x97,0x32,0x05,0x8c,0x93,0x95,0x45,0xd5,0x75,0x66,0x11,0xd3,0x6f,0x7f,0x5f,0x35,0x44,0xb7
+.byte 0xd7,0x34,0xcf,0x8c,0x4a,0x61,0x68,0x63,0x3f,0x92,0x54,0x01,0x3c,0x25,0x2d,0x6f,0x4a,0x2d,0x55,0xff,0x3f,0x86,0x85,0x9f,0xc2,0xa1,0xde,0x6b,0xbf,0x7e,0xb4,0x7c,0xc1,0x80,0x73,0xf5,0x3b,0x85,0xae,0x36,0x1a,0xdf,0x00,0x52,0xb7,0x70,0xa9,0x42,0x79,0xd2,0x26,0xf8,0x3b,0xeb,0x9f,0x2e,0x15,0x33,0xc8,0x85,0x2d,0x63,0xb2,0x89
+.byte 0x24,0x8e,0xfd,0xe6,0xdf,0x01,0x80,0x8b,0x27,0xe3,0x7e,0x17,0xc2,0x4e,0x26,0xa2,0xe1,0x95,0x81,0x3a,0xdd,0x2a,0xf4,0x75,0x21,0x64,0x11,0x04,0x5e,0x00,0x39,0xf0,0x08,0x68,0x67,0x09,0xa8,0x9b,0xbe,0xb7,0x62,0x0e,0xa8,0x69,0xcd,0x4e,0xaf,0xc8,0x4f,0x92,0x3d,0x8e,0x35,0x60,0x70,0xb3,0xda,0x2f,0x38,0x80,0x6f,0x5e,0xcc,0x3b
+.byte 0x6e,0x05,0x26,0x14,0x9d,0x36,0x72,0x7d,0x09,0xb8,0xb7,0xa1,0xf7,0x5f,0xb3,0xe1,0xd6,0xc5,0x54,0x4e,0x80,0x4d,0x06,0x8f,0x84,0xbb,0xb6,0x65,0x87,0x2c,0x19,0x4a,0x74,0x3c,0x34,0x62,0x32,0xad,0x4c,0x06,0xa3,0xbb,0xfb,0x4f,0x4f,0x9d,0x91,0x84,0x63,0x75,0x34,0xcc,0x6b,0x00,0xa1,0x5a,0x63,0x03,0x8d,0x1e,0xdb,0xa4,0x0c,0xe6
+.byte 0x3d,0xd1,0x94,0x77,0xd8,0x77,0x8c,0x39,0x48,0x78,0xb1,0xb5,0xa2,0x41,0xd0,0x6d,0x27,0x20,0x4a,0x41,0x88,0xa5,0x78,0x3f,0x51,0x72,0x8c,0x80,0xe7,0x37,0x81,0x8b,0x06,0x46,0x58,0xab,0x23,0x85,0x47,0x89,0x39,0xf9,0x14,0xfe,0xbf,0x07,0x7c,0x47,0x8e,0xcc,0xd7,0x08,0xfe,0x5d,0xee,0xf9,0x94,0xa2,0x83,0x81,0x8a,0xfd,0x0f,0x9a
+.byte 0xa7,0xe4,0x59,0xad,0xe6,0x1f,0xed,0x5d,0xe4,0x20,0xd6,0x2f,0xa7,0xd3,0xcf,0x5b,0x18,0x6d,0x24,0x79,0x66,0xd9,0xaa,0x44,0xfa,0x8d,0x74,0x60,0xcc,0x7e,0xbf,0x4f,0x0e,0xe3,0x9c,0xa5,0xe4,0xff,0x14,0x05,0xff,0x24,0x62,0x94,0x00,0x7a,0x58,0xe5,0x0b,0x3b,0xe8,0xee,0xe1,0x4d,0x4e,0x34,0x26,0xba,0x70,0x10,0x5e,0x14,0x4f,0xa5
+.byte 0x7a,0x9e,0x7b,0x28,0x99,0xbe,0x94,0x4a,0xcb,0x8d,0x65,0x60,0xa0,0x6e,0xc7,0xbc,0x51,0xba,0xb5,0x07,0x97,0x25,0x42,0xb7,0x2c,0x0e,0x9b,0xfc,0xfb,0x35,0x6f,0x74,0x10,0xce,0x25,0xdb,0xa9,0x7c,0x11,0x61,0x43,0xf9,0x19,0xbf,0xe2,0x21,0xa3,0x57,0x3c,0x41,0x0a,0x15,0x4e,0x7f,0x6b,0x38,0xb6,0x73,0x41,0xa2,0x4e,0x8e,0xb9,0x44
+.byte 0xee,0x2a,0x2e,0x0a,0x9e,0x85,0xf1,0x6e,0x93,0x72,0x42,0x50,0x55,0xe1,0xc6,0x18,0x11,0x92,0xf7,0xbf,0x05,0xd8,0xb6,0xbc,0x2b,0xd5,0xe0,0xd3,0x9b,0x64,0xc4,0xdd,0xb0,0xb3,0x46,0xd8,0xfb,0x73,0xea,0xed,0x06,0x96,0x16,0x9e,0xf6,0xc6,0xe8,0xbe,0xae,0x00,0x2f,0x5a,0xf4,0x1f,0xb5,0x28,0x7c,0x75,0x76,0x68,0x74,0xa2,0x57,0x0e
+.byte 0x6c,0xfa,0x2d,0xbe,0x34,0xf1,0xc9,0x2b,0x83,0x58,0xe7,0x2a,0x87,0xdb,0x47,0xae,0xc7,0xc2,0x78,0x50,0xed,0x20,0xdf,0x30,0x38,0xdd,0x84,0xa9,0x6b,0x00,0xb1,0x7b,0xbb,0x69,0xd3,0xbe,0xed,0x3d,0x99,0x6e,0x39,0x42,0x75,0x8a,0x6c,0x7c,0xa5,0xcf,0xc9,0xcf,0x11,0x14,0xb3,0xaf,0x72,0x00,0x3b,0x58,0xdd,0x2a,0xe1,0x44,0xa7,0x51
+.byte 0x15,0x05,0x1b,0x18,0x49,0x07,0x90,0x4c,0xbc,0x99,0x88,0x64,0xf6,0x14,0x0b,0x99,0xc0,0x84,0xc9,0x06,0x32,0xf0,0xec,0x19,0x8d,0x4a,0xb8,0xdb,0x32,0xb4,0x5e,0xc9,0x0c,0x24,0xf0,0xad,0xdc,0xf4,0x32,0x3b,0xf6,0x68,0x28,0x4a,0xa5,0x5b,0xb7,0xd5,0x00,0x35,0xf8,0x56,0x03,0xa3,0x86,0xa0,0x8a,0x1b,0x53,0xb5,0x58,0x73,0x8c,0xf9
+.byte 0x2b,0xd8,0xcb,0x88,0xe7,0x7e,0x79,0x68,0x13,0x5d,0x7d,0x23,0xc4,0xec,0x9c,0xf4,0x95,0x97,0xbf,0xb2,0xd9,0xdf,0x38,0xe8,0xa2,0x79,0xf7,0xe8,0x36,0x80,0x59,0x3f,0x58,0x2f,0xf7,0xf9,0x32,0x73,0xdd,0xd6,0x9e,0x20,0x1a,0x29,0xab,0xc1,0x77,0x14,0x71,0x3c,0xde,0x90,0xe9,0xea,0xdb,0x78,0x14,0xa3,0x89,0x43,0xf1,0x42,0x43,0x3f
+.byte 0xe7,0x67,0x32,0x3d,0x65,0xdc,0xa4,0x79,0x8f,0x81,0xa5,0xb0,0x94,0x0f,0x96,0xf5,0x82,0xcc,0x47,0xc1,0x29,0x39,0x70,0x7a,0xf3,0x49,0xf5,0x09,0x43,0x50,0x56,0xd6,0xea,0xc4,0x35,0xa5,0xa2,0x8a,0xbe,0xc0,0xe3,0xfe,0x4c,0xa2,0x83,0x09,0xab,0x72,0x8a,0x96,0x7c,0x01,0x70,0xb2,0xd5,0x62,0xb7,0x67,0x59,0x36,0xcf,0x56,0x2d,0x14
+.byte 0xc2,0x69,0x49,0x52,0x4e,0x7c,0x45,0x4b,0xef,0xcd,0x79,0xcd,0xe6,0xa6,0xd0,0xbe,0x10,0x1e,0x18,0xca,0xe7,0x8d,0x65,0xb1,0x17,0xc7,0x2c,0xc8,0x2a,0x5b,0xe8,0x08,0x11,0x15,0xea,0xa9,0x43,0x7b,0x70,0x04,0x0c,0xc8,0xca,0x67,0x18,0x18,0x12,0x16,0xc2,0xd3,0xf2,0x0a,0xc7,0x01,0xa9,0x97,0x61,0xf6,0xa7,0x44,0x9a,0xb3,0x67,0xdc
+.byte 0x07,0x63,0x02,0x02,0x2e,0x58,0x80,0xa9,0x95,0xa0,0x8e,0x86,0xb6,0xf6,0x14,0x13,0x0a,0xea,0xf1,0x6d,0xd9,0x98,0x37,0x12,0xdb,0x67,0x1b,0x13,0x8e,0xd1,0xfa,0x2f,0x98,0x53,0x3c,0xd7,0x56,0x55,0x42,0x2f,0x64,0x59,0xd5,0xb7,0x6e,0xa8,0x6c,0xc2,0x40,0x11,0xb5,0xa1,0xc0,0x5c,0x45,0x87,0x91,0xb1,0x1c,0x4e,0xa9,0xf6,0x72,0x57
+.byte 0x50,0x8e,0xc5,0xfc,0x64,0x59,0x52,0x82,0xb0,0x75,0xc3,0x98,0xff,0x32,0xce,0xa4,0x39,0xb8,0xa4,0x61,0xb4,0x53,0x3f,0xc7,0x80,0x35,0x48,0xaf,0xa8,0x67,0xfe,0xa1,0x1d,0x3c,0x95,0xb5,0x63,0x1c,0x3a,0x2c,0x68,0xfa,0x98,0x8b,0xa7,0x19,0x29,0x79,0xe4,0x9b,0xff,0x8f,0x15,0x9c,0x65,0x60,0xd2,0xa9,0x4f,0xd5,0xb2,0x57,0xff,0x32
+.byte 0x4c,0x96,0x82,0x6b,0x09,0x6c,0x74,0x55,0x00,0x5c,0x68,0x68,0xd5,0x9b,0xd4,0xdf,0x3d,0x2d,0xb9,0x0b,0xf5,0x2c,0x87,0x35,0x2a,0xc0,0xc0,0xc9,0xd7,0xa1,0x76,0x30,0x82,0x46,0xd8,0x24,0x6e,0x27,0x02,0x71,0x57,0x5c,0x43,0xf2,0x54,0xd6,0xea,0xd7,0x67,0x7d,0xac,0x76,0x91,0xf1,0x26,0x6e,0xaf,0x87,0x05,0x06,0x48,0x57,0xbd,0x67
+.byte 0x1d,0xd7,0x07,0xcd,0x41,0x02,0x49,0x6c,0x8c,0xe1,0xe3,0x00,0x78,0xbe,0x28,0x84,0x16,0x44,0xb1,0x0d,0x6d,0x40,0xfe,0xab,0x7e,0xf6,0x6b,0xff,0xfa,0xe1,0xc7,0x9d,0x56,0x62,0xf1,0x68,0xba,0x76,0x34,0x8f,0x54,0x20,0x49,0xf5,0xa2,0x54,0x52,0xca,0x42,0xed,0x4f,0x9b,0xdf,0xcf,0xfb,0xf6,0xee,0x12,0x29,0x43,0x8f,0xf9,0xfd,0xf4
+.byte 0x8a,0xbf,0xae,0x50,0xf2,0x8f,0x46,0xa2,0x97,0x3b,0x2d,0xfb,0x84,0x98,0x61,0xae,0xba,0x36,0x25,0x30,0x8b,0xdc,0xd3,0x08,0x8e,0x7e,0xfa,0x91,0xac,0x4b,0x29,0x6d,0x0c,0x81,0x0f,0xc7,0xc8,0xc4,0x5c,0x48,0x68,0xa7,0x83,0xf3,0x6a,0xc8,0x0d,0x3a,0x9b,0x46,0xb9,0xe1,0x31,0xac,0x3c,0x12,0xa2,0xae,0x74,0xb8,0x91,0xed,0x63,0xba
+.byte 0x40,0xb8,0x57,0x58,0x1f,0x1d,0x1a,0x2d,0x98,0x60,0xe8,0xe1,0x84,0x16,0xe5,0xf0,0x1e,0x35,0x58,0x31,0xc3,0x0c,0x49,0x6e,0x13,0x2c,0xac,0x14,0xc2,0xde,0x5f,0x62,0xe5,0x37,0x5b,0x1d,0x71,0x8b,0xc3,0x3d,0xd8,0xaf,0x3d,0x0a,0xef,0x80,0x3c,0x9a,0x4b,0x0a,0x3f,0x0e,0x8f,0x90,0x8f,0x73,0x2e,0xff,0x8e,0x8e,0x87,0xf8,0x46,0x52
+.byte 0xed,0x7d,0x76,0xf3,0xff,0xaf,0x5e,0x62,0x87,0x16,0x9c,0xa6,0x12,0x39,0x13,0xc3,0x62,0x4b,0xd2,0x21,0xa2,0x43,0xfa,0x4c,0x5d,0x75,0x61,0x64,0x5b,0x23,0xcd,0x76,0x86,0x81,0xd6,0xa6,0x25,0xe1,0xc1,0xc6,0x04,0x5e,0x65,0xfe,0x89,0x0e,0x67,0x02,0xeb,0xb9,0x26,0x88,0x81,0x97,0x1e,0x62,0x4e,0xf4,0x4e,0x0d,0xef,0xac,0xcf,0xd7
+.byte 0xc5,0x9b,0x9d,0x3a,0xa2,0x71,0xd7,0xd4,0x72,0xa6,0x66,0x90,0xe2,0xf7,0xb7,0xec,0xe4,0xca,0x9f,0xd1,0xd8,0x5a,0x65,0xff,0x39,0x65,0x78,0x47,0x1c,0x64,0xab,0x1a,0x35,0x2e,0xe2,0xf7,0x67,0xa4,0x7f,0xd5,0xea,0x04,0xee,0x4d,0xf6,0x29,0xe4,0xcd,0x1b,0xcf,0x0a,0xef,0xa1,0x14,0x90,0x0e,0xed,0x1a,0x10,0x63,0xa0,0x56,0x11,0x05
+.byte 0x57,0x94,0x3a,0x11,0xff,0xe0,0xc7,0x33,0x19,0x67,0xd7,0xd0,0xcc,0x76,0x52,0x5d,0x9e,0x10,0xe7,0xd6,0xaa,0x13,0xe8,0x8d,0xa5,0x60,0x66,0x98,0x26,0x11,0x66,0x0f,0x2d,0x4d,0xec,0x28,0x93,0x17,0x3a,0x6f,0x99,0x70,0x00,0x2b,0x66,0xb3,0x49,0x69,0x3c,0x3b,0x03,0xb8,0xc0,0x9b,0x1c,0x96,0xd9,0xd1,0xe1,0x6d,0x8f,0x45,0xce,0x22
+.byte 0xcf,0x48,0x61,0x85,0x10,0x1b,0x3f,0x2b,0x74,0x48,0x61,0x68,0x63,0xe3,0xa3,0x83,0xe2,0xcc,0xa0,0x6d,0x82,0x8b,0xe5,0x42,0xab,0xa7,0x62,0x6c,0x05,0xb4,0x7b,0x65,0xf5,0xd8,0x0b,0x7d,0x61,0xd6,0x5c,0xf0,0xc0,0x03,0x0c,0x51,0xec,0x06,0xad,0x79,0x8c,0x62,0x0c,0xf5,0x8e,0xcb,0x97,0x62,0xf9,0x3e,0x39,0x8d,0x3c,0x2e,0xd1,0xc0
+.byte 0x5f,0x98,0xea,0xb5,0x26,0x19,0xf5,0x93,0xbb,0xf8,0xd4,0xd5,0x35,0xee,0x1f,0xf8,0x71,0x81,0x0e,0xe6,0xe9,0xf3,0x2c,0x80,0xa8,0x15,0x35,0x1e,0xda,0x07,0x41,0x39,0x8a,0x19,0x1f,0x70,0x99,0xbe,0x3d,0x5c,0x1f,0xf6,0x72,0x85,0x73,0xea,0xb5,0x61,0xbb,0x77,0xaa,0xef,0xc7,0x2c,0xed,0x1e,0xa6,0xfd,0xc9,0xde,0xa9,0x82,0xba,0x19
+.byte 0x04,0x17,0xf7,0xa1,0x59,0x5c,0x7d,0x8d,0xe7,0x1c,0x89,0x7f,0xe1,0x02,0xd3,0xb0,0x46,0x6c,0xcf,0xde,0xf0,0x0b,0x00,0x43,0x8d,0xd6,0xe6,0xf7,0xc8,0x83,0x20,0x77,0x8b,0x9f,0x14,0xea,0x2b,0xb2,0xd2,0x41,0xfd,0x96,0x7c,0x0d,0x05,0xb9,0x5a,0xa0,0x83,0x50,0xde,0x0e,0xc6,0xa6,0x29,0x55,0x12,0x8e,0x2f,0x0a,0x5c,0xcd,0xae,0x92
+.byte 0x76,0x84,0xc9,0x8a,0x81,0xe5,0x3e,0xf0,0xe6,0x5b,0xe4,0x21,0xfb,0x4c,0xb6,0x0a,0x7b,0x7f,0x7e,0xab,0xdc,0x15,0x44,0xf8,0xeb,0x23,0x21,0x31,0xef,0x98,0xec,0x84,0x69,0x34,0x29,0x99,0x03,0x8a,0x12,0x8e,0x28,0xdd,0x00,0x6a,0xa3,0xe7,0x08,0x17,0x35,0x2a,0x42,0x8a,0xcb,0x4a,0x7b,0x1c,0xd2,0x74,0x4f,0x6a,0x8c,0x85,0x1c,0xd6
+.byte 0x05,0x3a,0xfd,0xdf,0x1c,0xa5,0x59,0xbb,0xdb,0xe3,0xa7,0x59,0xb1,0x67,0x3d,0xa4,0x71,0x4d,0x6c,0x99,0xe0,0xa7,0x8c,0xfa,0x96,0x1f,0x8d,0x0c,0xa7,0xc8,0xce,0xa3,0xbf,0x4d,0xc7,0xa9,0xb7,0xfd,0x04,0x58,0xcd,0xd7,0x20,0xb1,0xb9,0xf5,0x06,0x70,0x1b,0xdd,0xf4,0x1c,0xdc,0x32,0xa0,0x90,0x0d,0xb2,0x91,0x14,0x05,0xa2,0xf7,0xb7
+.byte 0xb6,0xd2,0xf1,0x30,0x75,0xcc,0x78,0x0d,0x56,0x70,0x64,0x02,0xe7,0x83,0x97,0x65,0x63,0x4b,0x64,0xff,0x8b,0x62,0xc9,0xa4,0x6e,0x96,0xbf,0xd3,0xeb,0x74,0xc5,0x1f,0xdb,0x1c,0xf3,0xca,0x54,0x7d,0x8d,0xd9,0xec,0x18,0xd8,0x99,0xd1,0xa5,0x70,0x8a,0xc5,0xdc,0xa0,0xcb,0xb7,0x52,0xe3,0xe6,0x88,0x0c,0x5a,0x42,0xde,0xe6,0xd8,0xc4
+.byte 0x39,0xe5,0x6c,0x0b,0xd4,0xa5,0x9b,0x51,0xa2,0x3d,0xc5,0xc7,0x17,0x17,0xb8,0xd8,0x09,0xad,0xeb,0x67,0x47,0xe0,0x88,0xef,0x1d,0x22,0x18,0x25,0xdc,0x32,0xb2,0xf7,0x47,0xc5,0xb3,0x0b,0x57,0x01,0x67,0xac,0xc3,0x9e,0xb0,0xa8,0xd7,0xce,0xb2,0xcd,0xea,0x3b,0x61,0xbb,0x24,0xad,0x91,0x7b,0xa2,0x9a,0xb3,0x63,0x56,0xe2,0x9d,0x69
+.byte 0x9e,0xd7,0x5f,0x5f,0x47,0x9f,0xae,0xf6,0x09,0xb1,0x9e,0x22,0x35,0xaa,0x55,0x0b,0xfc,0x70,0x96,0xfd,0x53,0x8a,0x37,0xaf,0x2d,0xa2,0xc5,0x49,0x5b,0x1e,0x32,0x47,0x9d,0xc3,0xb4,0x46,0xf3,0x54,0xdb,0x3f,0xb9,0x69,0x9e,0x8b,0xad,0x11,0xb2,0x68,0xe8,0x27,0x0d,0xca,0x33,0x1c,0x86,0xb2,0x2c,0xaa,0xc2,0x15,0xf9,0x6e,0xed,0x30
+.byte 0x71,0x08,0xeb,0x93,0x1d,0x16,0xc5,0x34,0x73,0x65,0x7a,0x19,0x2b,0xa7,0x3d,0xe6,0x88,0xb5,0x0f,0xa0,0x92,0x91,0x22,0x9d,0x01,0xf3,0xf4,0x57,0x9f,0xd9,0x23,0x1b,0xbd,0xd7,0xd5,0x11,0xc9,0x24,0xf6,0x36,0x30,0x30,0x69,0x95,0x17,0x48,0xf9,0x76,0x71,0xef,0xef,0xc0,0x00,0x9c,0x7d,0x87,0xdc,0xdc,0x1a,0x32,0x82,0x7a,0x13,0xc2
+.byte 0x9f,0x53,0xc2,0x7d,0x4d,0xbf,0xbe,0xf5,0x9d,0xc8,0x81,0x5b,0x81,0xe9,0x38,0xb6,0xa5,0x40,0xa5,0xd4,0x6f,0x0c,0xea,0xf1,0x52,0x59,0x37,0x3b,0xc2,0xb2,0x5f,0x10,0xdf,0x22,0xf7,0x77,0xe8,0x66,0xb0,0x97,0x91,0x5f,0xc2,0x18,0x8d,0x17,0x40,0xd1,0x6d,0xde,0x6e,0xf0,0x6c,0x1f,0x4e,0x9b,0x15,0x83,0x9b,0x70,0x21,0x2b,0x98,0x46
+.byte 0xbf,0xa5,0x82,0xac,0x63,0xac,0xd7,0x52,0xec,0x2c,0xf2,0xe4,0xe0,0x2a,0xbf,0x7e,0xa2,0xd2,0x9d,0x0d,0xf2,0x9b,0x79,0x5f,0x22,0xb0,0x6d,0x22,0x2e,0xed,0xe2,0x4f,0x73,0xc5,0x89,0xcc,0x4a,0xaa,0x9a,0x7e,0xab,0x95,0x25,0xa7,0x9d,0xf4,0xc2,0xe8,0x42,0x6e,0xd3,0xf9,0x25,0x54,0xb9,0x1f,0xa9,0x16,0x9c,0x22,0x7a,0xf0,0xa6,0xac
+.byte 0x8b,0x9d,0xe6,0xe3,0x93,0x4e,0x65,0x3a,0x39,0x3e,0xf5,0x41,0x38,0x02,0xb7,0x37,0xd4,0xdc,0xea,0xc5,0x53,0x0e,0x52,0x85,0x96,0xc0,0xa7,0x21,0xbf,0xe7,0xca,0x12,0x1c,0x59,0x33,0xe4,0xd5,0x70,0x6b,0x25,0x54,0x24,0x58,0x48,0x1b,0x65,0x6e,0x7e,0xe6,0x84,0x39,0x38,0xbc,0xdf,0x96,0xbc,0x39,0xdf,0x8f,0x36,0x9e,0x3a,0xda,0x02
+.byte 0x86,0xe2,0x9f,0xb7,0x3a,0xd0,0xdb,0xc2,0x5d,0xb0,0xde,0x31,0x73,0x43,0xe5,0x4b,0x6a,0xa1,0x6d,0xaa,0xca,0x34,0xfa,0xa9,0xaf,0xec,0x05,0x2a,0xdb,0x82,0xa1,0xdc,0xdc,0x3d,0xb5,0x92,0x42,0x28,0xdc,0x93,0xec,0xab,0x9b,0x75,0xae,0x7c,0xbf,0x9b,0x25,0x01,0xb1,0xc8,0x3b,0x47,0xb6,0xfd,0x11,0x6f,0x4b,0xaa,0x6f,0xdf,0x1f,0x15
+.byte 0xc2,0xf3,0x87,0x4a,0xaf,0xf7,0x41,0x64,0x5a,0x19,0xa0,0xc4,0x4f,0x58,0xe8,0x19,0xe0,0x84,0x44,0xc7,0x65,0x0c,0xf1,0xff,0xcb,0x73,0xb2,0xac,0x25,0x28,0xe1,0xd4,0x03,0x16,0x3c,0x1c,0x24,0x3a,0xfc,0x2b,0x7e,0xcb,0xa3,0xba,0xb7,0x78,0x87,0xbe,0x95,0x06,0x27,0xb8,0x16,0x72,0xe4,0x24,0xa6,0x5d,0xe7,0x5e,0x93,0xa9,0x96,0xfd
+.byte 0x01,0x1d,0xb8,0x7c,0x85,0x3c,0xe3,0xc9,0x56,0x68,0xcd,0xd9,0x79,0x97,0x50,0x39,0xfe,0x96,0x93,0x50,0xae,0xde,0xcd,0x8d,0xa0,0x38,0x31,0xba,0xca,0x21,0xff,0x19,0xea,0x44,0x95,0x4d,0xba,0xae,0xe2,0x62,0xd2,0x82,0x60,0x0c,0xb9,0x10,0x40,0x9a,0xaf,0x9b,0x17,0xcd,0xf3,0x26,0xec,0x38,0x13,0x18,0xd3,0xf2,0xd2,0x11,0xa6,0xc3
+.byte 0x3c,0x3b,0xe8,0xa0,0x49,0xba,0x4e,0x07,0xec,0x44,0x75,0x1c,0xc9,0x2f,0x68,0x64,0x02,0x1d,0x14,0x35,0x80,0xd8,0xa8,0x53,0xde,0x44,0x65,0x72,0x37,0x28,0x61,0x5f,0xa1,0x58,0xea,0x17,0xb3,0x89,0x25,0xf7,0xcb,0x87,0xe6,0x43,0xc5,0xc3,0xf3,0xd1,0xf5,0x1f,0x18,0xe9,0xd1,0x05,0xd9,0x85,0x38,0xf0,0x5e,0x26,0x35,0xf2,0x72,0x92
+.byte 0x34,0x2f,0xea,0xdd,0x7b,0x64,0xac,0x1d,0x78,0x41,0x56,0x83,0x7d,0x83,0x83,0x59,0xbe,0x9f,0x81,0x90,0x00,0x1f,0x04,0xd8,0xd8,0x8e,0xd9,0xeb,0x12,0x16,0x96,0x81,0x61,0x96,0xe8,0x7b,0x36,0x7b,0x26,0x9b,0x43,0x1e,0x0e,0xc2,0x59,0xdf,0x8f,0xb4,0x91,0x74,0x2e,0x1e,0x6d,0x20,0x70,0xe7,0x3c,0x39,0xe3,0xa8,0x62,0x66,0x32,0x63
+.byte 0x7d,0x89,0xb6,0xad,0x69,0x38,0x2c,0x21,0xe5,0x02,0xcc,0x93,0x8a,0x65,0x71,0x65,0x02,0x5c,0xeb,0xc9,0x70,0xf3,0x81,0xce,0x65,0x37,0x22,0xb7,0x47,0x3c,0xd6,0x3d,0x29,0x65,0x29,0xba,0xf9,0xae,0xd9,0x1f,0xd7,0x38,0x88,0x95,0xa9,0x66,0xa8,0x77,0x75,0x4a,0xf9,0x2e,0xd9,0x63,0x75,0x80,0x90,0x82,0x39,0x8b,0x21,0x58,0xf4,0x2e
+.byte 0x2d,0x1f,0x7f,0xcb,0x33,0xdb,0x9b,0x9b,0x31,0x21,0x4e,0x6e,0xdb,0x0f,0x1f,0x69,0x22,0x97,0x69,0xd7,0x7f,0x2e,0xd7,0xce,0x6c,0xe4,0xc0,0xe7,0x27,0x82,0xe6,0x8a,0xf8,0xae,0x46,0x2d,0x5a,0x45,0x82,0xce,0xb6,0x49,0x84,0x15,0x4a,0x54,0xa6,0x76,0xf3,0x29,0x28,0xc0,0x05,0x82,0xae,0x7d,0x85,0x41,0xb0,0x87,0x67,0x44,0x37,0x46
+.byte 0x3e,0x47,0xbc,0x00,0x7c,0x05,0xd3,0xdc,0x9a,0x31,0x49,0xf8,0x48,0x99,0x57,0x4a,0x2b,0xe7,0xcf,0xb2,0xa7,0xf0,0xcf,0xc7,0xf5,0xfd,0x73,0x59,0xf1,0xe4,0x86,0xb5,0x5d,0xce,0x6d,0xbf,0xc6,0xe5,0xa9,0xca,0x75,0xe9,0x69,0xe6,0x09,0xab,0x66,0x17,0x09,0xe9,0xbc,0x14,0xd8,0x6f,0xe9,0xc2,0x87,0x39,0x2f,0x87,0x1e,0xb8,0x16,0x08
+.byte 0x10,0xee,0x1c,0x2f,0x47,0x7d,0xa3,0x5b,0x1f,0x1f,0x5d,0x95,0xd0,0xa4,0xbb,0x08,0xc2,0x47,0xab,0x46,0x3c,0xbb,0xbe,0x3a,0x64,0x82,0x40,0x08,0x75,0x03,0x02,0x6e,0x6a,0xab,0x6b,0xd4,0x90,0xa7,0x28,0x7a,0xb4,0x8b,0x1f,0x6b,0xcc,0x16,0x30,0x16,0xf5,0xc6,0xd8,0x4a,0xed,0xc9,0xc7,0xac,0x0f,0x75,0x1b,0x13,0xe3,0x45,0x6d,0x22
+.byte 0x7e,0x3d,0x59,0x55,0x87,0x8d,0x04,0xee,0x85,0xac,0x98,0x0c,0x52,0x5b,0xe6,0x92,0x04,0x31,0xdf,0x7c,0x44,0x4d,0x06,0xbe,0xb2,0x5a,0x95,0xef,0x29,0x75,0x9b,0xb2,0xe7,0xb8,0x83,0x18,0x82,0x23,0x4e,0x66,0xe5,0xdd,0x47,0xa1,0x6b,0x33,0x4e,0x9c,0x13,0x0e,0x0a,0x8a,0x5c,0xba,0x7b,0x2f,0x6c,0x72,0x78,0x86,0xd2,0xf8,0xbd,0x1b
+.byte 0x4b,0x9e,0xe0,0x99,0x46,0x7f,0x24,0x0f,0x1b,0xda,0x85,0x87,0xe9,0xda,0x96,0x25,0xc6,0x81,0x77,0x8b,0x56,0xae,0x7a,0x9c,0x47,0x34,0xe1,0xac,0xf2,0xba,0x52,0x95,0xf8,0x56,0x26,0x66,0xf0,0x53,0xcc,0xc4,0x6f,0x46,0x94,0x10,0x22,0x69,0xb1,0x93,0x7b,0x51,0xb7,0xb8,0xdd,0x42,0x67,0x51,0x6d,0x9c,0xb2,0xbd,0xdb,0xdd,0x19,0xa2
+.byte 0x25,0x13,0xfe,0x42,0xca,0x36,0xeb,0xce,0x15,0x41,0xe7,0x35,0xce,0xa8,0x45,0x56,0x58,0x9f,0x46,0xcf,0x11,0xe7,0xcc,0x40,0x54,0xe4,0x85,0x0d,0x73,0x36,0x7e,0xae,0x38,0x8c,0x56,0xab,0xf0,0x5f,0x5c,0xff,0x14,0x9b,0x46,0x1b,0x35,0xbd,0x03,0x0e,0x2f,0x9e,0xde,0xd8,0x82,0xfe,0xa0,0x09,0xb4,0xb4,0xbd,0x58,0xc0,0xe2,0x01,0xb1
+.byte 0xca,0x5c,0x3d,0xc3,0x18,0x5e,0xc1,0xee,0x61,0x60,0x00,0xca,0x1e,0xf3,0x71,0xd8,0x15,0x37,0xf0,0x2e,0x13,0xa0,0xf7,0xac,0x73,0x4b,0xfb,0x6a,0x27,0x6b,0xde,0x69,0x3d,0x19,0x36,0x4b,0x63,0x55,0xae,0xd1,0x2b,0x66,0x69,0x0d,0x64,0xa7,0x86,0xfd,0x3a,0xb8,0xe6,0x87,0xaa,0x32,0x5f,0xbc,0xa7,0x67,0xde,0x7a,0xe0,0xdd,0xff,0x57
+.byte 0x2c,0xc9,0x25,0x92,0x03,0x91,0xa8,0x0e,0x39,0xe4,0x9a,0xdf,0x21,0x29,0xc7,0xbc,0x93,0x01,0x2a,0x02,0xd8,0xaf,0xbc,0x20,0x57,0xc7,0x37,0x77,0xa7,0xad,0x5e,0x15,0x20,0xcf,0x4a,0x3c,0x22,0x1b,0x92,0xa9,0x05,0x91,0x70,0xb3,0x88,0x4e,0x97,0x58,0xf7,0x33,0x1a,0x05,0x33,0x57,0xdc,0xbb,0x2a,0xba,0xd0,0x22,0xac,0x40,0xbe,0x60
+.byte 0xa2,0x89,0xe6,0x6c,0xf3,0x5d,0xef,0x58,0xb4,0x7c,0x4a,0x28,0xb8,0x16,0xd2,0xe0,0x49,0xf5,0xe8,0xaf,0x84,0x39,0xae,0x1e,0xa2,0x34,0x67,0x42,0x26,0x31,0x93,0x87,0x7a,0xd5,0xde,0x79,0xdb,0x4c,0x7e,0xcf,0x1f,0xef,0x9a,0x4c,0xb9,0x70,0xe2,0x72,0x9b,0xcd,0x30,0xe5,0xf1,0x84,0x44,0x5a,0xff,0x36,0xa2,0x37,0xe7,0x49,0x78,0x63
+.byte 0xbe,0xe0,0x90,0xdf,0xef,0x9e,0xf3,0x55,0x9e,0x8a,0x51,0xe8,0xa3,0x32,0x2d,0xed,0xc8,0x99,0xf6,0x92,0xf9,0x62,0x74,0xa7,0x8d,0xcf,0xa5,0x09,0xb3,0x43,0xb9,0x18,0x70,0x59,0x4f,0xd2,0x7f,0x7e,0xce,0x1e,0x7d,0xe8,0xa9,0xb7,0x29,0x0f,0x86,0x8a,0xac,0x22,0x41,0x98,0xb2,0xc3,0x48,0x3b,0x60,0xcb,0x7b,0x1d,0xc3,0x5e,0x19,0x5b
+.byte 0x31,0x57,0x12,0x09,0x41,0x54,0xf8,0x01,0x70,0x02,0x03,0x8a,0x6e,0x8e,0x5b,0x23,0xf3,0xd4,0x13,0xbf,0x51,0xba,0xf9,0x2d,0x6c,0xb9,0xb3,0x90,0xd0,0xa3,0x76,0xfb,0xef,0x85,0x17,0x8b,0x2c,0x05,0xa3,0x06,0x0a,0xaa,0xdd,0xbf,0xd4,0xcc,0xe4,0x96,0x19,0x7f,0x51,0xf6,0x7e,0xa1,0x2c,0x14,0x1c,0x21,0x99,0x28,0x3a,0x0e,0x36,0x1b
+.byte 0xf1,0xd7,0x3e,0x29,0x94,0xa6,0x03,0xf7,0xe5,0x6f,0x1b,0x56,0xc8,0xfb,0x2d,0x4f,0x12,0x2b,0xc7,0x3a,0xec,0x5e,0xc8,0x88,0x1b,0xd8,0x65,0x21,0x04,0x0e,0xe2,0x95,0x6d,0x62,0xea,0xeb,0xee,0xbe,0x47,0x0a,0x90,0x26,0xe3,0x85,0xd7,0x1d,0xb5,0xd5,0x56,0x8b,0xc0,0x2f,0x7f,0x01,0xc8,0xac,0x90,0xc3,0x2d,0x10,0xf2,0x11,0x30,0x0c
+.byte 0xa9,0x4d,0x13,0xde,0x65,0x6d,0x34,0x68,0x5d,0xad,0x3f,0x7a,0x56,0x3a,0x1f,0xb9,0xd6,0x7b,0x8f,0xe8,0x42,0x2a,0x16,0xb6,0x3f,0xf2,0x4f,0x14,0x8e,0x8e,0x29,0x88,0x68,0x1b,0x10,0x80,0x80,0x47,0x36,0xaa,0x82,0xf5,0xa8,0x97,0xc4,0xcb,0xc2,0xef,0xaa,0x9f,0xdc,0x96,0x4f,0x1f,0xaf,0x39,0x71,0x55,0x8f,0x3c,0xbf,0x26,0x91,0x46
+.byte 0x38,0x59,0xa7,0xd1,0xb5,0x87,0xd6,0x81,0x71,0x17,0x83,0x05,0x40,0x9c,0xf3,0x33,0x4b,0x09,0x06,0xb1,0x69,0xfb,0x43,0x1f,0xef,0x9a,0xfe,0xc3,0x4e,0x4e,0x25,0xe1,0x3a,0xfb,0xf9,0xc9,0x97,0xe2,0x1c,0xa1,0x9a,0x06,0x6e,0xbb,0x16,0x4a,0x9f,0xf4,0x87,0x31,0x38,0x78,0xae,0x77,0x4c,0x42,0x28,0xc4,0x63,0xc0,0x49,0x37,0x4f,0xf9
+.byte 0xeb,0x31,0x0d,0x3e,0x0c,0x8a,0xb7,0x17,0xa7,0x90,0x26,0xc2,0xea,0xa5,0x9d,0xe4,0x4d,0xc6,0x3a,0x33,0x2d,0x47,0x42,0x8c,0xeb,0x50,0xea,0xfe,0x74,0x43,0x06,0xcd,0xa5,0xb1,0x49,0xf0,0x98,0x91,0x25,0xf4,0x8d,0x06,0xd1,0xeb,0x56,0x2c,0xf9,0xc4,0x84,0x02,0x9e,0xf2,0x3a,0xfe,0xb4,0x39,0xce,0xee,0x85,0xb6,0x64,0x6c,0xbc,0x1f
+.byte 0xe6,0x86,0x00,0xc3,0xa9,0xb4,0x53,0xdf,0x2d,0x7c,0xc6,0xde,0x2e,0x79,0x25,0x5c,0xbb,0xe5,0xbe,0x33,0xe9,0x58,0x49,0x35,0xbe,0xae,0xbc,0x06,0xdc,0x48,0x9d,0xc3,0x08,0x6f,0xe8,0xb8,0x48,0x67,0xea,0x1c,0x05,0xb4,0xf7,0xe3,0xcc,0xc1,0xb3,0xa8,0x61,0xcb,0xa8,0xf6,0x12,0x52,0x68,0x06,0x36,0x2b,0x15,0x43,0xc9,0x98,0xfe,0xe5
+.byte 0x43,0x11,0x0d,0xc3,0x37,0x38,0x7a,0xcb,0x98,0x14,0xc1,0xaf,0x29,0x36,0x35,0x63,0x74,0x98,0xcf,0x0f,0x44,0xe4,0x6e,0xf7,0x3f,0x6e,0x15,0xe8,0xe9,0x93,0x7b,0x96,0x1b,0x84,0xe7,0x8b,0x83,0x30,0xa1,0xdc,0xc3,0xb8,0x18,0x2f,0xc5,0x34,0xd1,0xa5,0xb9,0xee,0x4a,0x04,0xbf,0x26,0x63,0x29,0xba,0x90,0xb5,0x7c,0x83,0x2b,0x1f,0xe8
+.byte 0x5c,0x9f,0x23,0x40,0x7f,0x9c,0x2f,0x76,0x96,0xd6,0xd5,0x13,0xda,0x5c,0x81,0xa4,0x60,0x60,0xbd,0x5e,0xb3,0xd2,0x2c,0xaa,0x48,0x04,0x74,0x31,0x5d,0xbd,0x46,0xd8,0x8d,0x3f,0x62,0x2d,0x1e,0x17,0x97,0x08,0x71,0x06,0x1b,0x96,0x1b,0xd5,0x80,0xa6,0x41,0x06,0x10,0x6e,0x36,0xd4,0xfb,0x36,0x6d,0x96,0xb8,0x86,0x22,0x34,0xda,0x7e
+.byte 0x6c,0x5f,0x3b,0x95,0x35,0x1b,0x42,0x3c,0xf2,0x9d,0xe3,0xe9,0x3f,0x44,0xd5,0x4c,0x60,0x55,0xae,0xbe,0x4f,0xf2,0xb3,0x84,0xa1,0x79,0xdf,0x86,0xf0,0x8f,0xad,0xa5,0xa3,0x4a,0xea,0x5d,0x68,0x34,0x17,0x4c,0xb7,0xd8,0x6f,0x67,0x22,0x85,0xe2,0x16,0xcf,0xba,0xee,0x92,0xeb,0x95,0x8e,0x67,0xb1,0xf0,0xbb,0xb0,0x34,0x2f,0x58,0x49
+.byte 0x56,0x3e,0x81,0x31,0xb6,0xc3,0x2c,0xee,0x2b,0x85,0x72,0xbc,0xe9,0x20,0xaa,0x4e,0x34,0xb9,0x8b,0x32,0x2f,0x9e,0xd7,0x98,0x63,0x9d,0xfd,0x3a,0xe9,0x30,0x49,0x23,0x4a,0xb4,0xcb,0xc5,0xe5,0x78,0xcd,0x22,0x90,0xce,0x9f,0x35,0x13,0xda,0x8f,0x14,0xdb,0x36,0x0f,0x66,0x87,0x62,0x50,0xde,0x52,0x15,0x10,0x67,0x8a,0x5c,0xdb,0x76
+.byte 0x51,0x7f,0x72,0x9b,0x8e,0x91,0x39,0xc8,0x3c,0x34,0x0f,0x3d,0x92,0x07,0xb8,0xef,0x2a,0x8b,0x59,0xbd,0x82,0xc1,0x5c,0x95,0x93,0x0d,0x3d,0x9b,0x51,0x53,0x38,0x6b,0xd0,0xe3,0x5b,0xbb,0xe5,0x6c,0xc0,0xb5,0x71,0xa8,0xd8,0x7d,0x5d,0xbd,0xfc,0x69,0xcf,0xcc,0xa1,0xcd,0x83,0x9d,0x8f,0x46,0x47,0xe7,0x36,0x19,0x9f,0x4d,0xda,0x9c
+.byte 0xcb,0x2a,0x47,0x58,0x93,0xbb,0x64,0xa3,0x89,0x53,0xbf,0xc7,0xc2,0xe2,0x65,0x0f,0x4f,0x17,0xc6,0x4c,0x15,0xfe,0x4b,0x95,0xb2,0x79,0x4a,0xb8,0xf6,0xae,0xcc,0xba,0xc3,0x5d,0x18,0xb2,0x8e,0xd8,0x6b,0x43,0x1b,0x2f,0xe1,0x36,0xb2,0xa5,0x22,0xa0,0xc7,0xc0,0x26,0x8e,0x48,0x77,0x0c,0x14,0xdd,0xdc,0xde,0x71,0x98,0xce,0xdd,0x61
+.byte 0x85,0xd9,0x23,0x42,0x7f,0x85,0xc8,0x06,0x81,0x3e,0xa2,0x0f,0x1e,0x3e,0xcf,0x33,0xef,0x43,0x6a,0xc7,0xee,0x3f,0x91,0x68,0x32,0x89,0xd9,0xed,0xdf,0x45,0x33,0x10,0xbb,0xd5,0xef,0x1d,0x3c,0x1e,0x26,0x21,0x4d,0x1a,0x06,0x98,0x60,0x71,0x7f,0xce,0x45,0x4e,0xe3,0x3f,0xfa,0xff,0xcd,0xe2,0x92,0x82,0x2e,0x83,0x69,0x9c,0xc6,0x5c
+.byte 0x6e,0xb6,0xec,0x28,0xdc,0x7b,0xdb,0xf3,0x02,0x3a,0xf7,0xad,0x9b,0x7a,0x73,0xb2,0x07,0x70,0x76,0x9d,0xa2,0x11,0xcf,0x89,0xea,0xaf,0x6a,0xd2,0x15,0xeb,0x5a,0x99,0x1a,0x17,0x1d,0xce,0xc0,0x7f,0x50,0x26,0x84,0x07,0xd7,0x7e,0x33,0x27,0x74,0x84,0x18,0x32,0x86,0x32,0x34,0x28,0xe8,0x45,0x21,0xb7,0x26,0x3b,0x11,0xbb,0x9a,0x8b
+.byte 0x46,0x8e,0x27,0xf8,0x62,0xb5,0x98,0x6e,0x03,0xee,0x9e,0xcb,0xbc,0x74,0xbe,0x63,0x7a,0x86,0xe5,0x75,0xeb,0x7f,0x14,0xa6,0x96,0x76,0x5a,0x46,0xa9,0xda,0xf1,0x4e,0x0e,0x90,0x59,0x56,0x4a,0x48,0x2d,0x91,0xbe,0x78,0x5b,0xfb,0xf7,0xea,0xab,0x1c,0xc0,0x0c,0x5d,0xba,0xb4,0x7b,0xc7,0x21,0xb1,0xc9,0xa3,0x20,0xe6,0xae,0xee,0x0e
+.byte 0xf0,0x3b,0x44,0xd6,0xaa,0x57,0x88,0x1f,0x76,0xc8,0x43,0x07,0x91,0x71,0xa5,0xcc,0x04,0x38,0x01,0x13,0xa6,0xea,0x18,0x48,0x8f,0x09,0x8d,0x37,0x8b,0x6f,0x35,0x36,0x51,0xc6,0x30,0xca,0x9e,0xe2,0xaf,0x0c,0x26,0x14,0xe3,0xbf,0xea,0x0e,0x14,0x88,0x97,0xcc,0xf6,0xc1,0x8f,0xad,0xef,0x2d,0xc1,0x0f,0xad,0x45,0x12,0x7a,0xe6,0x37
+.byte 0x97,0xcb,0x34,0x83,0xd8,0xef,0x34,0x2a,0xce,0xd0,0x21,0x8a,0x7d,0x87,0x7a,0x66,0xf7,0x1c,0xdf,0xa0,0x3f,0xa0,0xf6,0xb3,0x24,0xee,0x6e,0x21,0xe9,0xc3,0x73,0xe4,0xd9,0xc6,0xf6,0xf6,0xac,0x25,0xb7,0xb5,0x64,0x7f,0xcc,0x88,0x3e,0x98,0xe1,0xef,0xa9,0xd2,0x03,0x10,0x4b,0xa3,0xbc,0x3c,0x24,0xfc,0x41,0x36,0x30,0x2d,0xca,0x17
+.byte 0x35,0xd6,0x17,0xa2,0x2b,0x48,0xed,0xd3,0xd7,0x18,0x4f,0x45,0xe9,0x59,0x03,0x35,0xa0,0x80,0x75,0x17,0x48,0xd5,0xea,0x07,0x7a,0x6c,0x3f,0x7a,0x2c,0x02,0x0a,0x7f,0xb5,0x17,0xea,0xf4,0xf6,0xb5,0xf4,0x81,0xba,0x69,0x44,0x81,0x6b,0xff,0xb2,0x43,0xae,0x3d,0x37,0x81,0x91,0x3f,0x6a,0x70,0x35,0x2d,0x06,0x9d,0xa8,0xb5,0xb8,0xc7
+.byte 0x19,0x3a,0x5f,0x59,0x79,0x0b,0x62,0x23,0xa4,0x5b,0x46,0x7b,0x17,0x82,0x19,0x87,0xe8,0xdf,0x09,0xb7,0x50,0x7e,0x40,0xe3,0x71,0x2d,0x09,0xde,0x69,0x2e,0x6c,0x35,0x5c,0x44,0xae,0xb7,0x05,0xb8,0x7e,0xb4,0xe4,0x34,0x05,0x1f,0xd2,0x1f,0xe5,0x79,0x2a,0x15,0xf8,0x8f,0x02,0xc7,0xc8,0x1e,0xe6,0x12,0x83,0x08,0x9c,0x7a,0x2f,0xc6
+.byte 0xc9,0x15,0x0f,0x0f,0x0f,0xa9,0x53,0x16,0x19,0x5b,0x74,0x58,0x6c,0xac,0x21,0x72,0x7f,0xa1,0xae,0xbc,0x34,0x76,0xa6,0x9b,0xbe,0x0f,0x13,0x55,0x50,0x5a,0x8b,0x9e,0xb3,0xf3,0x9e,0x8b,0x61,0xbe,0xb4,0x09,0x71,0x61,0xf0,0xd6,0xaa,0x8c,0x0d,0x0c,0x66,0x31,0x88,0xe3,0x71,0x6a,0xb5,0xaa,0xc0,0x9b,0xce,0x0d,0x79,0x90,0xc1,0x0a
+.byte 0xf9,0xfe,0x4d,0x49,0xd0,0x5a,0x63,0xf1,0xfc,0x47,0x71,0x9e,0xbb,0xd1,0x2c,0xef,0xfe,0x90,0x28,0x75,0x82,0xf6,0xa5,0x95,0xea,0x65,0xfa,0xe8,0x04,0xcd,0xb4,0xe1,0x0d,0xb2,0xac,0xd5,0x12,0xf5,0x17,0xbb,0x3b,0x2e,0x52,0x9e,0x7b,0xe7,0x8e,0x86,0x03,0xce,0x77,0x01,0xf0,0x4f,0xb5,0xf7,0xef,0x8b,0x37,0x5e,0x97,0x80,0xbb,0x2b
+.byte 0xcf,0x9a,0x63,0x18,0xc5,0x0c,0xfb,0x3c,0x91,0x9c,0x37,0x90,0x76,0x71,0x62,0xbc,0x80,0x40,0x1a,0x74,0xb8,0x1b,0x61,0xb1,0x89,0x4d,0xf7,0x8d,0xd4,0x46,0xef,0x1f,0x3b,0xac,0xe8,0x41,0x62,0x8e,0xea,0x2b,0x56,0x22,0x25,0x37,0x70,0x53,0xcd,0x8f,0x57,0xfa,0xad,0x00,0xc5,0x0c,0x9e,0x57,0xde,0x50,0x07,0x8d,0x80,0xbf,0x22,0x5d
+.byte 0x4a,0xbd,0x6a,0xcb,0xfc,0x6f,0xd1,0x56,0x8f,0xd5,0x34,0x8a,0xe6,0xe9,0xa0,0x00,0x06,0x12,0xd8,0xb1,0x49,0x0a,0xbb,0x87,0xe5,0xca,0x75,0x11,0x4c,0x85,0x60,0x77,0xc0,0x90,0x1c,0x14,0x38,0x38,0x3e,0x4f,0xff,0xbf,0xfc,0xa1,0xa1,0xe7,0xb0,0x5d,0xd8,0x1f,0x33,0x07,0x5f,0x04,0x4f,0xc7,0x93,0xc6,0xcc,0xe3,0x01,0xd0,0x43,0xe1
+.byte 0xd9,0x00,0xc5,0x9f,0x79,0xab,0xfc,0xe9,0x55,0x51,0x03,0x0c,0xe1,0x73,0xd6,0x09,0xe3,0xb9,0x76,0x72,0x77,0x4c,0x1b,0x7c,0x57,0x1e,0x7f,0x5f,0x02,0x83,0xa3,0xc6,0xde,0x23,0x85,0x76,0x1a,0xbf,0x48,0xc8,0x02,0xdb,0x31,0x30,0x95,0x85,0x68,0x8a,0xf6,0xe9,0x48,0x7f,0xc9,0x26,0xab,0x68,0x36,0x9f,0x1c,0xf0,0x90,0xbc,0x4a,0x68
+.byte 0x94,0xf8,0x7f,0xae,0xa9,0x3b,0x5b,0x63,0x9a,0xcd,0xe3,0xf0,0xac,0x9f,0x6f,0x78,0xa0,0x67,0x58,0xd8,0x2c,0x71,0x8a,0x14,0x31,0x07,0x95,0x0c,0x38,0xa4,0x53,0x33,0x60,0x23,0x21,0x87,0x6b,0x4f,0xf9,0xa8,0xb8,0xfc,0x8e,0xf1,0x3a,0x03,0x0b,0x03,0x02,0x33,0xbc,0x6a,0xb9,0x8e,0x41,0xc8,0x38,0xd8,0x83,0x30,0x6a,0x61,0x5c,0xcf
+.byte 0x49,0xdd,0xd7,0xda,0x2c,0xaf,0xc4,0x68,0xad,0x07,0x9c,0xd4,0xaf,0x94,0x64,0xcf,0xe1,0x9b,0x37,0x50,0x65,0x03,0x20,0x3c,0x34,0x43,0xe9,0xb0,0x9b,0xba,0xb1,0x9a,0x3e,0x10,0x99,0x8f,0x93,0xb7,0x3d,0xac,0xbd,0xab,0xa8,0xfa,0x74,0x90,0xe1,0x38,0xe4,0xf3,0x47,0xfc,0xad,0x8b,0xb4,0x98,0xe4,0x65,0xe9,0xd9,0x8a,0x21,0x81,0x4f
+.byte 0x0c,0xd7,0xb1,0x84,0xb9,0x69,0x68,0x64,0xa3,0x1f,0x25,0x84,0x5f,0xf7,0x3f,0xca,0x52,0xff,0xda,0xc9,0x3d,0x5e,0x8b,0x57,0xd3,0x9a,0x1d,0xb7,0xae,0x90,0xa4,0xc3,0x78,0x68,0xfd,0x80,0x3f,0xfd,0x5c,0x09,0x83,0x5d,0xc2,0x48,0xd8,0x84,0xeb,0x8a,0xfe,0xbe,0x30,0x12,0x79,0x54,0x5f,0x7f,0x6e,0x4b,0x8a,0x1e,0xcb,0xcd,0xed,0xb6
+.byte 0xe9,0x6d,0x8a,0x1f,0xdc,0xb1,0x46,0xab,0xdc,0x0d,0xbf,0xda,0xd9,0x39,0x3b,0xd2,0x81,0x00,0x83,0x77,0x32,0xf7,0xdf,0x0e,0x31,0x5d,0x1d,0x6c,0xa7,0x4e,0x54,0xa8,0xac,0x81,0x8c,0xb6,0xa5,0x89,0x02,0xd7,0x2e,0xfd,0x26,0xa3,0x9e,0xcf,0xdb,0x1f,0x5a,0xf3,0x54,0xac,0xe5,0xd0,0x1f,0x9b,0xa7,0xab,0x28,0xcc,0x66,0xd3,0xbc,0x4c
+.byte 0x54,0x1a,0x54,0x73,0x78,0xde,0x08,0xd5,0xa5,0x08,0xdc,0x00,0x09,0xc5,0x37,0x61,0x1a,0x98,0x12,0x84,0x2d,0xff,0xc3,0x25,0x62,0x93,0x83,0x05,0x66,0x3d,0xfb,0x1d,0x54,0x08,0x8a,0x50,0x03,0xc4,0xc4,0x6e,0xfa,0x16,0x83,0xbb,0x27,0xf1,0xb7,0x31,0x92,0x64,0x76,0xbc,0xf0,0x44,0x62,0xe9,0x5e,0x15,0x94,0xdc,0xe9,0xf3,0xf8,0x20
+.byte 0x93,0x4d,0x11,0xa2,0xc8,0xde,0x83,0xe6,0x75,0x63,0xfe,0x13,0x75,0x0f,0x79,0xd1,0x3d,0x75,0xb7,0x43,0x62,0x57,0x8d,0x96,0x9c,0xa3,0xc4,0xb2,0x84,0x6a,0x14,0x6e,0x17,0x32,0x09,0x76,0x95,0xbb,0xd6,0xc1,0x2e,0xdc,0x8c,0x73,0xd7,0xad,0x5a,0x41,0x8b,0xb3,0x7e,0x8d,0x90,0xec,0xf5,0xa0,0x46,0x90,0x4c,0x52,0xec,0x97,0xc6,0x98
+.byte 0x7d,0x19,0x77,0xa0,0x99,0x85,0x11,0x26,0x77,0x26,0xf9,0xac,0xe3,0x81,0xcf,0x7d,0x22,0xc8,0x00,0x3d,0x5b,0xee,0xa5,0xf8,0x6d,0xfe,0x47,0xe4,0xef,0x60,0xcc,0xd0,0x33,0xf7,0x5b,0xed,0xbd,0x82,0xc9,0xa8,0x41,0xb8,0x47,0x34,0x9f,0x62,0xb2,0x67,0x62,0xb0,0x3a,0x27,0x95,0xe1,0x22,0x76,0x98,0x0f,0x35,0xaf,0xfc,0x4d,0xc7,0x92
+.byte 0x92,0x7e,0xaf,0x3b,0x3a,0x36,0x5e,0x5c,0xbf,0x43,0x02,0x66,0x5a,0x30,0x78,0x82,0x52,0x20,0x98,0xd6,0xa1,0xe9,0x9a,0x61,0x54,0x0b,0x74,0x85,0xb5,0x99,0x69,0x9f,0x9b,0x3b,0x2f,0x49,0xec,0xb3,0x18,0x0c,0x4a,0x53,0x20,0xd7,0x80,0x7b,0xd4,0x20,0x21,0x32,0x89,0x08,0x81,0x50,0x2b,0x16,0x8d,0xbb,0xe6,0xbb,0xc7,0x74,0x80,0x67
+.byte 0x47,0xf1,0x06,0x68,0x02,0x37,0x31,0x00,0x50,0x8b,0xe2,0x44,0x85,0x2e,0x39,0x54,0xda,0x26,0x7b,0xe1,0xb0,0x23,0xd7,0x0c,0x3c,0x3b,0x81,0x9b,0xa6,0xbe,0x24,0xfd,0x09,0x73,0xbe,0xc3,0x2f,0xa0,0x7b,0x85,0x5b,0x1b,0x55,0x4e,0x9e,0x38,0x80,0x61,0xd7,0xe8,0x9b,0xec,0x88,0x00,0x6a,0x64,0x1b,0xd5,0x65,0x20,0x2a,0x62,0x64,0xbc
+.byte 0x21,0xca,0xce,0xc3,0xeb,0x2d,0x2b,0x5c,0x4d,0xb8,0x7c,0xb5,0xbe,0x98,0x0d,0x5b,0x88,0x23,0x60,0xff,0xbe,0x0a,0xb6,0xdd,0xdf,0x28,0xd5,0x2c,0xe5,0x9d,0xb5,0x29,0xea,0x6c,0x3a,0xf4,0x78,0x91,0xa3,0xb2,0xab,0x12,0xf9,0x90,0x96,0xc9,0xa4,0xfc,0x4d,0x28,0x2b,0x0c,0x28,0x8b,0xb7,0x8b,0x36,0xd6,0x80,0xbf,0x07,0x09,0xf9,0x62
+.byte 0x32,0xc0,0x50,0x60,0xd9,0x73,0xe3,0xbe,0xfa,0xa6,0x78,0x48,0x47,0xd7,0xb5,0x39,0xd8,0x04,0x6d,0x79,0x98,0x2e,0xd6,0x3a,0xe5,0xc9,0x01,0xd0,0x00,0x2e,0xd2,0x8b,0xd7,0x1f,0xf1,0xba,0xd4,0x0e,0x9f,0x9d,0xab,0xbf,0x2c,0xe1,0x75,0xf6,0x9c,0xc0,0xae,0x73,0x2b,0x58,0xcb,0x6d,0x46,0x6d,0x11,0xb7,0xce,0xc7,0xef,0x34,0x2c,0x11
+.byte 0x93,0x3c,0x17,0xd9,0x3e,0xad,0xc9,0x4c,0xb3,0xd0,0x0a,0xd0,0xfe,0xf3,0x9d,0xc5,0x43,0x03,0xa9,0x78,0x4a,0x42,0x7f,0xfb,0x75,0xd2,0x85,0xfb,0xe7,0xe6,0xa9,0x48,0x2f,0xa6,0xc3,0x16,0xe2,0x2a,0x9d,0x0d,0xcb,0x2e,0x8b,0x75,0xa8,0x14,0x3a,0x2e,0xb1,0xff,0x58,0x1d,0xa8,0xa6,0xc0,0xf6,0x17,0xda,0xc1,0xce,0xaf,0x08,0xa9,0xc2
+.byte 0xa3,0xc1,0xab,0xb6,0xe8,0x10,0x57,0x8a,0xce,0xc0,0x03,0x5c,0x53,0x5c,0x02,0x5d,0xcf,0x5c,0x65,0xc6,0x47,0x3c,0x62,0x0e,0xa3,0xfc,0xe2,0xae,0x10,0x55,0x4a,0xb4,0x27,0xe8,0x59,0x5e,0x45,0xa9,0xbb,0x21,0x10,0x91,0x46,0x1f,0x50,0x3b,0xc6,0x8c,0xa1,0x8a,0xee,0x5e,0x6e,0x32,0xe6,0x42,0x40,0x79,0x7f,0xbb,0xb3,0x5b,0x05,0xde
+.byte 0xe0,0xf6,0x7f,0x3d,0x37,0xe6,0xc3,0x3b,0x40,0xc9,0xe0,0x42,0x36,0xd0,0x0e,0x13,0x32,0x3e,0x48,0xce,0xd8,0xa2,0xef,0xae,0x93,0x66,0x7d,0xde,0xb9,0xdd,0x60,0x15,0x53,0xf2,0xd9,0x90,0x3d,0x38,0x8c,0xa6,0x34,0x44,0xb5,0x6c,0x74,0x7d,0x9d,0xe7,0xd0,0xef,0x6c,0xd6,0xfe,0x9b,0x79,0x4e,0x79,0x5e,0x48,0xef,0x93,0xb2,0x81,0x0b
+.byte 0x2b,0xee,0x83,0x69,0x3d,0x15,0x8c,0x27,0x69,0x6f,0xca,0xbf,0x75,0x29,0x37,0xc6,0xe6,0xca,0xb2,0x70,0xd0,0xaf,0xc8,0x5e,0x69,0xf1,0x6b,0x2d,0x0d,0xe7,0xe9,0xbf,0x07,0x52,0xe5,0xac,0x98,0xcf,0xcf,0xd6,0xdd,0x7c,0x2b,0xfc,0x8f,0xd2,0x5f,0x81,0x4b,0x1b,0x7b,0x2d,0x84,0xe2,0x69,0x96,0xcb,0xa2,0x59,0x10,0xba,0xda,0x51,0x11
+.byte 0xeb,0xc3,0x4f,0x10,0xbf,0x8e,0x5b,0xbb,0xa3,0x29,0xe9,0xd8,0x0e,0x71,0xa0,0x1b,0xff,0xee,0x36,0x8c,0x00,0x83,0x6b,0x32,0xfe,0x05,0xeb,0x89,0x8f,0xed,0x48,0x22,0xe1,0x76,0x0a,0xac,0xae,0x3c,0x24,0x54,0x84,0xc2,0x0f,0x79,0x33,0x2b,0x49,0x35,0x1c,0x84,0x5a,0xca,0x92,0x6c,0x1f,0x78,0x15,0x5a,0x36,0xad,0xd5,0x1d,0x9d,0x10
+.byte 0xc1,0x5f,0x7c,0x61,0x60,0xba,0x2e,0xe6,0x9b,0x34,0x02,0xe9,0x68,0x1c,0xfb,0xbf,0x02,0xdc,0x79,0x57,0x1c,0x0f,0xc8,0x8c,0x2a,0x66,0x2a,0x50,0xaa,0x81,0x4e,0x1f,0xa8,0x2d,0xe4,0x61,0xe8,0x43,0x84,0xcb,0xda,0x96,0xf9,0x4a,0xd0,0x8f,0xe1,0xd7,0xc4,0x05,0xf5,0x76,0xfa,0x47,0x7a,0x07,0x1a,0x77,0xbb,0x63,0xb3,0x3a,0x85,0x3b
+.byte 0x0d,0x32,0x4f,0x14,0x15,0x02,0x5b,0x9c,0xbc,0xc2,0x12,0x90,0x0f,0x7b,0x94,0x27,0x5f,0x70,0x23,0xd8,0x5d,0x54,0xc4,0xca,0x6a,0x69,0x9e,0xd1,0xb3,0x2a,0x75,0x1a,0x07,0x9c,0x20,0xf6,0x76,0x22,0x4d,0x09,0x30,0x24,0x3f,0x3b,0xe5,0xcb,0x4b,0x5a,0x03,0x2d,0xe8,0xbe,0xed,0xf0,0xe3,0x91,0xf2,0x6c,0xb8,0x02,0x2d,0x6c,0x7a,0xa6
+.byte 0xc1,0x8e,0xa7,0xbb,0x73,0xdf,0x40,0xa5,0x60,0x91,0xbf,0xbe,0x28,0x0b,0x37,0x2e,0x5f,0x4b,0xcd,0x14,0x4d,0x2d,0xfc,0x5e,0x43,0xb5,0x78,0x8d,0xea,0xa0,0x86,0x54,0x4f,0xb6,0x25,0x40,0x39,0x3f,0x9c,0x7a,0x26,0x74,0x88,0x42,0x53,0xb0,0x3b,0x81,0x75,0x04,0x67,0x41,0x65,0x66,0x2c,0xdc,0xe9,0xf0,0xb3,0xab,0x2a,0xa5,0xf3,0xef
+.byte 0xfa,0xc5,0x10,0x63,0xe2,0x70,0xb5,0x29,0x60,0x86,0x9e,0xb9,0x0b,0xe2,0xc4,0x05,0xa9,0x3c,0x1b,0x60,0x15,0x6b,0x2f,0x74,0x93,0x5e,0x70,0x9a,0x56,0x6a,0xc4,0x92,0x49,0xaa,0x95,0x51,0xc4,0xba,0xfd,0xf6,0x2d,0x36,0x3e,0x66,0xbd,0x74,0xbc,0x2e,0xb3,0xad,0xa1,0x41,0x50,0x33,0x79,0x84,0xac,0x21,0x7a,0xfc,0x3a,0x8e,0xdb,0xcc
+.byte 0x27,0xf6,0x2c,0x5c,0x23,0x38,0x73,0xd5,0xaf,0xc9,0x2d,0x9c,0x18,0x58,0xdf,0x8f,0x89,0x9d,0xdd,0x00,0x3c,0x5f,0x23,0x00,0x6e,0x66,0x1d,0xf3,0x1c,0x40,0x9d,0x43,0xb0,0x74,0xf1,0x41,0xa5,0x77,0xcb,0x8d,0x5b,0x94,0x68,0x95,0xb6,0x0e,0xd4,0x4d,0x47,0x9b,0xd2,0xcd,0x9b,0x94,0xa4,0x28,0xf9,0xf0,0x3d,0xcf,0x89,0xb1,0xc3,0x73
+.byte 0x84,0x15,0xb6,0xc8,0x6b,0xf1,0xb1,0xdc,0x1b,0x1a,0x6f,0xb5,0x73,0x87,0x8b,0x63,0xbf,0x4b,0x25,0x9b,0xe4,0xdd,0x44,0xed,0xe7,0x0e,0x6f,0x03,0xae,0xa1,0x5e,0x1f,0x5f,0xa7,0xa4,0xed,0x69,0x7a,0x91,0x6d,0x55,0xac,0xce,0x18,0x32,0x17,0x78,0x49,0x9f,0x1e,0x9c,0xd2,0x7b,0x1f,0x74,0x60,0xa5,0x64,0xb1,0x99,0xe6,0xc5,0x0d,0x69
+.byte 0xfa,0xb2,0xd9,0x05,0x61,0x71,0xa4,0x6f,0xc2,0xb6,0x91,0x0e,0x6c,0xf2,0xa6,0x6c,0xea,0x8e,0x94,0x8b,0xac,0xa7,0xfe,0x70,0x8e,0x8d,0xc2,0x85,0xa6,0xa7,0x8e,0xe8,0xfa,0xbc,0xa1,0xaf,0x0e,0xa9,0x06,0xa4,0x9a,0xb0,0x23,0x93,0xbc,0x93,0x2d,0x97,0x42,0xe2,0x0d,0x3a,0x65,0xb4,0x60,0x5b,0xeb,0xa1,0x20,0x8a,0xdc,0x17,0x6b,0xc5
+.byte 0x19,0xc3,0x67,0xbf,0xae,0xf7,0xb9,0xb1,0x88,0x7f,0xe5,0x1b,0xc2,0x61,0x97,0xa0,0xd3,0x64,0x74,0x6b,0x7a,0x46,0x39,0x3f,0xc8,0xd3,0x53,0x79,0x74,0x4e,0x1e,0x63,0x91,0xc5,0x4a,0x70,0xb0,0x05,0x35,0x19,0xc2,0x26,0x54,0x44,0x3b,0xa9,0x12,0x40,0xd0,0x21,0x19,0xf3,0x8d,0xc7,0x2b,0x88,0x9a,0xec,0x41,0x8f,0x4f,0x23,0x19,0x1a
+.byte 0xf3,0x1d,0x0a,0x88,0x0f,0xa7,0x02,0xd4,0x78,0x88,0xe6,0x43,0xb6,0x9e,0x07,0xdf,0x6a,0x1f,0x41,0xbb,0x3e,0xea,0x15,0xff,0x66,0x4c,0x7a,0x8b,0xee,0x27,0x47,0x81,0x81,0x95,0xa2,0x22,0xb4,0x9f,0x1c,0x09,0x1c,0xfc,0x0a,0xef,0x88,0x7f,0x59,0x60,0x91,0x6a,0xe4,0x92,0x8c,0x02,0x54,0xc9,0xee,0xc7,0x5e,0xd1,0xbf,0xc9,0x41,0xde
+.byte 0x2f,0xa3,0x22,0x07,0x1d,0x8c,0xe1,0x04,0x59,0x94,0x75,0x3e,0xee,0x56,0x62,0x07,0x80,0x18,0x60,0x78,0x0e,0x55,0x06,0xec,0xe1,0xa5,0xf6,0x21,0x7e,0xf9,0x37,0xab,0x6a,0xed,0x07,0xcb,0xbf,0xa2,0xab,0x50,0xee,0x1f,0x2f,0x54,0x2b,0x82,0x93,0x59,0x03,0x35,0xd9,0xe8,0x2b,0xa6,0x03,0xc2,0xef,0x37,0x85,0xfc,0x89,0x06,0x30,0xe0
+.byte 0xc2,0x00,0xc4,0xaf,0x59,0xb6,0x31,0x52,0x37,0xa4,0x6c,0xdb,0x1b,0x20,0x87,0xf0,0xa4,0x15,0x4b,0xa8,0xd9,0x7e,0x1b,0x96,0x00,0x07,0xf4,0x86,0x07,0x14,0x55,0x70,0x37,0xe3,0xe3,0xf0,0xeb,0xd6,0xf1,0xe0,0xe9,0x6c,0xdf,0x3d,0xaf,0x86,0xb8,0x00,0x9b,0xdf,0xc6,0x5c,0xd2,0x53,0xcb,0xcf,0x63,0xcc,0x3e,0x6d,0x62,0xeb,0xe6,0x97
+.byte 0xd8,0x54,0xed,0x36,0xe4,0xed,0x69,0xaa,0x10,0x83,0xde,0x16,0xfd,0xcc,0xd6,0x24,0xb9,0x3c,0x4f,0x99,0x81,0xc2,0x23,0x16,0x91,0x5d,0x9f,0x46,0xa5,0xdd,0xb4,0x8a,0xe1,0x07,0x89,0x84,0x2e,0x62,0x48,0xf6,0x1a,0x17,0x7b,0xc8,0xf7,0xb4,0x3d,0x9e,0x82,0xe3,0xe3,0xcf,0x0b,0xd9,0x52,0x90,0x61,0xd8,0xdf,0x9e,0xc4,0xc7,0x7c,0xfa
+.byte 0xcf,0x09,0xd2,0x94,0x86,0x37,0x94,0xaf,0x7e,0x0a,0x9d,0x16,0xee,0xad,0xfb,0xa2,0x9e,0x2d,0x2f,0xad,0xd5,0xc2,0xf9,0x91,0xf8,0x7e,0x2b,0xb8,0xb2,0x60,0x3c,0x0a,0x89,0x53,0x07,0x87,0x3b,0x83,0x70,0xee,0x71,0xa3,0x94,0x0b,0x77,0x50,0xeb,0xcc,0x23,0xf0,0xbe,0x95,0x51,0x54,0xd2,0xd6,0xd2,0x09,0xa5,0x19,0x3d,0x4e,0xec,0xe3
+.byte 0x88,0x71,0xa7,0xb1,0x10,0x03,0x7e,0xc4,0x92,0x2a,0xe7,0x99,0x75,0xff,0xae,0x10,0x3d,0xbb,0x33,0xc9,0x7f,0xc2,0xe6,0x3c,0xc4,0xe7,0xba,0x37,0xba,0x68,0x69,0x92,0x4a,0xfb,0x32,0x3b,0xb5,0xde,0xdb,0x91,0xd0,0x8e,0x77,0xf2,0x1e,0x2d,0x25,0xb4,0xa0,0x42,0xef,0x78,0x6c,0x75,0xcb,0xa0,0x73,0xdf,0xde,0xd8,0x26,0xfe,0xe3,0xf9
+.byte 0x74,0xe7,0xa0,0xd2,0xbd,0x6c,0x99,0x8d,0x07,0xf2,0xf8,0xff,0x36,0x2d,0x8e,0xda,0x5e,0x5c,0x47,0x06,0xf8,0x08,0x33,0x1d,0x93,0xcf,0xc3,0x1a,0x20,0x86,0xb6,0x8e,0x44,0x10,0xbc,0xba,0x89,0xfc,0xa3,0x57,0x92,0x2c,0x28,0xa1,0xd0,0xab,0xdc,0xba,0x0a,0x7e,0x9d,0xd2,0xfd,0x09,0xd3,0x87,0x6c,0x06,0x44,0x17,0x73,0xfe,0xc9,0x8b
+.byte 0x52,0xd3,0x09,0x60,0x14,0x03,0xb1,0x79,0x4c,0x9c,0xc4,0xec,0x42,0x4c,0xd3,0x21,0xe5,0x34,0x21,0x38,0xdd,0x12,0x95,0xd4,0x20,0x50,0xef,0x5f,0x46,0x4f,0x37,0x65,0xd5,0xf1,0xb2,0x2c,0x6c,0x9a,0x06,0x28,0x77,0xbf,0xe3,0xec,0xec,0x2b,0xcb,0x2c,0x8b,0x62,0x2e,0x39,0xaa,0x28,0x0b,0x51,0x01,0xa5,0x02,0x06,0x66,0x4a,0x67,0x0c
+.byte 0x96,0xa3,0x12,0x74,0x94,0x2c,0x0f,0x23,0xa3,0xea,0xda,0x1a,0x6d,0x54,0x30,0x33,0xc8,0x33,0x0a,0xfb,0x25,0x2a,0x8b,0x9a,0x87,0xd9,0x9d,0x37,0x4c,0x41,0x3b,0xe5,0x4a,0x81,0x92,0x40,0x38,0x18,0x82,0x13,0x54,0xde,0x56,0x11,0x63,0xf3,0x09,0x61,0x3b,0xdd,0x0c,0x71,0xe8,0x4f,0xc2,0x9a,0x77,0x2f,0xeb,0xf1,0x39,0x1c,0x10,0x0e
+.byte 0x01,0xaf,0x92,0x34,0x9a,0xb6,0x7b,0x79,0x86,0x0c,0xf1,0x53,0xb6,0x59,0xbd,0x6d,0x79,0x6e,0x37,0x11,0x25,0x67,0x95,0x31,0x4f,0x43,0xdf,0xb7,0x4b,0x80,0x8d,0x07,0x3c,0x49,0x73,0x8a,0x72,0x61,0x02,0x0f,0x2f,0x13,0xed,0x91,0x10,0xf6,0x08,0xf3,0x50,0x4a,0xd4,0x36,0xcb,0x52,0xb3,0x3b,0xe6,0xef,0x85,0xe9,0xe0,0xad,0x0d,0x3d
+.byte 0x84,0x07,0x70,0xdf,0x16,0x47,0xeb,0x26,0x19,0x27,0xaf,0x7a,0x9f,0x2f,0x2b,0x6d,0xbb,0x37,0x68,0x8e,0x19,0x46,0x5a,0x65,0x0d,0x0a,0x67,0xd8,0xe2,0xc2,0xcd,0x49,0xf6,0xc2,0x27,0xac,0x12,0xea,0x1f,0x81,0x60,0xac,0x8b,0x5d,0xcc,0x9a,0x5b,0xec,0xc3,0xcb,0x85,0x0d,0xef,0xa6,0xd5,0x33,0xb3,0x67,0x73,0x3f,0xc9,0x90,0x25,0x3e
+.byte 0xe6,0x7c,0x41,0x59,0x83,0xf7,0x90,0x4a,0xbf,0x14,0x72,0x11,0xf2,0x3a,0x38,0x58,0x17,0xd8,0x3d,0x00,0xc6,0x42,0xf2,0xbc,0xfd,0x05,0x37,0x6d,0x11,0xb0,0xd7,0xb2,0xb7,0x73,0x69,0x80,0x47,0x30,0x64,0x13,0x8c,0x24,0xb2,0x42,0x12,0x8c,0xc0,0x8a,0x45,0x0b,0x71,0x23,0xeb,0xac,0x65,0xda,0x44,0x13,0x85,0x77,0xdf,0xb8,0x4b,0x69
+.byte 0xd4,0x8e,0x40,0x54,0x24,0xac,0xc8,0x62,0x36,0x51,0x20,0xaa,0xcd,0x5d,0xa5,0x73,0x2c,0x81,0x92,0x99,0x44,0x6b,0x04,0xac,0x8e,0xee,0x96,0x29,0xca,0xdc,0x2f,0xd1,0x13,0x5c,0x9e,0xc2,0x67,0x6a,0xaf,0xf6,0x3e,0xe2,0xa1,0x6d,0xda,0xbe,0x8a,0x55,0x50,0x27,0xee,0x6d,0xb8,0x35,0x5f,0xb4,0xa8,0x76,0xa1,0xe2,0x52,0x87,0xf6,0xfb
+.byte 0xe2,0x16,0x1c,0x90,0x78,0xe4,0x17,0xb0,0xd9,0x56,0xf5,0xd3,0xa4,0xb0,0x3f,0xe9,0x01,0xf9,0xd0,0x67,0x2b,0xeb,0x1d,0x73,0x24,0x90,0x36,0x36,0x0d,0xcf,0xfb,0x3f,0xa1,0xa0,0x25,0x3b,0xf1,0x7f,0x9e,0x90,0xcf,0xb6,0xd0,0x83,0x90,0xcd,0x3f,0xff,0x5f,0xa3,0x33,0x95,0xd7,0xbe,0x78,0xfe,0xcc,0x9a,0xb9,0x64,0x88,0xb7,0xd9,0x5e
+.byte 0x46,0x2d,0xf0,0xb1,0xa1,0x81,0x2b,0xab,0x80,0xf5,0x4d,0x3b,0xd8,0x53,0x64,0x8f,0xac,0x7a,0x03,0xb3,0x39,0x7a,0x85,0xef,0x61,0xb5,0x2c,0x8e,0xf4,0x27,0x07,0x9b,0x7b,0xc9,0x8b,0x1a,0xe4,0x4f,0xce,0x8b,0x35,0x32,0xac,0xcf,0x47,0xb8,0x2f,0x9e,0xe5,0x11,0x48,0xc1,0x07,0xea,0x0c,0xee,0x06,0xc6,0xa3,0x48,0xb6,0x1a,0xd8,0xb4
+.byte 0xa7,0xae,0x59,0x7d,0x9e,0x4e,0x66,0x7f,0xe9,0x02,0x40,0xdc,0x21,0x5e,0x74,0x2c,0x1d,0x29,0x22,0xca,0x97,0x4f,0xc8,0xc7,0xea,0x69,0x02,0x89,0xd1,0x43,0xff,0x83,0x89,0x58,0x66,0x92,0xbc,0x11,0xf6,0x02,0x8b,0xa8,0x34,0x8d,0xbe,0x3a,0x70,0xc3,0x10,0xe7,0xb5,0xc4,0xda,0xdb,0xc6,0x87,0xee,0xee,0xe0,0x48,0x62,0x80,0x8d,0xfc
+.byte 0xaa,0xc7,0xce,0x1a,0xea,0xb9,0x1b,0x30,0x4a,0x48,0x9b,0xf4,0x58,0xff,0x5d,0x15,0xc8,0xf2,0x84,0x44,0xae,0x63,0xe8,0xb1,0xe0,0x2e,0x38,0x8e,0x47,0xf9,0x09,0xec,0xb9,0x94,0x18,0x37,0x68,0xef,0xbd,0xd5,0x67,0x72,0x01,0x9a,0x15,0xb9,0x7c,0x36,0xc0,0x22,0x80,0x12,0xb1,0x4e,0xab,0x3c,0xea,0x81,0xcf,0x70,0xf3,0xde,0x1f,0xd4
+.byte 0x67,0x94,0xfa,0xe1,0xf0,0xb6,0xd6,0x6b,0xc3,0xa2,0xbb,0x59,0x6b,0x9f,0x58,0x26,0x99,0x0c,0xdc,0xcd,0xb8,0xae,0x49,0xf0,0x8f,0xd3,0x0d,0xb7,0x4c,0x22,0xcf,0xb6,0x6c,0xa3,0x19,0x09,0x42,0x59,0x25,0xf8,0xdc,0xf3,0xc2,0x00,0xc3,0xc3,0xd3,0x9e,0x98,0xd3,0xa3,0xd0,0x96,0xfd,0x4f,0x15,0x57,0x5b,0xa7,0x08,0x3a,0x0e,0x3d,0xd2
+.byte 0x7d,0xa1,0xa0,0x94,0xc0,0x76,0x83,0xf6,0xc1,0xe8,0x7e,0xd3,0x97,0xc1,0xbf,0x38,0x74,0x9b,0xfb,0x35,0xeb,0xf7,0x34,0x20,0xea,0xda,0xd3,0xb1,0x2e,0x10,0x16,0x9c,0x09,0x1c,0x67,0x46,0xa2,0x05,0xf9,0x47,0xde,0x35,0x53,0x18,0x58,0xb0,0xbb,0x7a,0x88,0x58,0xc5,0x3e,0x98,0x29,0x43,0x98,0x07,0x76,0xa3,0xe1,0x95,0x92,0x21,0xe9
+.byte 0x06,0x17,0x15,0xe0,0x6b,0xd5,0x5a,0x6d,0x10,0xa6,0x08,0x92,0xa9,0xf5,0xcf,0x57,0x1a,0x28,0x5d,0x14,0x33,0x99,0xf9,0xa0,0xb3,0xeb,0xee,0xd4,0x6e,0x0b,0x5e,0xf7,0xe9,0xe3,0xc6,0x71,0x34,0x55,0xf3,0xde,0xd5,0xc2,0x52,0xc3,0x7b,0x06,0x87,0xef,0x26,0x81,0xc9,0xbd,0xaf,0x12,0x61,0x95,0x2b,0xa4,0x8e,0xe8,0x08,0x9a,0x13,0x48
+.byte 0x2e,0x84,0x98,0xf6,0x95,0x21,0x22,0xe5,0xcf,0x30,0x8d,0xaf,0x70,0x16,0x27,0x0c,0xcd,0x26,0x7f,0xe8,0xa0,0x35,0x0c,0x01,0x0e,0xdd,0x9d,0x2c,0x89,0x41,0x34,0xc4,0xa2,0xaa,0xf6,0x3f,0xca,0x3b,0x86,0xce,0xd7,0x4c,0xe3,0xb5,0x69,0xe9,0x41,0xbe,0x3c,0x9a,0x4c,0x1a,0xb3,0x88,0xea,0x78,0x12,0x4c,0x1b,0x79,0xc7,0xcd,0x32,0x72
+.byte 0xfa,0x3f,0x0b,0x73,0x1b,0xd9,0xec,0x85,0xd4,0x52,0x6c,0x91,0x2d,0xbe,0x76,0x8b,0xfd,0xb6,0x49,0xcf,0x67,0xd1,0x18,0x7b,0xae,0x86,0x47,0x47,0xfd,0xff,0x63,0xf2,0x88,0x1b,0x58,0xd5,0x30,0x69,0xf9,0x9a,0x03,0x52,0xae,0xe5,0xe2,0x55,0xbf,0x35,0x12,0xb0,0x84,0xa9,0xed,0xb6,0x8d,0x5f,0x6c,0xed,0x1a,0x00,0x7a,0xdc,0xf2,0x03
+.byte 0x9e,0xef,0x59,0x27,0x4c,0xf4,0x83,0xa2,0x36,0x3d,0x3d,0x8c,0x75,0x8c,0x37,0x68,0x93,0x0b,0x30,0x48,0xea,0x91,0x14,0x37,0x88,0x87,0x7f,0xe6,0xd8,0xbd,0x04,0x34,0x1e,0xe8,0x2a,0x41,0x48,0x5c,0x66,0xf9,0xc2,0xd1,0x56,0x25,0x29,0x45,0xfa,0x71,0xe1,0x59,0xa8,0x52,0x99,0x0b,0x92,0xe0,0x33,0x52,0x91,0xd6,0x5f,0x0a,0x70,0x83
+.byte 0x4f,0xa3,0x47,0x6e,0xfa,0x85,0x5e,0xb1,0x0a,0x1d,0xe7,0x35,0xc9,0x88,0x27,0xc9,0x8c,0x3e,0x7f,0x6d,0x34,0x1e,0x11,0x7b,0xcd,0xe7,0x09,0x82,0x3a,0xa1,0x46,0xc6,0x15,0xde,0x0b,0xde,0x35,0x71,0x92,0x5c,0x72,0x50,0x08,0x6b,0x62,0xa7,0xec,0xa2,0xca,0x53,0x6e,0x47,0x7d,0x50,0x32,0xa7,0x32,0x7b,0x49,0x0c,0x97,0xcc,0x98,0x8d
+.byte 0xc3,0x29,0x72,0x1e,0x85,0x47,0x1b,0xa7,0x89,0x19,0x85,0xaa,0x3f,0x11,0x6a,0xea,0x61,0x84,0x07,0x9a,0xc8,0xb3,0x25,0xfe,0x72,0xca,0x83,0xa9,0xf0,0x9e,0x01,0xe4,0x9a,0xd6,0x1b,0x87,0xfc,0xd4,0x3a,0x04,0x34,0x8c,0x0b,0x46,0xbc,0xe9,0x3c,0x3f,0xd9,0x93,0xf1,0xca,0x41,0x0b,0xdb,0x28,0xe8,0x28,0x1b,0x84,0x36,0x16,0x84,0x22
+.byte 0x1e,0x1e,0x2b,0xb0,0xfb,0xa6,0xcc,0x95,0x31,0x46,0xd7,0xca,0xc2,0x8b,0xa3,0x3a,0xa5,0xb0,0xaf,0x52,0x66,0x53,0x39,0x5f,0x58,0xb5,0xdf,0x01,0x52,0x07,0xb4,0x82,0xdc,0xb7,0xf9,0x88,0xd8,0x77,0xf8,0x12,0x9d,0xe8,0x21,0xd7,0x0b,0x0f,0x57,0x90,0x40,0xb2,0x64,0x3f,0xce,0xa0,0xa3,0xfa,0x12,0x16,0xec,0x6d,0xcc,0xc7,0x2a,0x43
+.byte 0xc9,0xe7,0xb7,0x90,0x52,0x35,0x22,0x6d,0x46,0x99,0x1e,0x44,0x12,0xd6,0x0f,0xaf,0x5c,0x16,0xd3,0x7a,0xd6,0xb4,0xfe,0x20,0x26,0x11,0xe1,0xc6,0xa5,0x10,0xfd,0x9f,0x0c,0x47,0xae,0x32,0x08,0x15,0x8f,0xef,0xef,0x4c,0x83,0xbc,0xbf,0x6a,0xe5,0xf5,0x69,0x11,0x4d,0x7d,0x47,0x1f,0x10,0x58,0x61,0xb0,0x0d,0x98,0x67,0xc0,0x99,0x3a
+.byte 0x2d,0x9a,0x5b,0xd5,0x37,0xe7,0xe5,0xd4,0x56,0x96,0x69,0xf8,0x53,0x7e,0x24,0x70,0x51,0x01,0x83,0x8d,0x49,0x01,0x32,0x7d,0x4f,0x41,0x92,0x54,0x9c,0x15,0xf1,0x3c,0x05,0x32,0x28,0x0d,0x0f,0x67,0xbe,0x65,0xfa,0x1b,0xa3,0xd0,0x28,0x18,0xb8,0x84,0xfe,0x6a,0x30,0xea,0xb9,0x00,0xb1,0x10,0x7c,0xa2,0x94,0x4f,0x86,0x18,0xdd,0xb4
+.byte 0x80,0x18,0x48,0x18,0xe1,0x56,0x70,0x7d,0x5c,0x3b,0xe5,0xd7,0x88,0x66,0x57,0xe3,0xe1,0x04,0x4c,0x68,0x5b,0x64,0x4d,0x0d,0x30,0x76,0x26,0xaa,0x84,0x0e,0xe0,0xed,0x53,0x62,0x20,0x33,0xaf,0x45,0x42,0x40,0x47,0x01,0x15,0xc9,0x0b,0x27,0x7c,0x68,0x4d,0x55,0xc4,0x6a,0x5f,0x96,0x9f,0x96,0x67,0xae,0x13,0x1c,0x84,0x52,0x33,0x41
+.byte 0x80,0xfc,0xae,0xb6,0xb1,0x8c,0xc3,0x19,0x80,0xa8,0x5f,0xe5,0x8c,0xd0,0xa8,0xb4,0x58,0xc9,0x48,0x29,0xab,0x11,0xd1,0x09,0xc6,0x20,0x98,0x4c,0xdb,0xa4,0x83,0x5c,0x26,0x51,0xce,0x80,0xe5,0xc4,0x9b,0xae,0xba,0x8e,0x99,0x4e,0xa4,0xff,0xdc,0x99,0x4c,0x02,0xa0,0x42,0x80,0xca,0xd7,0xea,0x6a,0x58,0x31,0xdb,0x16,0xd8,0x4d,0xab
+.byte 0x03,0x2e,0x3a,0xdc,0xe9,0x07,0xfb,0xfb,0x5b,0x57,0x67,0x2a,0x7b,0xdc,0xc1,0x66,0xd1,0x31,0x3a,0x03,0x87,0xd8,0x66,0xda,0xa1,0x24,0x00,0x26,0xc0,0x26,0x78,0xf8,0x59,0x13,0x3f,0x34,0x08,0x35,0x45,0xbd,0x45,0x4f,0x89,0x65,0x97,0xdb,0xe6,0x1e,0x09,0x6e,0x23,0x2a,0xc4,0xf5,0x6a,0x74,0x28,0xb0,0xae,0x8c,0xfb,0x49,0x35,0x99
+.byte 0x06,0x30,0xc6,0xb2,0x8c,0xcd,0x8b,0x41,0xea,0xf2,0x04,0x18,0x29,0x25,0x1b,0x32,0x42,0x45,0xb5,0x92,0x42,0xb4,0x33,0xd2,0x90,0x31,0x08,0xcd,0x35,0x5d,0x50,0x64,0xa8,0x93,0xfd,0xa5,0xfd,0x32,0xbd,0xe8,0x13,0x1c,0x48,0x5c,0x14,0x70,0x03,0x92,0x0f,0x12,0x86,0xf6,0x6c,0xcd,0xc6,0xec,0xbf,0x8e,0x85,0x28,0x1d,0x1c,0x63,0x3f
+.byte 0x81,0x93,0xd4,0x80,0x3c,0x29,0x0b,0x63,0xfe,0x87,0xa6,0x24,0xd6,0x3e,0x62,0xb6,0xd9,0xb0,0x58,0xf1,0x41,0x36,0xc7,0x47,0x8b,0xfd,0x4b,0x91,0x4e,0x5d,0x41,0x44,0xb0,0x65,0x3d,0x9e,0x3b,0x70,0x01,0xcc,0x7d,0x77,0xf0,0x23,0xd9,0xca,0x5f,0xda,0xa1,0x8c,0x71,0x11,0x91,0x7d,0x36,0xf5,0xc9,0xcd,0xf4,0x34,0x5f,0x69,0x57,0xd6
+.byte 0x33,0x4c,0xb2,0xe1,0x38,0x5f,0x86,0x3c,0x57,0x7b,0x2e,0x99,0x05,0x80,0x63,0xc4,0x77,0x69,0x06,0xc2,0x47,0x44,0xca,0x17,0x27,0x1d,0x55,0x34,0x02,0xd0,0x89,0x3a,0x3b,0x79,0xf0,0x86,0xd7,0x6b,0x01,0x9c,0xc7,0xa8,0xde,0xdb,0xdf,0x49,0xd1,0xb9,0x11,0xaf,0x7e,0x22,0x8b,0x5d,0xb5,0x0b,0xdc,0xd0,0x36,0xe6,0x9d,0x85,0x41,0x4a
+.byte 0x35,0xf0,0xe1,0xcd,0xce,0x7b,0xd1,0xd6,0x00,0xdd,0xb6,0xe4,0x06,0x3e,0x66,0xe9,0x2b,0xa8,0x44,0x0d,0x18,0xd4,0xbc,0xfb,0x3c,0x58,0x6c,0x11,0xe9,0xdc,0x19,0x14,0x08,0x27,0x23,0x0c,0xd0,0xf9,0x97,0xaf,0x97,0x07,0x02,0x1a,0x5e,0xcd,0xae,0xd2,0x80,0x96,0x16,0x49,0xc3,0xfc,0xda,0x25,0x12,0x20,0xe1,0xc0,0x68,0x90,0x4b,0x30
+.byte 0x2d,0x06,0x53,0x2c,0x57,0x63,0x4a,0x7a,0xf6,0xc8,0x5a,0xb7,0x58,0x8c,0x13,0xfe,0x43,0xb3,0xf8,0x25,0x3e,0x7a,0x25,0x3e,0x1d,0x7f,0x8f,0x5e,0xdb,0xad,0x99,0x83,0xfc,0xd9,0x0a,0xdf,0xb5,0x19,0x1c,0x2c,0xf6,0xe8,0x06,0xbe,0xc0,0x9f,0x7e,0x0f,0x95,0xaa,0xac,0x09,0xdc,0x8c,0x37,0xcf,0x35,0x35,0x95,0x62,0xf1,0xff,0x96,0x1c
+.byte 0x77,0xe9,0x53,0x7e,0x12,0x56,0x2d,0x4e,0x3e,0x1f,0xdb,0x1d,0x71,0x0e,0xdc,0xf7,0x65,0xb1,0x78,0x7f,0xe4,0xba,0xbf,0x7f,0x6c,0xcb,0x73,0xd3,0xe8,0xd9,0xce,0xfb,0xdb,0x48,0x87,0xe0,0x10,0x00,0x74,0xcb,0xdf,0x32,0xa8,0xdd,0x83,0x24,0x49,0xda,0x86,0x38,0x1c,0x2c,0x93,0x09,0x8a,0x26,0xbb,0x34,0x21,0x1d,0xac,0xb5,0x16,0xae
+.byte 0xd8,0xcb,0x94,0x04,0xd6,0xbc,0xde,0x9c,0x70,0x28,0xa5,0x1a,0x15,0x5e,0x35,0xe4,0xe6,0x53,0xea,0x9c,0x3b,0x0c,0x36,0x3b,0x80,0x13,0x28,0x1d,0xc7,0x1a,0xa8,0x8e,0x9e,0x09,0xce,0x5d,0x50,0xd3,0xc7,0x6f,0x3a,0x75,0xa5,0x84,0x1c,0x08,0x66,0xe6,0x05,0xda,0x8b,0xf1,0x4b,0x5c,0xe2,0xc7,0x0f,0xa1,0xf1,0x47,0x02,0xf4,0xa7,0x24
+.byte 0xf3,0x0e,0x2c,0xa9,0xae,0x67,0xdf,0xce,0x30,0x88,0x4a,0x9a,0x39,0x4a,0x97,0x64,0xa8,0x30,0x53,0xf9,0x47,0x66,0x5c,0x19,0x1c,0xfb,0x2f,0x05,0x89,0x4f,0xfe,0x25,0xe7,0xed,0xed,0x17,0x5a,0x86,0xeb,0x25,0xee,0xe4,0x09,0x88,0x05,0x49,0x20,0x54,0x4b,0x7f,0x3e,0xb5,0x23,0x85,0xa9,0x66,0x61,0x73,0xe0,0x61,0x94,0xc6,0xe5,0x29
+.byte 0xb4,0xe1,0x6f,0xa4,0x4d,0x50,0x56,0x2e,0x30,0x75,0x51,0x5d,0xdd,0xa2,0x68,0x56,0x67,0xd8,0xec,0x2d,0x2a,0xfd,0x49,0xc5,0xbc,0xae,0x2f,0x6b,0xc7,0x8d,0x2e,0xca,0x91,0x35,0xe8,0xea,0x65,0xe9,0x9c,0x65,0xaf,0x8e,0xd5,0x16,0xdf,0xac,0x44,0x1e,0xb6,0x16,0xf0,0xb6,0x33,0x6a,0xe6,0x96,0x0f,0x85,0x2e,0xa1,0xaa,0x6a,0xe0,0x12
+.byte 0x0c,0xaa,0x7d,0xae,0xf7,0xe3,0xb2,0x4c,0x3c,0x10,0xc6,0x87,0x8e,0x87,0xfb,0xac,0xf7,0xd7,0x7a,0x2e,0x9a,0x7a,0xa7,0x4f,0xf0,0x75,0xce,0xbd,0xc3,0xe6,0x79,0x1d,0x56,0xab,0xff,0x56,0xfe,0x69,0xbd,0xcf,0x15,0x27,0x64,0x3c,0x83,0x1c,0x08,0xb0,0x91,0x60,0x67,0xe7,0x27,0x44,0x49,0x22,0x78,0xd5,0x1a,0xc8,0x3b,0x35,0x9b,0xa5
+.byte 0x53,0xce,0xde,0x04,0xd2,0x3e,0x67,0x48,0xaf,0x54,0xdf,0x9c,0xf7,0xb9,0xd4,0xe3,0xb6,0x85,0x02,0x68,0x21,0x10,0xdb,0xb5,0xca,0x11,0xa2,0x7c,0xcf,0x13,0x41,0x7a,0xfd,0xe9,0x0a,0x3c,0x53,0xd6,0x07,0xf2,0xdd,0xe2,0x7c,0x16,0xf0,0x44,0x3f,0x5d,0x34,0x09,0x7c,0x7b,0x21,0x8c,0x8e,0xdb,0x0d,0xc5,0x73,0xce,0x61,0xce,0x17,0x46
+.byte 0x6c,0x14,0x07,0xb5,0x70,0x80,0xf0,0x29,0x7c,0x13,0x41,0x2d,0x8e,0xdc,0x53,0xc2,0xbf,0xf0,0xc2,0xfb,0x59,0xa0,0x66,0x5f,0x25,0xda,0x17,0x5f,0xac,0xab,0x75,0x1b,0xc7,0x61,0x87,0x53,0x80,0x2e,0x11,0x4e,0x04,0x48,0xf9,0xee,0x54,0xe6,0x69,0x69,0x57,0xc2,0x46,0xd8,0xb3,0x2e,0x7b,0xc8,0xa5,0xd0,0xb2,0x5e,0xd4,0x6b,0x9b,0x1a
+.byte 0xd6,0x79,0x9d,0x99,0xa6,0xbb,0x4d,0xca,0x74,0x2c,0x3d,0xd4,0x86,0xd0,0x64,0xd4,0x81,0x49,0x76,0x42,0xb8,0xf9,0x2c,0x52,0xe7,0x77,0x37,0x31,0xbb,0x2e,0x5b,0x38,0x81,0x01,0x2c,0x27,0x28,0xcb,0x0c,0xba,0xfa,0x8a,0x9a,0x45,0x51,0xa2,0xde,0xf2,0x7b,0xe6,0x65,0xec,0x5b,0x2d,0xe8,0x55,0x8e,0xb4,0x7f,0xf8,0x1a,0x66,0x3a,0x5f
+.byte 0x06,0x10,0x15,0xb2,0x3d,0xb2,0x36,0x6e,0x9f,0x8e,0xe2,0x4c,0x78,0xe5,0x3a,0xac,0x21,0x16,0x20,0x30,0x0f,0x51,0x56,0xcb,0x53,0xca,0x70,0x3c,0xa2,0x3f,0x37,0x06,0x6c,0x70,0xec,0xf4,0x3d,0x7c,0x77,0xa0,0x61,0xc7,0x0e,0x26,0x9f,0x25,0xc0,0xf2,0x28,0xdb,0x57,0xbe,0xe6,0x4e,0x9c,0x4d,0x2e,0x48,0x50,0xc2,0xd4,0xfd,0x5e,0x52
+.byte 0x3f,0xd0,0x82,0xd1,0xd4,0x53,0xad,0x42,0x38,0xb1,0x02,0xd6,0xa0,0x34,0x7a,0xb4,0xb3,0xdd,0x91,0x12,0xf4,0x91,0xc9,0xa2,0x35,0x2d,0xdc,0x97,0xa1,0xdb,0x82,0xe7,0x92,0x99,0x66,0x13,0x99,0x20,0x95,0x1f,0x47,0x64,0x80,0x5e,0x5f,0x74,0x6b,0xa6,0xca,0x47,0x0b,0x24,0x72,0xa6,0x27,0xe7,0x56,0x61,0xa7,0x8e,0x62,0xa4,0xff,0x8e
+.byte 0x29,0xf8,0x09,0xa4,0xbb,0x70,0x97,0x8a,0x39,0xe8,0x65,0xc8,0x52,0x23,0x9d,0xbf,0x10,0xe8,0x7d,0xbc,0x3c,0xc4,0x8b,0x1e,0x5c,0x75,0x94,0x24,0x62,0x3f,0x5b,0x2b,0x9a,0x08,0x00,0x78,0xfd,0x28,0x44,0x12,0x62,0x2a,0x6f,0x47,0x9d,0x57,0xb0,0x4e,0x3b,0xcd,0x01,0x7d,0x6e,0x62,0xe3,0x99,0x9c,0xae,0x6e,0xe2,0x70,0x7a,0x32,0xb4
+.byte 0xc1,0x19,0xb1,0x03,0x6b,0x92,0x89,0x4f,0x37,0xaf,0x36,0xee,0x5e,0x03,0x31,0x8c,0x41,0x27,0x17,0x21,0xdf,0xe4,0x34,0x97,0x8d,0xe7,0x41,0x47,0xf2,0x80,0x51,0x41,0x01,0xe4,0x0c,0x1a,0x09,0xfc,0x07,0xc3,0x94,0x07,0x6f,0xa7,0x6c,0xff,0x32,0x21,0xa5,0x01,0x8c,0xa2,0x88,0x3c,0xc8,0x57,0xe8,0x68,0x19,0x4a,0x46,0x7a,0x36,0xd2
+.byte 0x75,0x8e,0xc5,0xa4,0x84,0x91,0x13,0x7f,0xdd,0x2b,0x3c,0x2e,0xc4,0x92,0x29,0xb3,0x60,0x74,0xc8,0x81,0x58,0x0e,0xad,0x6a,0x9d,0xaa,0x81,0x49,0x26,0x0f,0xd4,0x2a,0x39,0xdd,0x4d,0x2b,0x13,0xdb,0x2e,0x72,0xe6,0x45,0x99,0xeb,0xe6,0xe5,0xd5,0x76,0xd4,0x19,0xd8,0xd7,0xa9,0x1f,0xce,0x7f,0xc4,0x1c,0x9e,0x6f,0x68,0x32,0xb1,0x26
+.byte 0xc4,0xb6,0x4e,0x9f,0xbf,0xdc,0xe0,0xde,0x54,0x9b,0xe0,0x04,0x03,0xae,0xc9,0xce,0x3a,0xcb,0x93,0xad,0xcc,0x1f,0x46,0xf6,0xbb,0xff,0x40,0x52,0x9c,0x64,0x97,0x5a,0x6f,0x8d,0x28,0x45,0x1c,0xf6,0x8b,0xcb,0xb9,0x38,0xb8,0x00,0xee,0xec,0xac,0x68,0x3f,0x50,0xcb,0x36,0x6e,0x97,0xfd,0xa5,0x1d,0x29,0x6e,0xfa,0x9f,0x4b,0x83,0xcd
+.byte 0x0d,0x34,0xf3,0x1e,0x3f,0x0f,0x2e,0x89,0xeb,0xf7,0x8e,0x5f,0xe0,0x3b,0x39,0xd2,0xe8,0x87,0xe3,0xe7,0xe9,0xd0,0x1b,0x32,0x03,0x6b,0x3c,0x75,0x7d,0xe2,0x5c,0x3c,0x42,0xb4,0x46,0x69,0x0b,0xaf,0x0a,0x5d,0x1a,0x83,0x0b,0x0e,0x3c,0x5a,0x36,0xbd,0x5d,0xb6,0xad,0x4c,0xdd,0xf1,0x8d,0xbf,0x2b,0x70,0x8e,0xbc,0x92,0x95,0x1b,0x0f
+.byte 0xed,0x3f,0xae,0x9e,0xa2,0x5a,0x50,0xe4,0xda,0xde,0x04,0x51,0x31,0xac,0xa4,0x0b,0x94,0xcc,0x14,0x87,0x59,0xa8,0x30,0x09,0xe6,0x46,0xb9,0x07,0x3e,0x1a,0xbf,0x5a,0x23,0x32,0xfb,0x60,0x63,0x24,0x25,0x12,0xf6,0x3e,0x2d,0xd0,0x8b,0x88,0x9b,0xe9,0x2d,0xab,0xf5,0xaf,0xba,0xbc,0xfe,0xab,0xb2,0x61,0x7a,0x7c,0xbb,0x28,0x6b,0x86
+.byte 0xe5,0xa2,0x9c,0x2c,0x5a,0x23,0x12,0x11,0xe5,0x72,0xe8,0x7b,0x6b,0x40,0xf1,0x91,0x37,0x3b,0x47,0x75,0x65,0xac,0x4d,0x22,0x59,0x75,0x13,0xb0,0x73,0xff,0x59,0xd1,0x1b,0xcc,0x05,0x1f,0xf2,0xc8,0x50,0x83,0xf1,0x28,0x38,0x0b,0xc3,0xa0,0x3b,0xe3,0x86,0xbb,0x9c,0x7e,0xc1,0xe9,0xcc,0xd9,0xb8,0x2b,0x05,0xf3,0x6f,0xc7,0x9d,0xaf
+.byte 0x7b,0xb7,0x38,0x41,0xa3,0x50,0x8f,0x92,0xe0,0x63,0x35,0xb3,0x95,0x9f,0x80,0xf8,0x75,0xbb,0xf3,0x2b,0x0e,0xaf,0x32,0x6e,0xff,0xeb,0x79,0xca,0xbf,0x1c,0x4f,0x6c,0x9c,0x06,0xb2,0xeb,0x99,0x57,0x1f,0xf6,0x64,0x0b,0x81,0x57,0xba,0xf4,0x32,0x1e,0x77,0x37,0x55,0xb7,0xbc,0xba,0x70,0x0b,0x0d,0xdd,0x95,0x41,0xb5,0x17,0x5b,0x14
+.byte 0x10,0x9d,0x14,0x52,0x83,0x65,0x0a,0xf4,0x55,0xca,0xf8,0xbe,0xa6,0x3a,0xa0,0x6e,0xcc,0x83,0x84,0x65,0xb4,0x1c,0x7e,0x40,0xdd,0x32,0x36,0x5a,0x23,0x17,0x7d,0xb5,0xb9,0x38,0x48,0x5c,0x6f,0x23,0x54,0x0e,0x93,0x74,0x27,0x0f,0xfd,0x58,0xc1,0x97,0x26,0x78,0x9a,0xd3,0x85,0xc5,0xb2,0xb3,0x44,0xb7,0x36,0x85,0x69,0xde,0x3b,0xa1
+.byte 0x2b,0x11,0xef,0x75,0xfc,0xaa,0x92,0xf1,0xf1,0x72,0xa0,0x5f,0x33,0xf6,0x0b,0x72,0xdb,0xce,0x6c,0x2a,0x15,0x76,0x40,0xd4,0x85,0xff,0x96,0xe1,0x48,0xe1,0x27,0x8f,0x74,0xf3,0xfa,0xa1,0xb7,0x2a,0xb6,0x41,0x90,0x92,0x7e,0xfa,0xfc,0xad,0xa3,0x94,0x91,0x77,0xf1,0x8f,0xee,0xa2,0x64,0x47,0x01,0xb3,0x01,0x99,0x05,0xe7,0x31,0x4a
+.byte 0xe8,0xd2,0x65,0x40,0x21,0xc4,0x83,0x8e,0xc9,0x89,0xda,0x16,0x7b,0xe0,0xcb,0xc0,0xc0,0x3d,0x37,0x18,0x66,0xe9,0x70,0x86,0x0b,0x6c,0xe8,0x65,0x44,0xce,0x3a,0xcd,0x84,0x1e,0xce,0x0e,0xe3,0xf9,0x77,0x12,0xfb,0xe6,0x92,0x8b,0x0d,0x7e,0x15,0x7a,0x34,0x94,0x2a,0xa7,0xc5,0x35,0xa4,0xfc,0xbe,0xa3,0x13,0x70,0xe4,0x6b,0x2f,0x71
+.byte 0x31,0xef,0xdb,0x79,0x44,0xf2,0x77,0xc7,0xc9,0x0d,0x1a,0x7b,0xff,0x34,0xf8,0xc9,0xe8,0xc9,0xc2,0xe0,0x0c,0x9e,0xd6,0xb4,0x7a,0xdb,0x1f,0x65,0xb8,0xd4,0x92,0xbf,0x7f,0x06,0x44,0xe3,0xb4,0xd8,0x14,0xe3,0x9b,0x49,0x81,0x12,0xec,0x7d,0x01,0xe2,0x50,0x2c,0x0e,0xfd,0x4b,0x84,0x3b,0x4d,0x89,0x1d,0x2e,0x4b,0xe9,0xda,0xa5,0x3f
+.byte 0x19,0xc2,0x53,0x36,0x5d,0xd8,0xdc,0x6e,0xc3,0x48,0x8f,0x09,0xd5,0x95,0x4b,0x0c,0x7c,0x00,0x15,0x33,0x8e,0x1d,0x0c,0xdf,0x32,0x3b,0x93,0x1f,0xf5,0x49,0x4f,0xfd,0x8b,0x64,0xe7,0x96,0xaf,0x2f,0xc8,0xea,0xab,0x91,0x53,0x29,0xe3,0x31,0x0a,0x1c,0x6e,0xe0,0xbb,0x81,0x11,0x83,0xe0,0x07,0xfb,0x29,0x11,0x0f,0x0d,0x85,0xd4,0x61
+.byte 0x3c,0x75,0xbb,0x8a,0x23,0xb6,0xa0,0x7f,0xa4,0xbb,0x11,0xd4,0x75,0xde,0x27,0xe5,0xeb,0x11,0x5d,0x02,0xfe,0x5c,0x62,0x60,0x0f,0x6f,0x45,0x9b,0xfb,0xb7,0x32,0xa8,0x1c,0xd6,0xff,0x43,0x7b,0x53,0xee,0xa4,0x1f,0xf2,0xba,0xb6,0xb7,0xb7,0x39,0x18,0x85,0x79,0x77,0x27,0x30,0x26,0xe4,0xef,0xd1,0x39,0xc9,0xa2,0x0d,0x50,0xd7,0xef
+.byte 0x9e,0xd8,0x8e,0xd2,0x74,0x1a,0x3f,0x99,0x24,0xf4,0x8b,0x4d,0x02,0x63,0x18,0x3a,0xaf,0x26,0xef,0xfc,0x1d,0xfe,0x46,0xc1,0x55,0xd7,0x92,0x65,0x2f,0xe7,0x4f,0x47,0xa8,0x2f,0x5d,0x47,0x67,0xeb,0x62,0x1d,0x69,0xa6,0x0e,0x51,0x1d,0x2c,0xed,0x6e,0x94,0xe9,0x48,0x4c,0x22,0xc2,0x93,0x79,0x6f,0x1b,0xc2,0x93,0x61,0x3d,0x8b,0xba
+.byte 0xcb,0xe9,0x4a,0x88,0x5e,0x19,0x50,0x14,0xfe,0xda,0x3f,0x4d,0x47,0x54,0xfc,0x1c,0x09,0x77,0x37,0x30,0xfe,0x75,0x9f,0xdd,0xa4,0x74,0x04,0x04,0x88,0xe0,0xac,0x93,0x64,0x6f,0xbf,0x50,0xd8,0xf0,0xf7,0xa0,0xfa,0x98,0x49,0xfa,0xf7,0x6e,0xcf,0xa2,0xbf,0xb6,0x07,0x15,0x0e,0x4e,0x21,0x74,0x0a,0xa6,0xa3,0x67,0xce,0xf9,0x3b,0xd6
+.byte 0x4c,0xc8,0x43,0xe3,0x3b,0x3b,0x6a,0x86,0x62,0x3f,0x5a,0xf3,0x3f,0xf9,0xeb,0xbf,0xa3,0x2a,0x83,0x8a,0x70,0x8f,0x01,0x65,0x17,0x9a,0xa6,0x26,0x3b,0x09,0x06,0x22,0x19,0xed,0xd7,0x25,0x4b,0xd2,0x9a,0x30,0xfe,0x1c,0x82,0x68,0x16,0x04,0x0e,0x04,0x8f,0xc6,0x92,0xbe,0xe4,0x43,0x98,0x1d,0x3b,0x10,0x15,0x5b,0xef,0x4e,0x60,0x5e
+.byte 0x6b,0xc9,0xde,0xb8,0x47,0x02,0x86,0x45,0x39,0x7a,0x1a,0xef,0x67,0x28,0xc5,0x40,0x73,0x2a,0xa7,0x12,0x9d,0x58,0x3a,0x34,0xc2,0xda,0x34,0xb0,0x48,0xd9,0x34,0xcd,0x18,0xe9,0x76,0x41,0x78,0x8f,0xe5,0xe8,0x3d,0xb2,0x01,0x3b,0x84,0xd1,0xca,0x5e,0x26,0x1d,0x8c,0xea,0xe1,0x46,0xa3,0xf9,0x11,0xac,0x0d,0x98,0x9f,0xd3,0x46,0x79
+.byte 0xff,0xad,0x99,0x32,0x63,0x96,0xbc,0x57,0x39,0x16,0xce,0x06,0x7e,0x63,0x78,0x7b,0x86,0x92,0x1a,0xe1,0x45,0xc0,0x73,0xe1,0xec,0xfc,0x88,0x8f,0xf8,0x36,0x0f,0x54,0x76,0x02,0x98,0x49,0x40,0xb9,0xef,0xd8,0x13,0x68,0xf5,0x1d,0x0a,0x98,0x65,0x21,0xc5,0x1a,0x22,0x4e,0x8e,0xad,0xa9,0x52,0x57,0xc4,0xc6,0xa8,0x48,0x01,0x7a,0x78
+.byte 0xc9,0xfc,0xdd,0xf3,0xc3,0x83,0xc0,0x06,0xb5,0x56,0x84,0xe2,0x0c,0x6b,0x80,0xd9,0x59,0xa1,0x3d,0xe3,0x56,0xf0,0xe3,0x3f,0x93,0x61,0xf7,0x8c,0x6b,0x40,0x65,0x6e,0x01,0xc2,0xa1,0xc1,0xb8,0x9b,0x15,0x6c,0xa1,0x18,0x4a,0x6c,0x8b,0x18,0x2d,0x8e,0x71,0x7a,0xa1,0x26,0xc1,0x4b,0xac,0x0c,0xca,0x08,0x33,0xef,0x35,0x33,0x63,0xeb
+.byte 0x57,0x6e,0x7e,0x36,0xe0,0x31,0xad,0x10,0x76,0xb7,0x45,0xd9,0x3a,0x92,0x66,0x69,0x13,0x61,0x59,0x87,0xfd,0x6b,0xf1,0x46,0x0a,0x7a,0x3f,0x29,0x88,0x5b,0x7d,0xef,0x07,0x02,0xa8,0xa1,0xdc,0xd4,0x0e,0x77,0x8f,0x68,0x32,0xbd,0x8e,0xd6,0x0b,0xe4,0xd1,0x75,0xc1,0xb0,0x74,0x6c,0x0e,0xc3,0x46,0x79,0x36,0x3b,0x5f,0x0e,0xa0,0xad
+.byte 0x28,0x8c,0xcb,0x01,0x8e,0x58,0x14,0x09,0xf1,0xd4,0x3b,0x2e,0xdc,0xbf,0x37,0x95,0x26,0xda,0xb6,0xcf,0xc8,0xa1,0xd4,0xec,0x72,0xf3,0x44,0xf5,0x4e,0x27,0x9b,0x2e,0x7c,0xfa,0x37,0x16,0x1d,0x7f,0x90,0x86,0xae,0x96,0x3b,0xe1,0xda,0xf7,0xc4,0x54,0x0b,0x51,0x7e,0x83,0xbe,0xed,0xd6,0x5f,0xd2,0x6d,0xbb,0xd3,0xc6,0x53,0x95,0x65
+.byte 0x3d,0x19,0xc2,0xc5,0xdf,0x47,0x00,0x2c,0x4b,0x2d,0xec,0x32,0xd5,0x28,0xb5,0x30,0xe0,0x79,0x15,0x2e,0xab,0x97,0xa8,0xcf,0xc5,0x40,0x98,0x30,0x22,0x9f,0xbc,0xdb,0x65,0x06,0xfc,0x58,0xe5,0x55,0x5b,0xe2,0xf8,0x6e,0xc6,0xfc,0xec,0x6c,0x14,0xd2,0xe3,0x9a,0x71,0x8a,0x61,0xea,0x39,0xc6,0x77,0x94,0xdf,0x7b,0x99,0x71,0xdd,0x18
+.byte 0xc6,0x03,0x2d,0x49,0xf6,0xc3,0xe8,0x2b,0x7e,0x3f,0x28,0xfc,0xc8,0xa1,0xb0,0x15,0x31,0x7e,0x83,0xb8,0x14,0x34,0x0e,0x7f,0xde,0x74,0x7b,0xbf,0xb7,0x8e,0xd9,0x31,0x90,0x16,0xb6,0x57,0x14,0x4a,0xc6,0x67,0x3d,0xb9,0x46,0x92,0xf2,0xf9,0x94,0x36,0x2b,0xd6,0x1f,0x84,0xa5,0x8c,0x0f,0xd9,0x8c,0x5f,0x97,0x7a,0x7b,0xff,0xc9,0xf5
+.byte 0x5e,0x13,0x5f,0x19,0x58,0xba,0xa6,0xe8,0x29,0xf4,0xb8,0x7e,0x98,0xb7,0xef,0x1b,0x00,0xe8,0x90,0x8f,0x86,0x4c,0xe0,0x51,0x13,0x8b,0xa1,0x37,0x40,0x38,0x51,0x2f,0x5a,0x9b,0x63,0x8f,0xce,0x9a,0x97,0x07,0x0d,0x8e,0xce,0xb1,0x66,0x89,0x78,0xca,0xa6,0x0c,0x20,0xc4,0xf1,0xe3,0xab,0xe2,0x1c,0x83,0x2b,0x46,0x97,0xe8,0x8f,0x94
+.byte 0xb4,0x71,0x40,0xde,0xa1,0x05,0x4b,0xed,0xbf,0x0c,0x46,0xe1,0x25,0xf1,0xd0,0x5a,0xdb,0x9c,0x2a,0x09,0x03,0x80,0x24,0xc1,0x22,0x02,0xa5,0xde,0xf6,0x4c,0xbc,0x93,0x37,0xa9,0x28,0xb3,0x92,0x19,0xa8,0x3f,0x71,0x90,0x62,0x78,0xaa,0x9a,0x0c,0xab,0x50,0xaf,0x89,0x2b,0xf1,0xf4,0x12,0xbd,0xc9,0xd5,0xee,0x64,0x8b,0x48,0x21,0xd6
+.byte 0xa1,0xa1,0xf2,0x68,0x4a,0xf8,0x06,0x3e,0x20,0x31,0x66,0xb7,0x2f,0x64,0x01,0x5a,0x46,0x14,0x85,0xfb,0xde,0x04,0xc3,0xe4,0xd6,0x25,0x14,0xa0,0xbe,0x4d,0x39,0xd8,0xe0,0x9b,0xb7,0x6b,0x00,0xe6,0x46,0xfb,0xcc,0xa8,0xad,0x67,0x12,0x2c,0x53,0x2c,0xb6,0x9f,0x6e,0xfe,0xbc,0xcc,0x2c,0xa8,0x09,0x17,0x00,0x8e,0xf1,0xf4,0x3e,0xa9
+.byte 0x92,0x4d,0x83,0xe6,0x3c,0xf0,0xd3,0x1c,0xaf,0x84,0x2c,0x59,0x7e,0xda,0x1e,0xfd,0x7d,0xf3,0xef,0x93,0x05,0x03,0xb0,0x76,0x69,0xb5,0x51,0xa8,0x65,0x8f,0x8a,0xf8,0x55,0x92,0x08,0xfe,0xbf,0xc1,0x95,0x98,0x58,0xb1,0xd3,0xb6,0x78,0x4f,0x2f,0x25,0xcb,0x9d,0x32,0x4f,0xa6,0xcc,0xf8,0x36,0xff,0x72,0xb3,0x93,0x3d,0xd8,0x0b,0xe6
+.byte 0xc6,0xf6,0xed,0xcc,0x2a,0xa5,0x44,0x6e,0xe2,0x2d,0x6e,0x02,0xb4,0x7c,0x24,0x7f,0x57,0x02,0x84,0x61,0x8e,0xbd,0x32,0x4e,0x41,0x92,0x01,0x1b,0x8b,0x1d,0xd1,0x1e,0x31,0xc1,0x4c,0x5b,0x0c,0xa7,0x48,0x52,0x67,0xc2,0xd9,0xdc,0x86,0x9d,0xbd,0x6c,0x19,0x95,0x00,0xf0,0xd4,0x47,0xaf,0xfe,0x5d,0xa5,0x81,0xbd,0x1b,0x42,0x62,0xce
+.byte 0x18,0x1b,0xa3,0x6f,0xf5,0x0b,0xb7,0x6a,0x3d,0xe3,0xcc,0x41,0x27,0xcd,0x49,0x4b,0xe5,0x2b,0xc4,0x28,0xfa,0xbe,0xd5,0x7e,0xb7,0xac,0xab,0x64,0x3b,0xe3,0x87,0xb1,0x33,0x8b,0xa8,0xe5,0x75,0xce,0x61,0x57,0x89,0xad,0x5f,0x61,0xdd,0x7c,0x06,0x2a,0x3f,0x50,0xb8,0x7e,0xd2,0xfb,0x32,0x83,0x07,0xd4,0xc5,0x3f,0xad,0x64,0x59,0x1f
+.byte 0x21,0x59,0x6f,0x1b,0xd7,0x40,0x89,0x28,0x18,0xac,0xca,0xee,0x92,0x1c,0x0d,0x88,0x98,0x7a,0x75,0x68,0xe0,0xe2,0x96,0xda,0x88,0xb3,0xc6,0x21,0x02,0x34,0xfa,0xae,0x0b,0x38,0xcf,0x1c,0x6c,0x7a,0xc9,0xd9,0x5f,0xf0,0x4c,0x73,0xfd,0xe6,0x14,0xf3,0x39,0xed,0xbc,0x28,0x2f,0xf8,0x79,0x02,0x39,0x05,0xf3,0x6a,0x88,0xd9,0x03,0xe2
+.byte 0xb9,0x65,0x81,0x3a,0x34,0x80,0x3f,0x17,0x37,0x1e,0xe8,0x7d,0x41,0x49,0xfb,0x70,0x5d,0x58,0x3a,0x71,0x7b,0x3e,0xd3,0x83,0x0b,0x1b,0x11,0xfc,0x53,0xce,0xc6,0xc4,0x39,0x55,0xbe,0xbe,0x32,0xa5,0x88,0xab,0xcd,0x38,0x78,0x3e,0x52,0xaf,0x64,0x42,0x10,0xc3,0x70,0x81,0x76,0xe9,0x7d,0x8e,0x46,0x41,0xca,0x2c,0x0c,0x4c,0x30,0xd3
+.byte 0xca,0x38,0xa3,0x97,0x2e,0x0f,0xa5,0x18,0x3b,0xaa,0x0f,0x00,0x75,0x35,0x9c,0xcd,0x28,0x83,0xd4,0xa7,0x7c,0xb9,0xcd,0xb5,0x55,0x29,0x4c,0x14,0xcd,0xfc,0x8f,0xaf,0x7d,0x69,0x4f,0xf7,0x0f,0xed,0x7c,0xa5,0x79,0x9d,0x36,0xbb,0x72,0xbc,0xf2,0x14,0xfd,0xf0,0x04,0x2a,0x89,0x1e,0xf7,0x80,0x4c,0x5e,0xb8,0xc1,0xdb,0xfa,0x3c,0x27
+.byte 0xbb,0x30,0x08,0x2b,0xd2,0xf8,0xdb,0xe0,0x8c,0x00,0xe4,0xca,0xa9,0xde,0xb0,0x14,0x5b,0xec,0x6b,0xe6,0x5c,0x90,0x17,0x02,0x59,0x5f,0x5f,0x51,0xf8,0x30,0x10,0x11,0xc4,0xdf,0x37,0x30,0x32,0xb1,0x4d,0x49,0xfe,0x82,0x87,0xd2,0x42,0xf5,0x38,0x76,0xf9,0xa5,0x28,0xfc,0x14,0xb2,0xe0,0x72,0x82,0xde,0xc8,0x47,0x9e,0x8f,0x8a,0xb5
+.byte 0x85,0x44,0x42,0x12,0xc6,0xc0,0xa5,0x60,0x5a,0x27,0xd0,0x36,0x14,0x7b,0x2a,0x83,0x98,0x92,0x08,0xe9,0x03,0xc9,0xc3,0xd3,0x36,0x97,0xba,0x5e,0xd5,0x51,0xcc,0x44,0xeb,0x81,0x76,0xae,0x28,0x94,0x0b,0xf6,0xc7,0xeb,0xae,0x61,0x6f,0x7b,0x34,0xb5,0x8c,0x5f,0x31,0xb6,0x23,0xe3,0xe7,0x4b,0x60,0xe6,0xba,0x8d,0x0e,0xd1,0xb2,0x37
+.byte 0x72,0x3d,0xc1,0x75,0x9b,0x5e,0xcb,0x0f,0xf9,0xe4,0xdb,0x82,0x4c,0xc4,0x37,0xef,0x9d,0xde,0x16,0x85,0xe9,0xc2,0x03,0xd8,0x5b,0xa1,0xff,0xfa,0xd4,0xd7,0x5c,0x34,0xb6,0x1e,0x25,0x96,0xf5,0x8b,0xc3,0xee,0x16,0x1f,0xf8,0x55,0x4e,0x1c,0x83,0x80,0x77,0x1d,0x4f,0xb6,0x95,0x1c,0x91,0x7d,0x50,0x25,0xf4,0x2a,0x5d,0x2e,0xc7,0x8a
+.byte 0x14,0xf8,0xb9,0xbc,0xab,0x5b,0xcd,0x47,0xb5,0xaf,0x85,0xc0,0x34,0x27,0x7d,0x6a,0x8c,0x84,0x8a,0xae,0x68,0x60,0x0e,0xa1,0x45,0xf7,0x83,0x66,0x91,0x69,0x30,0xed,0x26,0x5e,0xf5,0x48,0x6b,0x20,0xb3,0x11,0x50,0xf7,0x70,0x9d,0x10,0x50,0x44,0x87,0xfe,0x96,0x5c,0xc6,0xa4,0xa4,0xed,0x5e,0x7f,0x3d,0x90,0x19,0xbe,0x31,0xa3,0xdd
+.byte 0x44,0xbb,0x9b,0x51,0x5a,0x06,0x1d,0x2e,0xd7,0xef,0xd1,0x81,0xb6,0xec,0xc6,0x89,0xfb,0x13,0xc5,0x21,0xef,0x9a,0x1a,0x48,0xf2,0xf8,0xb3,0xa3,0xec,0x7f,0x85,0xc1,0xc6,0x8c,0x5f,0xa9,0x30,0x38,0x25,0x1e,0x8d,0xcf,0x18,0x24,0xef,0x5a,0x9a,0x14,0x31,0xc0,0x2c,0x88,0xa5,0x3f,0x50,0x8b,0xb1,0xda,0x5d,0x26,0xd9,0xd3,0x81,0xb1
+.byte 0xec,0xf0,0x42,0x88,0xd0,0x81,0x51,0xf9,0x1b,0xbc,0x43,0xa4,0x37,0xf1,0xd7,0x90,0x21,0x7e,0xa0,0x3e,0x63,0xfb,0x21,0xfa,0x12,0xfb,0xde,0xc7,0xbf,0xb3,0x58,0xe7,0x76,0x42,0x20,0x01,0x3d,0x66,0x80,0xf1,0xb8,0xaf,0xfa,0x7d,0x96,0x89,0x36,0x48,0x95,0xd9,0x6e,0x6d,0xe6,0x4f,0xff,0x2a,0x47,0x61,0xf2,0x04,0xb7,0x83,0x14,0xce
+.byte 0x0a,0x3c,0x73,0x17,0x50,0x88,0x03,0x25,0x4a,0xe3,0x13,0x55,0x8b,0x7e,0x50,0x38,0xfc,0x14,0x0b,0x04,0x8e,0xa8,0x5b,0xd6,0x72,0x20,0x60,0xe9,0xaa,0x22,0x82,0x11,0xc6,0xc4,0xd7,0xb9,0xc8,0x0c,0x7e,0x05,0xfb,0x90,0xe4,0x9c,0x28,0x89,0x29,0x99,0x63,0x4d,0xec,0x7b,0x50,0xbd,0xd8,0xa3,0x5b,0x50,0x77,0x19,0x81,0x92,0xce,0x82
+.size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed
+.align 5
+.Lpoly:
+.quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001
+.LRR: // 2^512 mod P precomputed for NIST P256 polynomial
+.quad 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd
+.Lone_mont:
+.quad 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe
+.Lone:
+.quad 1,0,0,0
+.Lord:
+.quad 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000
+.LordK:
+.quad 0xccd1c8aaee00bc4f
+.byte 69,67,80,95,78,73,83,84,90,50,53,54,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 2
+
+// void ecp_nistz256_to_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_to_mont
+.type ecp_nistz256_to_mont,%function
+.align 6
+ecp_nistz256_to_mont:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-32]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+
+ ldr x3,.LRR // bp[0]
+ ldp x4,x5,[x1]
+ ldp x6,x7,[x1,#16]
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+ adr x2,.LRR // &bp[0]
+
+ bl __ecp_nistz256_mul_mont
+
+ ldp x19,x20,[sp,#16]
+ ldp x29,x30,[sp],#32
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
+
+// void ecp_nistz256_from_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_from_mont
+.type ecp_nistz256_from_mont,%function
+.align 4
+ecp_nistz256_from_mont:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-32]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+
+ mov x3,#1 // bp[0]
+ ldp x4,x5,[x1]
+ ldp x6,x7,[x1,#16]
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+ adr x2,.Lone // &bp[0]
+
+ bl __ecp_nistz256_mul_mont
+
+ ldp x19,x20,[sp,#16]
+ ldp x29,x30,[sp],#32
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
+
+// void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4],
+// const BN_ULONG x2[4]);
+.globl ecp_nistz256_mul_mont
+.type ecp_nistz256_mul_mont,%function
+.align 4
+ecp_nistz256_mul_mont:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-32]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+
+ ldr x3,[x2] // bp[0]
+ ldp x4,x5,[x1]
+ ldp x6,x7,[x1,#16]
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+
+ bl __ecp_nistz256_mul_mont
+
+ ldp x19,x20,[sp,#16]
+ ldp x29,x30,[sp],#32
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
+
+// void ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_sqr_mont
+.type ecp_nistz256_sqr_mont,%function
+.align 4
+ecp_nistz256_sqr_mont:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-32]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+
+ ldp x4,x5,[x1]
+ ldp x6,x7,[x1,#16]
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+
+ bl __ecp_nistz256_sqr_mont
+
+ ldp x19,x20,[sp,#16]
+ ldp x29,x30,[sp],#32
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
+
+// void ecp_nistz256_add(BN_ULONG x0[4],const BN_ULONG x1[4],
+// const BN_ULONG x2[4]);
+.globl ecp_nistz256_add
+.type ecp_nistz256_add,%function
+.align 4
+ecp_nistz256_add:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ldp x14,x15,[x1]
+ ldp x8,x9,[x2]
+ ldp x16,x17,[x1,#16]
+ ldp x10,x11,[x2,#16]
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+
+ bl __ecp_nistz256_add
+
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_add,.-ecp_nistz256_add
+
+// void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_div_by_2
+.type ecp_nistz256_div_by_2,%function
+.align 4
+ecp_nistz256_div_by_2:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ldp x14,x15,[x1]
+ ldp x16,x17,[x1,#16]
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+
+ bl __ecp_nistz256_div_by_2
+
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
+
+// void ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_mul_by_2
+.type ecp_nistz256_mul_by_2,%function
+.align 4
+ecp_nistz256_mul_by_2:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ldp x14,x15,[x1]
+ ldp x16,x17,[x1,#16]
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+ mov x8,x14
+ mov x9,x15
+ mov x10,x16
+ mov x11,x17
+
+ bl __ecp_nistz256_add // ret = a+a // 2*a
+
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
+
+// void ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_mul_by_3
+.type ecp_nistz256_mul_by_3,%function
+.align 4
+ecp_nistz256_mul_by_3:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ldp x14,x15,[x1]
+ ldp x16,x17,[x1,#16]
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+ mov x8,x14
+ mov x9,x15
+ mov x10,x16
+ mov x11,x17
+ mov x4,x14
+ mov x5,x15
+ mov x6,x16
+ mov x7,x17
+
+ bl __ecp_nistz256_add // ret = a+a // 2*a
+
+ mov x8,x4
+ mov x9,x5
+ mov x10,x6
+ mov x11,x7
+
+ bl __ecp_nistz256_add // ret += a // 2*a+a=3*a
+
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
+
+// void ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4],
+// const BN_ULONG x2[4]);
+.globl ecp_nistz256_sub
+.type ecp_nistz256_sub,%function
+.align 4
+ecp_nistz256_sub:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ldp x14,x15,[x1]
+ ldp x16,x17,[x1,#16]
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+
+ bl __ecp_nistz256_sub_from
+
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_sub,.-ecp_nistz256_sub
+
+// void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_neg
+.type ecp_nistz256_neg,%function
+.align 4
+ecp_nistz256_neg:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ mov x2,x1
+ mov x14,xzr // a = 0
+ mov x15,xzr
+ mov x16,xzr
+ mov x17,xzr
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+
+ bl __ecp_nistz256_sub_from
+
+ ldp x29,x30,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_neg,.-ecp_nistz256_neg
+
+// note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded
+// to x4-x7 and b[0] - to x3
+.type __ecp_nistz256_mul_mont,%function
+.align 4
+__ecp_nistz256_mul_mont:
+ mul x14,x4,x3 // a[0]*b[0]
+ umulh x8,x4,x3
+
+ mul x15,x5,x3 // a[1]*b[0]
+ umulh x9,x5,x3
+
+ mul x16,x6,x3 // a[2]*b[0]
+ umulh x10,x6,x3
+
+ mul x17,x7,x3 // a[3]*b[0]
+ umulh x11,x7,x3
+ ldr x3,[x2,#8] // b[1]
+
+ adds x15,x15,x8 // accumulate high parts of multiplication
+ lsl x8,x14,#32
+ adcs x16,x16,x9
+ lsr x9,x14,#32
+ adcs x17,x17,x10
+ adc x19,xzr,x11
+ mov x20,xzr
+ subs x10,x14,x8 // "*0xffff0001"
+ sbc x11,x14,x9
+ adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0]
+ mul x8,x4,x3 // lo(a[0]*b[i])
+ adcs x15,x16,x9
+ mul x9,x5,x3 // lo(a[1]*b[i])
+ adcs x16,x17,x10 // +=acc[0]*0xffff0001
+ mul x10,x6,x3 // lo(a[2]*b[i])
+ adcs x17,x19,x11
+ mul x11,x7,x3 // lo(a[3]*b[i])
+ adc x19,x20,xzr
+
+ adds x14,x14,x8 // accumulate low parts of multiplication
+ umulh x8,x4,x3 // hi(a[0]*b[i])
+ adcs x15,x15,x9
+ umulh x9,x5,x3 // hi(a[1]*b[i])
+ adcs x16,x16,x10
+ umulh x10,x6,x3 // hi(a[2]*b[i])
+ adcs x17,x17,x11
+ umulh x11,x7,x3 // hi(a[3]*b[i])
+ adc x19,x19,xzr
+ ldr x3,[x2,#8*(1+1)] // b[1+1]
+ adds x15,x15,x8 // accumulate high parts of multiplication
+ lsl x8,x14,#32
+ adcs x16,x16,x9
+ lsr x9,x14,#32
+ adcs x17,x17,x10
+ adcs x19,x19,x11
+ adc x20,xzr,xzr
+ subs x10,x14,x8 // "*0xffff0001"
+ sbc x11,x14,x9
+ adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0]
+ mul x8,x4,x3 // lo(a[0]*b[i])
+ adcs x15,x16,x9
+ mul x9,x5,x3 // lo(a[1]*b[i])
+ adcs x16,x17,x10 // +=acc[0]*0xffff0001
+ mul x10,x6,x3 // lo(a[2]*b[i])
+ adcs x17,x19,x11
+ mul x11,x7,x3 // lo(a[3]*b[i])
+ adc x19,x20,xzr
+
+ adds x14,x14,x8 // accumulate low parts of multiplication
+ umulh x8,x4,x3 // hi(a[0]*b[i])
+ adcs x15,x15,x9
+ umulh x9,x5,x3 // hi(a[1]*b[i])
+ adcs x16,x16,x10
+ umulh x10,x6,x3 // hi(a[2]*b[i])
+ adcs x17,x17,x11
+ umulh x11,x7,x3 // hi(a[3]*b[i])
+ adc x19,x19,xzr
+ ldr x3,[x2,#8*(2+1)] // b[2+1]
+ adds x15,x15,x8 // accumulate high parts of multiplication
+ lsl x8,x14,#32
+ adcs x16,x16,x9
+ lsr x9,x14,#32
+ adcs x17,x17,x10
+ adcs x19,x19,x11
+ adc x20,xzr,xzr
+ subs x10,x14,x8 // "*0xffff0001"
+ sbc x11,x14,x9
+ adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0]
+ mul x8,x4,x3 // lo(a[0]*b[i])
+ adcs x15,x16,x9
+ mul x9,x5,x3 // lo(a[1]*b[i])
+ adcs x16,x17,x10 // +=acc[0]*0xffff0001
+ mul x10,x6,x3 // lo(a[2]*b[i])
+ adcs x17,x19,x11
+ mul x11,x7,x3 // lo(a[3]*b[i])
+ adc x19,x20,xzr
+
+ adds x14,x14,x8 // accumulate low parts of multiplication
+ umulh x8,x4,x3 // hi(a[0]*b[i])
+ adcs x15,x15,x9
+ umulh x9,x5,x3 // hi(a[1]*b[i])
+ adcs x16,x16,x10
+ umulh x10,x6,x3 // hi(a[2]*b[i])
+ adcs x17,x17,x11
+ umulh x11,x7,x3 // hi(a[3]*b[i])
+ adc x19,x19,xzr
+ adds x15,x15,x8 // accumulate high parts of multiplication
+ lsl x8,x14,#32
+ adcs x16,x16,x9
+ lsr x9,x14,#32
+ adcs x17,x17,x10
+ adcs x19,x19,x11
+ adc x20,xzr,xzr
+ // last reduction
+ subs x10,x14,x8 // "*0xffff0001"
+ sbc x11,x14,x9
+ adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0]
+ adcs x15,x16,x9
+ adcs x16,x17,x10 // +=acc[0]*0xffff0001
+ adcs x17,x19,x11
+ adc x19,x20,xzr
+
+ adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus
+ sbcs x9,x15,x12
+ sbcs x10,x16,xzr
+ sbcs x11,x17,x13
+ sbcs xzr,x19,xzr // did it borrow?
+
+ csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus
+ csel x15,x15,x9,lo
+ csel x16,x16,x10,lo
+ stp x14,x15,[x0]
+ csel x17,x17,x11,lo
+ stp x16,x17,[x0,#16]
+
+ ret
+.size __ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont
+
+// note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded
+// to x4-x7
+.type __ecp_nistz256_sqr_mont,%function
+.align 4
+__ecp_nistz256_sqr_mont:
+ // | | | | | |a1*a0| |
+ // | | | | |a2*a0| | |
+ // | |a3*a2|a3*a0| | | |
+ // | | | |a2*a1| | | |
+ // | | |a3*a1| | | | |
+ // *| | | | | | | | 2|
+ // +|a3*a3|a2*a2|a1*a1|a0*a0|
+ // |--+--+--+--+--+--+--+--|
+ // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow
+ //
+ // "can't overflow" below mark carrying into high part of
+ // multiplication result, which can't overflow, because it
+ // can never be all ones.
+
+ mul x15,x5,x4 // a[1]*a[0]
+ umulh x9,x5,x4
+ mul x16,x6,x4 // a[2]*a[0]
+ umulh x10,x6,x4
+ mul x17,x7,x4 // a[3]*a[0]
+ umulh x19,x7,x4
+
+ adds x16,x16,x9 // accumulate high parts of multiplication
+ mul x8,x6,x5 // a[2]*a[1]
+ umulh x9,x6,x5
+ adcs x17,x17,x10
+ mul x10,x7,x5 // a[3]*a[1]
+ umulh x11,x7,x5
+ adc x19,x19,xzr // can't overflow
+
+ mul x20,x7,x6 // a[3]*a[2]
+ umulh x1,x7,x6
+
+ adds x9,x9,x10 // accumulate high parts of multiplication
+ mul x14,x4,x4 // a[0]*a[0]
+ adc x10,x11,xzr // can't overflow
+
+ adds x17,x17,x8 // accumulate low parts of multiplication
+ umulh x4,x4,x4
+ adcs x19,x19,x9
+ mul x9,x5,x5 // a[1]*a[1]
+ adcs x20,x20,x10
+ umulh x5,x5,x5
+ adc x1,x1,xzr // can't overflow
+
+ adds x15,x15,x15 // acc[1-6]*=2
+ mul x10,x6,x6 // a[2]*a[2]
+ adcs x16,x16,x16
+ umulh x6,x6,x6
+ adcs x17,x17,x17
+ mul x11,x7,x7 // a[3]*a[3]
+ adcs x19,x19,x19
+ umulh x7,x7,x7
+ adcs x20,x20,x20
+ adcs x1,x1,x1
+ adc x2,xzr,xzr
+
+ adds x15,x15,x4 // +a[i]*a[i]
+ adcs x16,x16,x9
+ adcs x17,x17,x5
+ adcs x19,x19,x10
+ adcs x20,x20,x6
+ lsl x8,x14,#32
+ adcs x1,x1,x11
+ lsr x9,x14,#32
+ adc x2,x2,x7
+ subs x10,x14,x8 // "*0xffff0001"
+ sbc x11,x14,x9
+ adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0]
+ adcs x15,x16,x9
+ lsl x8,x14,#32
+ adcs x16,x17,x10 // +=acc[0]*0xffff0001
+ lsr x9,x14,#32
+ adc x17,x11,xzr // can't overflow
+ subs x10,x14,x8 // "*0xffff0001"
+ sbc x11,x14,x9
+ adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0]
+ adcs x15,x16,x9
+ lsl x8,x14,#32
+ adcs x16,x17,x10 // +=acc[0]*0xffff0001
+ lsr x9,x14,#32
+ adc x17,x11,xzr // can't overflow
+ subs x10,x14,x8 // "*0xffff0001"
+ sbc x11,x14,x9
+ adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0]
+ adcs x15,x16,x9
+ lsl x8,x14,#32
+ adcs x16,x17,x10 // +=acc[0]*0xffff0001
+ lsr x9,x14,#32
+ adc x17,x11,xzr // can't overflow
+ subs x10,x14,x8 // "*0xffff0001"
+ sbc x11,x14,x9
+ adds x14,x15,x8 // +=acc[0]<<96 and omit acc[0]
+ adcs x15,x16,x9
+ adcs x16,x17,x10 // +=acc[0]*0xffff0001
+ adc x17,x11,xzr // can't overflow
+
+ adds x14,x14,x19 // accumulate upper half
+ adcs x15,x15,x20
+ adcs x16,x16,x1
+ adcs x17,x17,x2
+ adc x19,xzr,xzr
+
+ adds x8,x14,#1 // subs x8,x14,#-1 // tmp = ret-modulus
+ sbcs x9,x15,x12
+ sbcs x10,x16,xzr
+ sbcs x11,x17,x13
+ sbcs xzr,x19,xzr // did it borrow?
+
+ csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus
+ csel x15,x15,x9,lo
+ csel x16,x16,x10,lo
+ stp x14,x15,[x0]
+ csel x17,x17,x11,lo
+ stp x16,x17,[x0,#16]
+
+ ret
+.size __ecp_nistz256_sqr_mont,.-__ecp_nistz256_sqr_mont
+
+// Note that __ecp_nistz256_add expects both input vectors pre-loaded to
+// x4-x7 and x8-x11. This is done because it's used in multiple
+// contexts, e.g. in multiplication by 2 and 3...
+.type __ecp_nistz256_add,%function
+.align 4
+__ecp_nistz256_add:
+ adds x14,x14,x8 // ret = a+b
+ adcs x15,x15,x9
+ adcs x16,x16,x10
+ adcs x17,x17,x11
+ adc x1,xzr,xzr // zap x1
+
+ adds x8,x14,#1 // subs x8,x4,#-1 // tmp = ret-modulus
+ sbcs x9,x15,x12
+ sbcs x10,x16,xzr
+ sbcs x11,x17,x13
+ sbcs xzr,x1,xzr // did subtraction borrow?
+
+ csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus
+ csel x15,x15,x9,lo
+ csel x16,x16,x10,lo
+ stp x14,x15,[x0]
+ csel x17,x17,x11,lo
+ stp x16,x17,[x0,#16]
+
+ ret
+.size __ecp_nistz256_add,.-__ecp_nistz256_add
+
+.type __ecp_nistz256_sub_from,%function
+.align 4
+__ecp_nistz256_sub_from:
+ ldp x8,x9,[x2]
+ ldp x10,x11,[x2,#16]
+ subs x14,x14,x8 // ret = a-b
+ sbcs x15,x15,x9
+ sbcs x16,x16,x10
+ sbcs x17,x17,x11
+ sbc x1,xzr,xzr // zap x1
+
+ subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus
+ adcs x9,x15,x12
+ adcs x10,x16,xzr
+ adc x11,x17,x13
+ cmp x1,xzr // did subtraction borrow?
+
+ csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret
+ csel x15,x15,x9,eq
+ csel x16,x16,x10,eq
+ stp x14,x15,[x0]
+ csel x17,x17,x11,eq
+ stp x16,x17,[x0,#16]
+
+ ret
+.size __ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from
+
+.type __ecp_nistz256_sub_morf,%function
+.align 4
+__ecp_nistz256_sub_morf:
+ ldp x8,x9,[x2]
+ ldp x10,x11,[x2,#16]
+ subs x14,x8,x14 // ret = b-a
+ sbcs x15,x9,x15
+ sbcs x16,x10,x16
+ sbcs x17,x11,x17
+ sbc x1,xzr,xzr // zap x1
+
+ subs x8,x14,#1 // adds x8,x4,#-1 // tmp = ret+modulus
+ adcs x9,x15,x12
+ adcs x10,x16,xzr
+ adc x11,x17,x13
+ cmp x1,xzr // did subtraction borrow?
+
+ csel x14,x14,x8,eq // ret = borrow ? ret+modulus : ret
+ csel x15,x15,x9,eq
+ csel x16,x16,x10,eq
+ stp x14,x15,[x0]
+ csel x17,x17,x11,eq
+ stp x16,x17,[x0,#16]
+
+ ret
+.size __ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf
+
+.type __ecp_nistz256_div_by_2,%function
+.align 4
+__ecp_nistz256_div_by_2:
+ subs x8,x14,#1 // adds x8,x4,#-1 // tmp = a+modulus
+ adcs x9,x15,x12
+ adcs x10,x16,xzr
+ adcs x11,x17,x13
+ adc x1,xzr,xzr // zap x1
+ tst x14,#1 // is a even?
+
+ csel x14,x14,x8,eq // ret = even ? a : a+modulus
+ csel x15,x15,x9,eq
+ csel x16,x16,x10,eq
+ csel x17,x17,x11,eq
+ csel x1,xzr,x1,eq
+
+ lsr x14,x14,#1 // ret >>= 1
+ orr x14,x14,x15,lsl#63
+ lsr x15,x15,#1
+ orr x15,x15,x16,lsl#63
+ lsr x16,x16,#1
+ orr x16,x16,x17,lsl#63
+ lsr x17,x17,#1
+ stp x14,x15,[x0]
+ orr x17,x17,x1,lsl#63
+ stp x16,x17,[x0,#16]
+
+ ret
+.size __ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2
+.globl ecp_nistz256_point_double
+.type ecp_nistz256_point_double,%function
+.align 5
+ecp_nistz256_point_double:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ sub sp,sp,#32*4
+
+.Ldouble_shortcut:
+ ldp x14,x15,[x1,#32]
+ mov x21,x0
+ ldp x16,x17,[x1,#48]
+ mov x22,x1
+ ldr x12,.Lpoly+8
+ mov x8,x14
+ ldr x13,.Lpoly+24
+ mov x9,x15
+ ldp x4,x5,[x22,#64] // forward load for p256_sqr_mont
+ mov x10,x16
+ mov x11,x17
+ ldp x6,x7,[x22,#64+16]
+ add x0,sp,#0
+ bl __ecp_nistz256_add // p256_mul_by_2(S, in_y);
+
+ add x0,sp,#64
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Zsqr, in_z);
+
+ ldp x8,x9,[x22]
+ ldp x10,x11,[x22,#16]
+ mov x4,x14 // put Zsqr aside for p256_sub
+ mov x5,x15
+ mov x6,x16
+ mov x7,x17
+ add x0,sp,#32
+ bl __ecp_nistz256_add // p256_add(M, Zsqr, in_x);
+
+ add x2,x22,#0
+ mov x14,x4 // restore Zsqr
+ mov x15,x5
+ ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont
+ mov x16,x6
+ mov x17,x7
+ ldp x6,x7,[sp,#0+16]
+ add x0,sp,#64
+ bl __ecp_nistz256_sub_morf // p256_sub(Zsqr, in_x, Zsqr);
+
+ add x0,sp,#0
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(S, S);
+
+ ldr x3,[x22,#32]
+ ldp x4,x5,[x22,#64]
+ ldp x6,x7,[x22,#64+16]
+ add x2,x22,#32
+ add x0,sp,#96
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(tmp0, in_z, in_y);
+
+ mov x8,x14
+ mov x9,x15
+ ldp x4,x5,[sp,#0] // forward load for p256_sqr_mont
+ mov x10,x16
+ mov x11,x17
+ ldp x6,x7,[sp,#0+16]
+ add x0,x21,#64
+ bl __ecp_nistz256_add // p256_mul_by_2(res_z, tmp0);
+
+ add x0,sp,#96
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(tmp0, S);
+
+ ldr x3,[sp,#64] // forward load for p256_mul_mont
+ ldp x4,x5,[sp,#32]
+ ldp x6,x7,[sp,#32+16]
+ add x0,x21,#32
+ bl __ecp_nistz256_div_by_2 // p256_div_by_2(res_y, tmp0);
+
+ add x2,sp,#64
+ add x0,sp,#32
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(M, M, Zsqr);
+
+ mov x8,x14 // duplicate M
+ mov x9,x15
+ mov x10,x16
+ mov x11,x17
+ mov x4,x14 // put M aside
+ mov x5,x15
+ mov x6,x16
+ mov x7,x17
+ add x0,sp,#32
+ bl __ecp_nistz256_add
+ mov x8,x4 // restore M
+ mov x9,x5
+ ldr x3,[x22] // forward load for p256_mul_mont
+ mov x10,x6
+ ldp x4,x5,[sp,#0]
+ mov x11,x7
+ ldp x6,x7,[sp,#0+16]
+ bl __ecp_nistz256_add // p256_mul_by_3(M, M);
+
+ add x2,x22,#0
+ add x0,sp,#0
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, in_x);
+
+ mov x8,x14
+ mov x9,x15
+ ldp x4,x5,[sp,#32] // forward load for p256_sqr_mont
+ mov x10,x16
+ mov x11,x17
+ ldp x6,x7,[sp,#32+16]
+ add x0,sp,#96
+ bl __ecp_nistz256_add // p256_mul_by_2(tmp0, S);
+
+ add x0,x21,#0
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(res_x, M);
+
+ add x2,sp,#96
+ bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, tmp0);
+
+ add x2,sp,#0
+ add x0,sp,#0
+ bl __ecp_nistz256_sub_morf // p256_sub(S, S, res_x);
+
+ ldr x3,[sp,#32]
+ mov x4,x14 // copy S
+ mov x5,x15
+ mov x6,x16
+ mov x7,x17
+ add x2,sp,#32
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, M);
+
+ add x2,x21,#32
+ add x0,x21,#32
+ bl __ecp_nistz256_sub_from // p256_sub(res_y, S, res_y);
+
+ add sp,x29,#0 // destroy frame
+ ldp x19,x20,[x29,#16]
+ ldp x21,x22,[x29,#32]
+ ldp x29,x30,[sp],#96
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_point_double,.-ecp_nistz256_point_double
+.globl ecp_nistz256_point_add
+.type ecp_nistz256_point_add,%function
+.align 5
+ecp_nistz256_point_add:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ sub sp,sp,#32*12
+
+ ldp x4,x5,[x2,#64] // in2_z
+ ldp x6,x7,[x2,#64+16]
+ mov x21,x0
+ mov x22,x1
+ mov x23,x2
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+ orr x8,x4,x5
+ orr x10,x6,x7
+ orr x25,x8,x10
+ cmp x25,#0
+ csetm x25,ne // ~in2infty
+ add x0,sp,#192
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z);
+
+ ldp x4,x5,[x22,#64] // in1_z
+ ldp x6,x7,[x22,#64+16]
+ orr x8,x4,x5
+ orr x10,x6,x7
+ orr x24,x8,x10
+ cmp x24,#0
+ csetm x24,ne // ~in1infty
+ add x0,sp,#128
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z);
+
+ ldr x3,[x23,#64]
+ ldp x4,x5,[sp,#192]
+ ldp x6,x7,[sp,#192+16]
+ add x2,x23,#64
+ add x0,sp,#320
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, Z2sqr, in2_z);
+
+ ldr x3,[x22,#64]
+ ldp x4,x5,[sp,#128]
+ ldp x6,x7,[sp,#128+16]
+ add x2,x22,#64
+ add x0,sp,#352
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z);
+
+ ldr x3,[x22,#32]
+ ldp x4,x5,[sp,#320]
+ ldp x6,x7,[sp,#320+16]
+ add x2,x22,#32
+ add x0,sp,#320
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, S1, in1_y);
+
+ ldr x3,[x23,#32]
+ ldp x4,x5,[sp,#352]
+ ldp x6,x7,[sp,#352+16]
+ add x2,x23,#32
+ add x0,sp,#352
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y);
+
+ add x2,sp,#320
+ ldr x3,[sp,#192] // forward load for p256_mul_mont
+ ldp x4,x5,[x22]
+ ldp x6,x7,[x22,#16]
+ add x0,sp,#160
+ bl __ecp_nistz256_sub_from // p256_sub(R, S2, S1);
+
+ orr x14,x14,x15 // see if result is zero
+ orr x16,x16,x17
+ orr x26,x14,x16 // ~is_equal(S1,S2)
+
+ add x2,sp,#192
+ add x0,sp,#256
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(U1, in1_x, Z2sqr);
+
+ ldr x3,[sp,#128]
+ ldp x4,x5,[x23]
+ ldp x6,x7,[x23,#16]
+ add x2,sp,#128
+ add x0,sp,#288
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in2_x, Z1sqr);
+
+ add x2,sp,#256
+ ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont
+ ldp x6,x7,[sp,#160+16]
+ add x0,sp,#96
+ bl __ecp_nistz256_sub_from // p256_sub(H, U2, U1);
+
+ orr x14,x14,x15 // see if result is zero
+ orr x16,x16,x17
+ orr x14,x14,x16 // ~is_equal(U1,U2)
+
+ mvn x27,x24 // -1/0 -> 0/-1
+ mvn x28,x25 // -1/0 -> 0/-1
+ orr x14,x14,x27
+ orr x14,x14,x28
+ orr x14,x14,x26
+ cbnz x14,.Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2))
+
+.Ladd_double:
+ mov x1,x22
+ mov x0,x21
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ add sp,sp,#32*(12-4) // difference in stack frames
+ b .Ldouble_shortcut
+
+.align 4
+.Ladd_proceed:
+ add x0,sp,#192
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R);
+
+ ldr x3,[x22,#64]
+ ldp x4,x5,[sp,#96]
+ ldp x6,x7,[sp,#96+16]
+ add x2,x22,#64
+ add x0,sp,#64
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z);
+
+ ldp x4,x5,[sp,#96]
+ ldp x6,x7,[sp,#96+16]
+ add x0,sp,#128
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H);
+
+ ldr x3,[x23,#64]
+ ldp x4,x5,[sp,#64]
+ ldp x6,x7,[sp,#64+16]
+ add x2,x23,#64
+ add x0,sp,#64
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, res_z, in2_z);
+
+ ldr x3,[sp,#96]
+ ldp x4,x5,[sp,#128]
+ ldp x6,x7,[sp,#128+16]
+ add x2,sp,#96
+ add x0,sp,#224
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H);
+
+ ldr x3,[sp,#128]
+ ldp x4,x5,[sp,#256]
+ ldp x6,x7,[sp,#256+16]
+ add x2,sp,#128
+ add x0,sp,#288
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, U1, Hsqr);
+
+ mov x8,x14
+ mov x9,x15
+ mov x10,x16
+ mov x11,x17
+ add x0,sp,#128
+ bl __ecp_nistz256_add // p256_mul_by_2(Hsqr, U2);
+
+ add x2,sp,#192
+ add x0,sp,#0
+ bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr);
+
+ add x2,sp,#224
+ bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub);
+
+ add x2,sp,#288
+ ldr x3,[sp,#224] // forward load for p256_mul_mont
+ ldp x4,x5,[sp,#320]
+ ldp x6,x7,[sp,#320+16]
+ add x0,sp,#32
+ bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x);
+
+ add x2,sp,#224
+ add x0,sp,#352
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S1, Hcub);
+
+ ldr x3,[sp,#160]
+ ldp x4,x5,[sp,#32]
+ ldp x6,x7,[sp,#32+16]
+ add x2,sp,#160
+ add x0,sp,#32
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R);
+
+ add x2,sp,#352
+ bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2);
+
+ ldp x4,x5,[sp,#0] // res
+ ldp x6,x7,[sp,#0+16]
+ ldp x8,x9,[x23] // in2
+ ldp x10,x11,[x23,#16]
+ ldp x14,x15,[x22,#0] // in1
+ cmp x24,#0 // ~, remember?
+ ldp x16,x17,[x22,#0+16]
+ csel x8,x4,x8,ne
+ csel x9,x5,x9,ne
+ ldp x4,x5,[sp,#0+0+32] // res
+ csel x10,x6,x10,ne
+ csel x11,x7,x11,ne
+ cmp x25,#0 // ~, remember?
+ ldp x6,x7,[sp,#0+0+48]
+ csel x14,x8,x14,ne
+ csel x15,x9,x15,ne
+ ldp x8,x9,[x23,#0+32] // in2
+ csel x16,x10,x16,ne
+ csel x17,x11,x17,ne
+ ldp x10,x11,[x23,#0+48]
+ stp x14,x15,[x21,#0]
+ stp x16,x17,[x21,#0+16]
+ ldp x14,x15,[x22,#32] // in1
+ cmp x24,#0 // ~, remember?
+ ldp x16,x17,[x22,#32+16]
+ csel x8,x4,x8,ne
+ csel x9,x5,x9,ne
+ ldp x4,x5,[sp,#0+32+32] // res
+ csel x10,x6,x10,ne
+ csel x11,x7,x11,ne
+ cmp x25,#0 // ~, remember?
+ ldp x6,x7,[sp,#0+32+48]
+ csel x14,x8,x14,ne
+ csel x15,x9,x15,ne
+ ldp x8,x9,[x23,#32+32] // in2
+ csel x16,x10,x16,ne
+ csel x17,x11,x17,ne
+ ldp x10,x11,[x23,#32+48]
+ stp x14,x15,[x21,#32]
+ stp x16,x17,[x21,#32+16]
+ ldp x14,x15,[x22,#64] // in1
+ cmp x24,#0 // ~, remember?
+ ldp x16,x17,[x22,#64+16]
+ csel x8,x4,x8,ne
+ csel x9,x5,x9,ne
+ csel x10,x6,x10,ne
+ csel x11,x7,x11,ne
+ cmp x25,#0 // ~, remember?
+ csel x14,x8,x14,ne
+ csel x15,x9,x15,ne
+ csel x16,x10,x16,ne
+ csel x17,x11,x17,ne
+ stp x14,x15,[x21,#64]
+ stp x16,x17,[x21,#64+16]
+
+.Ladd_done:
+ add sp,x29,#0 // destroy frame
+ ldp x19,x20,[x29,#16]
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_point_add,.-ecp_nistz256_point_add
+.globl ecp_nistz256_point_add_affine
+.type ecp_nistz256_point_add_affine,%function
+.align 5
+ecp_nistz256_point_add_affine:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-80]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ sub sp,sp,#32*10
+
+ mov x21,x0
+ mov x22,x1
+ mov x23,x2
+ ldr x12,.Lpoly+8
+ ldr x13,.Lpoly+24
+
+ ldp x4,x5,[x1,#64] // in1_z
+ ldp x6,x7,[x1,#64+16]
+ orr x8,x4,x5
+ orr x10,x6,x7
+ orr x24,x8,x10
+ cmp x24,#0
+ csetm x24,ne // ~in1infty
+
+ ldp x14,x15,[x2] // in2_x
+ ldp x16,x17,[x2,#16]
+ ldp x8,x9,[x2,#32] // in2_y
+ ldp x10,x11,[x2,#48]
+ orr x14,x14,x15
+ orr x16,x16,x17
+ orr x8,x8,x9
+ orr x10,x10,x11
+ orr x14,x14,x16
+ orr x8,x8,x10
+ orr x25,x14,x8
+ cmp x25,#0
+ csetm x25,ne // ~in2infty
+
+ add x0,sp,#128
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z);
+
+ mov x4,x14
+ mov x5,x15
+ mov x6,x16
+ mov x7,x17
+ ldr x3,[x23]
+ add x2,x23,#0
+ add x0,sp,#96
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, Z1sqr, in2_x);
+
+ add x2,x22,#0
+ ldr x3,[x22,#64] // forward load for p256_mul_mont
+ ldp x4,x5,[sp,#128]
+ ldp x6,x7,[sp,#128+16]
+ add x0,sp,#160
+ bl __ecp_nistz256_sub_from // p256_sub(H, U2, in1_x);
+
+ add x2,x22,#64
+ add x0,sp,#128
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z);
+
+ ldr x3,[x22,#64]
+ ldp x4,x5,[sp,#160]
+ ldp x6,x7,[sp,#160+16]
+ add x2,x22,#64
+ add x0,sp,#64
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z);
+
+ ldr x3,[x23,#32]
+ ldp x4,x5,[sp,#128]
+ ldp x6,x7,[sp,#128+16]
+ add x2,x23,#32
+ add x0,sp,#128
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y);
+
+ add x2,x22,#32
+ ldp x4,x5,[sp,#160] // forward load for p256_sqr_mont
+ ldp x6,x7,[sp,#160+16]
+ add x0,sp,#192
+ bl __ecp_nistz256_sub_from // p256_sub(R, S2, in1_y);
+
+ add x0,sp,#224
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H);
+
+ ldp x4,x5,[sp,#192]
+ ldp x6,x7,[sp,#192+16]
+ add x0,sp,#288
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R);
+
+ ldr x3,[sp,#160]
+ ldp x4,x5,[sp,#224]
+ ldp x6,x7,[sp,#224+16]
+ add x2,sp,#160
+ add x0,sp,#256
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H);
+
+ ldr x3,[x22]
+ ldp x4,x5,[sp,#224]
+ ldp x6,x7,[sp,#224+16]
+ add x2,x22,#0
+ add x0,sp,#96
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in1_x, Hsqr);
+
+ mov x8,x14
+ mov x9,x15
+ mov x10,x16
+ mov x11,x17
+ add x0,sp,#224
+ bl __ecp_nistz256_add // p256_mul_by_2(Hsqr, U2);
+
+ add x2,sp,#288
+ add x0,sp,#0
+ bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr);
+
+ add x2,sp,#256
+ bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub);
+
+ add x2,sp,#96
+ ldr x3,[x22,#32] // forward load for p256_mul_mont
+ ldp x4,x5,[sp,#256]
+ ldp x6,x7,[sp,#256+16]
+ add x0,sp,#32
+ bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x);
+
+ add x2,x22,#32
+ add x0,sp,#128
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, in1_y, Hcub);
+
+ ldr x3,[sp,#192]
+ ldp x4,x5,[sp,#32]
+ ldp x6,x7,[sp,#32+16]
+ add x2,sp,#192
+ add x0,sp,#32
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R);
+
+ add x2,sp,#128
+ bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2);
+
+ ldp x4,x5,[sp,#0] // res
+ ldp x6,x7,[sp,#0+16]
+ ldp x8,x9,[x23] // in2
+ ldp x10,x11,[x23,#16]
+ ldp x14,x15,[x22,#0] // in1
+ cmp x24,#0 // ~, remember?
+ ldp x16,x17,[x22,#0+16]
+ csel x8,x4,x8,ne
+ csel x9,x5,x9,ne
+ ldp x4,x5,[sp,#0+0+32] // res
+ csel x10,x6,x10,ne
+ csel x11,x7,x11,ne
+ cmp x25,#0 // ~, remember?
+ ldp x6,x7,[sp,#0+0+48]
+ csel x14,x8,x14,ne
+ csel x15,x9,x15,ne
+ ldp x8,x9,[x23,#0+32] // in2
+ csel x16,x10,x16,ne
+ csel x17,x11,x17,ne
+ ldp x10,x11,[x23,#0+48]
+ stp x14,x15,[x21,#0]
+ stp x16,x17,[x21,#0+16]
+ adr x23,.Lone_mont-64
+ ldp x14,x15,[x22,#32] // in1
+ cmp x24,#0 // ~, remember?
+ ldp x16,x17,[x22,#32+16]
+ csel x8,x4,x8,ne
+ csel x9,x5,x9,ne
+ ldp x4,x5,[sp,#0+32+32] // res
+ csel x10,x6,x10,ne
+ csel x11,x7,x11,ne
+ cmp x25,#0 // ~, remember?
+ ldp x6,x7,[sp,#0+32+48]
+ csel x14,x8,x14,ne
+ csel x15,x9,x15,ne
+ ldp x8,x9,[x23,#32+32] // in2
+ csel x16,x10,x16,ne
+ csel x17,x11,x17,ne
+ ldp x10,x11,[x23,#32+48]
+ stp x14,x15,[x21,#32]
+ stp x16,x17,[x21,#32+16]
+ ldp x14,x15,[x22,#64] // in1
+ cmp x24,#0 // ~, remember?
+ ldp x16,x17,[x22,#64+16]
+ csel x8,x4,x8,ne
+ csel x9,x5,x9,ne
+ csel x10,x6,x10,ne
+ csel x11,x7,x11,ne
+ cmp x25,#0 // ~, remember?
+ csel x14,x8,x14,ne
+ csel x15,x9,x15,ne
+ csel x16,x10,x16,ne
+ csel x17,x11,x17,ne
+ stp x14,x15,[x21,#64]
+ stp x16,x17,[x21,#64+16]
+
+ add sp,x29,#0 // destroy frame
+ ldp x19,x20,[x29,#16]
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x29,x30,[sp],#80
+.inst 0xd50323bf // autiasp
+ ret
+.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine
+////////////////////////////////////////////////////////////////////////
+// void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4],
+// uint64_t b[4]);
+.globl ecp_nistz256_ord_mul_mont
+.type ecp_nistz256_ord_mul_mont,%function
+.align 4
+ecp_nistz256_ord_mul_mont:
+ stp x29,x30,[sp,#-64]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+
+ adr x23,.Lord
+ ldr x3,[x2] // bp[0]
+ ldp x4,x5,[x1]
+ ldp x6,x7,[x1,#16]
+
+ ldp x12,x13,[x23,#0]
+ ldp x21,x22,[x23,#16]
+ ldr x23,[x23,#32]
+
+ mul x14,x4,x3 // a[0]*b[0]
+ umulh x8,x4,x3
+
+ mul x15,x5,x3 // a[1]*b[0]
+ umulh x9,x5,x3
+
+ mul x16,x6,x3 // a[2]*b[0]
+ umulh x10,x6,x3
+
+ mul x17,x7,x3 // a[3]*b[0]
+ umulh x19,x7,x3
+
+ mul x24,x14,x23
+
+ adds x15,x15,x8 // accumulate high parts of multiplication
+ adcs x16,x16,x9
+ adcs x17,x17,x10
+ adc x19,x19,xzr
+ mov x20,xzr
+ ldr x3,[x2,#8*1] // b[i]
+
+ lsl x8,x24,#32
+ subs x16,x16,x24
+ lsr x9,x24,#32
+ sbcs x17,x17,x8
+ sbcs x19,x19,x9
+ sbc x20,x20,xzr
+
+ subs xzr,x14,#1
+ umulh x9,x12,x24
+ mul x10,x13,x24
+ umulh x11,x13,x24
+
+ adcs x10,x10,x9
+ mul x8,x4,x3
+ adc x11,x11,xzr
+ mul x9,x5,x3
+
+ adds x14,x15,x10
+ mul x10,x6,x3
+ adcs x15,x16,x11
+ mul x11,x7,x3
+ adcs x16,x17,x24
+ adcs x17,x19,x24
+ adc x19,x20,xzr
+
+ adds x14,x14,x8 // accumulate low parts
+ umulh x8,x4,x3
+ adcs x15,x15,x9
+ umulh x9,x5,x3
+ adcs x16,x16,x10
+ umulh x10,x6,x3
+ adcs x17,x17,x11
+ umulh x11,x7,x3
+ adc x19,x19,xzr
+ mul x24,x14,x23
+ adds x15,x15,x8 // accumulate high parts
+ adcs x16,x16,x9
+ adcs x17,x17,x10
+ adcs x19,x19,x11
+ adc x20,xzr,xzr
+ ldr x3,[x2,#8*2] // b[i]
+
+ lsl x8,x24,#32
+ subs x16,x16,x24
+ lsr x9,x24,#32
+ sbcs x17,x17,x8
+ sbcs x19,x19,x9
+ sbc x20,x20,xzr
+
+ subs xzr,x14,#1
+ umulh x9,x12,x24
+ mul x10,x13,x24
+ umulh x11,x13,x24
+
+ adcs x10,x10,x9
+ mul x8,x4,x3
+ adc x11,x11,xzr
+ mul x9,x5,x3
+
+ adds x14,x15,x10
+ mul x10,x6,x3
+ adcs x15,x16,x11
+ mul x11,x7,x3
+ adcs x16,x17,x24
+ adcs x17,x19,x24
+ adc x19,x20,xzr
+
+ adds x14,x14,x8 // accumulate low parts
+ umulh x8,x4,x3
+ adcs x15,x15,x9
+ umulh x9,x5,x3
+ adcs x16,x16,x10
+ umulh x10,x6,x3
+ adcs x17,x17,x11
+ umulh x11,x7,x3
+ adc x19,x19,xzr
+ mul x24,x14,x23
+ adds x15,x15,x8 // accumulate high parts
+ adcs x16,x16,x9
+ adcs x17,x17,x10
+ adcs x19,x19,x11
+ adc x20,xzr,xzr
+ ldr x3,[x2,#8*3] // b[i]
+
+ lsl x8,x24,#32
+ subs x16,x16,x24
+ lsr x9,x24,#32
+ sbcs x17,x17,x8
+ sbcs x19,x19,x9
+ sbc x20,x20,xzr
+
+ subs xzr,x14,#1
+ umulh x9,x12,x24
+ mul x10,x13,x24
+ umulh x11,x13,x24
+
+ adcs x10,x10,x9
+ mul x8,x4,x3
+ adc x11,x11,xzr
+ mul x9,x5,x3
+
+ adds x14,x15,x10
+ mul x10,x6,x3
+ adcs x15,x16,x11
+ mul x11,x7,x3
+ adcs x16,x17,x24
+ adcs x17,x19,x24
+ adc x19,x20,xzr
+
+ adds x14,x14,x8 // accumulate low parts
+ umulh x8,x4,x3
+ adcs x15,x15,x9
+ umulh x9,x5,x3
+ adcs x16,x16,x10
+ umulh x10,x6,x3
+ adcs x17,x17,x11
+ umulh x11,x7,x3
+ adc x19,x19,xzr
+ mul x24,x14,x23
+ adds x15,x15,x8 // accumulate high parts
+ adcs x16,x16,x9
+ adcs x17,x17,x10
+ adcs x19,x19,x11
+ adc x20,xzr,xzr
+ lsl x8,x24,#32 // last reduction
+ subs x16,x16,x24
+ lsr x9,x24,#32
+ sbcs x17,x17,x8
+ sbcs x19,x19,x9
+ sbc x20,x20,xzr
+
+ subs xzr,x14,#1
+ umulh x9,x12,x24
+ mul x10,x13,x24
+ umulh x11,x13,x24
+
+ adcs x10,x10,x9
+ adc x11,x11,xzr
+
+ adds x14,x15,x10
+ adcs x15,x16,x11
+ adcs x16,x17,x24
+ adcs x17,x19,x24
+ adc x19,x20,xzr
+
+ subs x8,x14,x12 // ret -= modulus
+ sbcs x9,x15,x13
+ sbcs x10,x16,x21
+ sbcs x11,x17,x22
+ sbcs xzr,x19,xzr
+
+ csel x14,x14,x8,lo // ret = borrow ? ret : ret-modulus
+ csel x15,x15,x9,lo
+ csel x16,x16,x10,lo
+ stp x14,x15,[x0]
+ csel x17,x17,x11,lo
+ stp x16,x17,[x0,#16]
+
+ ldp x19,x20,[sp,#16]
+ ldp x21,x22,[sp,#32]
+ ldp x23,x24,[sp,#48]
+ ldr x29,[sp],#64
+ ret
+.size ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont
+
+////////////////////////////////////////////////////////////////////////
+// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4],
+// uint64_t rep);
+.globl ecp_nistz256_ord_sqr_mont
+.type ecp_nistz256_ord_sqr_mont,%function
+.align 4
+ecp_nistz256_ord_sqr_mont:
+ stp x29,x30,[sp,#-64]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+
+ adr x23,.Lord
+ ldp x4,x5,[x1]
+ ldp x6,x7,[x1,#16]
+
+ ldp x12,x13,[x23,#0]
+ ldp x21,x22,[x23,#16]
+ ldr x23,[x23,#32]
+ b .Loop_ord_sqr
+
+.align 4
+.Loop_ord_sqr:
+ sub x2,x2,#1
+ ////////////////////////////////////////////////////////////////
+ // | | | | | |a1*a0| |
+ // | | | | |a2*a0| | |
+ // | |a3*a2|a3*a0| | | |
+ // | | | |a2*a1| | | |
+ // | | |a3*a1| | | | |
+ // *| | | | | | | | 2|
+ // +|a3*a3|a2*a2|a1*a1|a0*a0|
+ // |--+--+--+--+--+--+--+--|
+ // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is , i.e. follow
+ //
+ // "can't overflow" below mark carrying into high part of
+ // multiplication result, which can't overflow, because it
+ // can never be all ones.
+
+ mul x15,x5,x4 // a[1]*a[0]
+ umulh x9,x5,x4
+ mul x16,x6,x4 // a[2]*a[0]
+ umulh x10,x6,x4
+ mul x17,x7,x4 // a[3]*a[0]
+ umulh x19,x7,x4
+
+ adds x16,x16,x9 // accumulate high parts of multiplication
+ mul x8,x6,x5 // a[2]*a[1]
+ umulh x9,x6,x5
+ adcs x17,x17,x10
+ mul x10,x7,x5 // a[3]*a[1]
+ umulh x11,x7,x5
+ adc x19,x19,xzr // can't overflow
+
+ mul x20,x7,x6 // a[3]*a[2]
+ umulh x1,x7,x6
+
+ adds x9,x9,x10 // accumulate high parts of multiplication
+ mul x14,x4,x4 // a[0]*a[0]
+ adc x10,x11,xzr // can't overflow
+
+ adds x17,x17,x8 // accumulate low parts of multiplication
+ umulh x4,x4,x4
+ adcs x19,x19,x9
+ mul x9,x5,x5 // a[1]*a[1]
+ adcs x20,x20,x10
+ umulh x5,x5,x5
+ adc x1,x1,xzr // can't overflow
+
+ adds x15,x15,x15 // acc[1-6]*=2
+ mul x10,x6,x6 // a[2]*a[2]
+ adcs x16,x16,x16
+ umulh x6,x6,x6
+ adcs x17,x17,x17
+ mul x11,x7,x7 // a[3]*a[3]
+ adcs x19,x19,x19
+ umulh x7,x7,x7
+ adcs x20,x20,x20
+ adcs x1,x1,x1
+ adc x3,xzr,xzr
+
+ adds x15,x15,x4 // +a[i]*a[i]
+ mul x24,x14,x23
+ adcs x16,x16,x9
+ adcs x17,x17,x5
+ adcs x19,x19,x10
+ adcs x20,x20,x6
+ adcs x1,x1,x11
+ adc x3,x3,x7
+ subs xzr,x14,#1
+ umulh x9,x12,x24
+ mul x10,x13,x24
+ umulh x11,x13,x24
+
+ adcs x10,x10,x9
+ adc x11,x11,xzr
+
+ adds x14,x15,x10
+ adcs x15,x16,x11
+ adcs x16,x17,x24
+ adc x17,xzr,x24 // can't overflow
+ mul x11,x14,x23
+ lsl x8,x24,#32
+ subs x15,x15,x24
+ lsr x9,x24,#32
+ sbcs x16,x16,x8
+ sbc x17,x17,x9 // can't borrow
+ subs xzr,x14,#1
+ umulh x9,x12,x11
+ mul x10,x13,x11
+ umulh x24,x13,x11
+
+ adcs x10,x10,x9
+ adc x24,x24,xzr
+
+ adds x14,x15,x10
+ adcs x15,x16,x24
+ adcs x16,x17,x11
+ adc x17,xzr,x11 // can't overflow
+ mul x24,x14,x23
+ lsl x8,x11,#32
+ subs x15,x15,x11
+ lsr x9,x11,#32
+ sbcs x16,x16,x8
+ sbc x17,x17,x9 // can't borrow
+ subs xzr,x14,#1
+ umulh x9,x12,x24
+ mul x10,x13,x24
+ umulh x11,x13,x24
+
+ adcs x10,x10,x9
+ adc x11,x11,xzr
+
+ adds x14,x15,x10
+ adcs x15,x16,x11
+ adcs x16,x17,x24
+ adc x17,xzr,x24 // can't overflow
+ mul x11,x14,x23
+ lsl x8,x24,#32
+ subs x15,x15,x24
+ lsr x9,x24,#32
+ sbcs x16,x16,x8
+ sbc x17,x17,x9 // can't borrow
+ subs xzr,x14,#1
+ umulh x9,x12,x11
+ mul x10,x13,x11
+ umulh x24,x13,x11
+
+ adcs x10,x10,x9
+ adc x24,x24,xzr
+
+ adds x14,x15,x10
+ adcs x15,x16,x24
+ adcs x16,x17,x11
+ adc x17,xzr,x11 // can't overflow
+ lsl x8,x11,#32
+ subs x15,x15,x11
+ lsr x9,x11,#32
+ sbcs x16,x16,x8
+ sbc x17,x17,x9 // can't borrow
+ adds x14,x14,x19 // accumulate upper half
+ adcs x15,x15,x20
+ adcs x16,x16,x1
+ adcs x17,x17,x3
+ adc x19,xzr,xzr
+
+ subs x8,x14,x12 // ret -= modulus
+ sbcs x9,x15,x13
+ sbcs x10,x16,x21
+ sbcs x11,x17,x22
+ sbcs xzr,x19,xzr
+
+ csel x4,x14,x8,lo // ret = borrow ? ret : ret-modulus
+ csel x5,x15,x9,lo
+ csel x6,x16,x10,lo
+ csel x7,x17,x11,lo
+
+ cbnz x2,.Loop_ord_sqr
+
+ stp x4,x5,[x0]
+ stp x6,x7,[x0,#16]
+
+ ldp x19,x20,[sp,#16]
+ ldp x21,x22,[sp,#32]
+ ldp x23,x24,[sp,#48]
+ ldr x29,[sp],#64
+ ret
+.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont
+// void ecp_nistz256_scatter_w5(void *x0,const P256_POINT *x1,
+// int x2);
+.globl ecp_nistz256_scatter_w5
+.type ecp_nistz256_scatter_w5,%function
+.align 4
+ecp_nistz256_scatter_w5:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ add x0,x0,x2,lsl#2
+
+ ldp x4,x5,[x1] // X
+ ldp x6,x7,[x1,#16]
+ stur w4,[x0,#64*0-4]
+ lsr x4,x4,#32
+ str w5,[x0,#64*1-4]
+ lsr x5,x5,#32
+ str w6,[x0,#64*2-4]
+ lsr x6,x6,#32
+ str w7,[x0,#64*3-4]
+ lsr x7,x7,#32
+ str w4,[x0,#64*4-4]
+ str w5,[x0,#64*5-4]
+ str w6,[x0,#64*6-4]
+ str w7,[x0,#64*7-4]
+ add x0,x0,#64*8
+
+ ldp x4,x5,[x1,#32] // Y
+ ldp x6,x7,[x1,#48]
+ stur w4,[x0,#64*0-4]
+ lsr x4,x4,#32
+ str w5,[x0,#64*1-4]
+ lsr x5,x5,#32
+ str w6,[x0,#64*2-4]
+ lsr x6,x6,#32
+ str w7,[x0,#64*3-4]
+ lsr x7,x7,#32
+ str w4,[x0,#64*4-4]
+ str w5,[x0,#64*5-4]
+ str w6,[x0,#64*6-4]
+ str w7,[x0,#64*7-4]
+ add x0,x0,#64*8
+
+ ldp x4,x5,[x1,#64] // Z
+ ldp x6,x7,[x1,#80]
+ stur w4,[x0,#64*0-4]
+ lsr x4,x4,#32
+ str w5,[x0,#64*1-4]
+ lsr x5,x5,#32
+ str w6,[x0,#64*2-4]
+ lsr x6,x6,#32
+ str w7,[x0,#64*3-4]
+ lsr x7,x7,#32
+ str w4,[x0,#64*4-4]
+ str w5,[x0,#64*5-4]
+ str w6,[x0,#64*6-4]
+ str w7,[x0,#64*7-4]
+
+ ldr x29,[sp],#16
+ ret
+.size ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5
+
+// void ecp_nistz256_gather_w5(P256_POINT *x0,const void *x1,
+// int x2);
+.globl ecp_nistz256_gather_w5
+.type ecp_nistz256_gather_w5,%function
+.align 4
+ecp_nistz256_gather_w5:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ cmp x2,xzr
+ csetm x3,ne
+ add x2,x2,x3
+ add x1,x1,x2,lsl#2
+
+ ldr w4,[x1,#64*0]
+ ldr w5,[x1,#64*1]
+ ldr w6,[x1,#64*2]
+ ldr w7,[x1,#64*3]
+ ldr w8,[x1,#64*4]
+ ldr w9,[x1,#64*5]
+ ldr w10,[x1,#64*6]
+ ldr w11,[x1,#64*7]
+ add x1,x1,#64*8
+ orr x4,x4,x8,lsl#32
+ orr x5,x5,x9,lsl#32
+ orr x6,x6,x10,lsl#32
+ orr x7,x7,x11,lsl#32
+ csel x4,x4,xzr,ne
+ csel x5,x5,xzr,ne
+ csel x6,x6,xzr,ne
+ csel x7,x7,xzr,ne
+ stp x4,x5,[x0] // X
+ stp x6,x7,[x0,#16]
+
+ ldr w4,[x1,#64*0]
+ ldr w5,[x1,#64*1]
+ ldr w6,[x1,#64*2]
+ ldr w7,[x1,#64*3]
+ ldr w8,[x1,#64*4]
+ ldr w9,[x1,#64*5]
+ ldr w10,[x1,#64*6]
+ ldr w11,[x1,#64*7]
+ add x1,x1,#64*8
+ orr x4,x4,x8,lsl#32
+ orr x5,x5,x9,lsl#32
+ orr x6,x6,x10,lsl#32
+ orr x7,x7,x11,lsl#32
+ csel x4,x4,xzr,ne
+ csel x5,x5,xzr,ne
+ csel x6,x6,xzr,ne
+ csel x7,x7,xzr,ne
+ stp x4,x5,[x0,#32] // Y
+ stp x6,x7,[x0,#48]
+
+ ldr w4,[x1,#64*0]
+ ldr w5,[x1,#64*1]
+ ldr w6,[x1,#64*2]
+ ldr w7,[x1,#64*3]
+ ldr w8,[x1,#64*4]
+ ldr w9,[x1,#64*5]
+ ldr w10,[x1,#64*6]
+ ldr w11,[x1,#64*7]
+ orr x4,x4,x8,lsl#32
+ orr x5,x5,x9,lsl#32
+ orr x6,x6,x10,lsl#32
+ orr x7,x7,x11,lsl#32
+ csel x4,x4,xzr,ne
+ csel x5,x5,xzr,ne
+ csel x6,x6,xzr,ne
+ csel x7,x7,xzr,ne
+ stp x4,x5,[x0,#64] // Z
+ stp x6,x7,[x0,#80]
+
+ ldr x29,[sp],#16
+ ret
+.size ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5
+
+// void ecp_nistz256_scatter_w7(void *x0,const P256_POINT_AFFINE *x1,
+// int x2);
+.globl ecp_nistz256_scatter_w7
+.type ecp_nistz256_scatter_w7,%function
+.align 4
+ecp_nistz256_scatter_w7:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ add x0,x0,x2
+ mov x2,#64/8
+.Loop_scatter_w7:
+ ldr x3,[x1],#8
+ subs x2,x2,#1
+ prfm pstl1strm,[x0,#4096+64*0]
+ prfm pstl1strm,[x0,#4096+64*1]
+ prfm pstl1strm,[x0,#4096+64*2]
+ prfm pstl1strm,[x0,#4096+64*3]
+ prfm pstl1strm,[x0,#4096+64*4]
+ prfm pstl1strm,[x0,#4096+64*5]
+ prfm pstl1strm,[x0,#4096+64*6]
+ prfm pstl1strm,[x0,#4096+64*7]
+ strb w3,[x0,#64*0]
+ lsr x3,x3,#8
+ strb w3,[x0,#64*1]
+ lsr x3,x3,#8
+ strb w3,[x0,#64*2]
+ lsr x3,x3,#8
+ strb w3,[x0,#64*3]
+ lsr x3,x3,#8
+ strb w3,[x0,#64*4]
+ lsr x3,x3,#8
+ strb w3,[x0,#64*5]
+ lsr x3,x3,#8
+ strb w3,[x0,#64*6]
+ lsr x3,x3,#8
+ strb w3,[x0,#64*7]
+ add x0,x0,#64*8
+ b.ne .Loop_scatter_w7
+
+ ldr x29,[sp],#16
+ ret
+.size ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7
+
+// void ecp_nistz256_gather_w7(P256_POINT_AFFINE *x0,const void *x1,
+// int x2);
+.globl ecp_nistz256_gather_w7
+.type ecp_nistz256_gather_w7,%function
+.align 4
+ecp_nistz256_gather_w7:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ cmp x2,xzr
+ csetm x3,ne
+ add x2,x2,x3
+ add x1,x1,x2
+ mov x2,#64/8
+ nop
+.Loop_gather_w7:
+ ldrb w4,[x1,#64*0]
+ prfm pldl1strm,[x1,#4096+64*0]
+ subs x2,x2,#1
+ ldrb w5,[x1,#64*1]
+ prfm pldl1strm,[x1,#4096+64*1]
+ ldrb w6,[x1,#64*2]
+ prfm pldl1strm,[x1,#4096+64*2]
+ ldrb w7,[x1,#64*3]
+ prfm pldl1strm,[x1,#4096+64*3]
+ ldrb w8,[x1,#64*4]
+ prfm pldl1strm,[x1,#4096+64*4]
+ ldrb w9,[x1,#64*5]
+ prfm pldl1strm,[x1,#4096+64*5]
+ ldrb w10,[x1,#64*6]
+ prfm pldl1strm,[x1,#4096+64*6]
+ ldrb w11,[x1,#64*7]
+ prfm pldl1strm,[x1,#4096+64*7]
+ add x1,x1,#64*8
+ orr x4,x4,x5,lsl#8
+ orr x6,x6,x7,lsl#8
+ orr x8,x8,x9,lsl#8
+ orr x4,x4,x6,lsl#16
+ orr x10,x10,x11,lsl#8
+ orr x4,x4,x8,lsl#32
+ orr x4,x4,x10,lsl#48
+ and x4,x4,x3
+ str x4,[x0],#8
+ b.ne .Loop_gather_w7
+
+ ldr x29,[sp],#16
+ ret
+.size ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S
new file mode 100644
index 0000000..6b0bda3
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S
@@ -0,0 +1,6389 @@
+#include "arm_arch.h"
+
+#if __ARM_MAX_ARCH__>=8
+.arch armv8-a+crypto
+.text
+.globl aes_gcm_enc_128_kernel
+.type aes_gcm_enc_128_kernel,%function
+.align 4
+aes_gcm_enc_128_kernel:
+ cbz x1, .L128_enc_ret
+ stp x19, x20, [sp, #-112]!
+ mov x16, x4
+ mov x8, x5
+ stp x21, x22, [sp, #16]
+ stp x23, x24, [sp, #32]
+ stp d8, d9, [sp, #48]
+ stp d10, d11, [sp, #64]
+ stp d12, d13, [sp, #80]
+ stp d14, d15, [sp, #96]
+
+ ldp x10, x11, [x16] //ctr96_b64, ctr96_t32
+#ifdef __AARCH64EB__
+ rev x10, x10
+ rev x11, x11
+#endif
+ ldp x13, x14, [x8, #160] //load rk10
+#ifdef __AARCH64EB__
+ ror x13, x13, #32
+ ror x14, x14, #32
+#endif
+ ld1 {v11.16b}, [x3]
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+ lsr x5, x1, #3 //byte_len
+ mov x15, x5
+
+ ld1 {v18.4s}, [x8], #16 //load rk0
+ add x4, x0, x1, lsr #3 //end_input_ptr
+ sub x5, x5, #1 //byte_len - 1
+
+ lsr x12, x11, #32
+ ldr q15, [x3, #112] //load h4l | h4h
+#ifndef __AARCH64EB__
+ ext v15.16b, v15.16b, v15.16b, #8
+#endif
+ fmov d1, x10 //CTR block 1
+ rev w12, w12 //rev_ctr32
+
+ add w12, w12, #1 //increment rev_ctr32
+ orr w11, w11, w11
+ ld1 {v19.4s}, [x8], #16 //load rk1
+
+ rev w9, w12 //CTR block 1
+ add w12, w12, #1 //CTR block 1
+ fmov d3, x10 //CTR block 3
+
+ orr x9, x11, x9, lsl #32 //CTR block 1
+ ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible
+
+ fmov v1.d[1], x9 //CTR block 1
+ rev w9, w12 //CTR block 2
+
+ fmov d2, x10 //CTR block 2
+ orr x9, x11, x9, lsl #32 //CTR block 2
+ add w12, w12, #1 //CTR block 2
+
+ fmov v2.d[1], x9 //CTR block 2
+ rev w9, w12 //CTR block 3
+
+ orr x9, x11, x9, lsl #32 //CTR block 3
+ ld1 {v20.4s}, [x8], #16 //load rk2
+
+ add w12, w12, #1 //CTR block 3
+ fmov v3.d[1], x9 //CTR block 3
+
+ ldr q14, [x3, #80] //load h3l | h3h
+#ifndef __AARCH64EB__
+ ext v14.16b, v14.16b, v14.16b, #8
+#endif
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 0
+ ld1 {v21.4s}, [x8], #16 //load rk3
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 0
+ ldr q12, [x3, #32] //load h1l | h1h
+#ifndef __AARCH64EB__
+ ext v12.16b, v12.16b, v12.16b, #8
+#endif
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 0
+ ld1 {v22.4s}, [x8], #16 //load rk4
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 0
+ ld1 {v23.4s}, [x8], #16 //load rk5
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 1
+ trn2 v17.2d, v14.2d, v15.2d //h4l | h3l
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 1
+ ld1 {v24.4s}, [x8], #16 //load rk6
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 1
+ ld1 {v25.4s}, [x8], #16 //load rk7
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 1
+ trn1 v9.2d, v14.2d, v15.2d //h4h | h3h
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 2
+ ld1 {v26.4s}, [x8], #16 //load rk8
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 2
+ ldr q13, [x3, #64] //load h2l | h2h
+#ifndef __AARCH64EB__
+ ext v13.16b, v13.16b, v13.16b, #8
+#endif
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 2
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 2
+ eor v17.16b, v17.16b, v9.16b //h4k | h3k
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 3
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 3
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 3
+ ld1 {v27.4s}, [x8], #16 //load rk9
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 3
+
+ and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail)
+ trn2 v16.2d, v12.2d, v13.2d //h2l | h1l
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 4
+ add x5, x5, x0
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 4
+ cmp x0, x5 //check if we have <= 4 blocks
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 4
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 5
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 5
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 5
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 6
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 4
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 6
+ trn1 v8.2d, v12.2d, v13.2d //h2h | h1h
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 6
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 5
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 7
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 7
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 6
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 7
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 8
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 7
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 8
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 8
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 8
+
+ aese v2.16b, v27.16b //AES block 2 - round 9
+
+ aese v0.16b, v27.16b //AES block 0 - round 9
+
+ eor v16.16b, v16.16b, v8.16b //h2k | h1k
+
+ aese v1.16b, v27.16b //AES block 1 - round 9
+
+ aese v3.16b, v27.16b //AES block 3 - round 9
+ b.ge .L128_enc_tail //handle tail
+
+ ldp x6, x7, [x0, #0] //AES block 0 - load plaintext
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ ldp x21, x22, [x0, #32] //AES block 2 - load plaintext
+#ifdef __AARCH64EB__
+ rev x21, x21
+ rev x22, x22
+#endif
+ ldp x19, x20, [x0, #16] //AES block 1 - load plaintext
+#ifdef __AARCH64EB__
+ rev x19, x19
+ rev x20, x20
+#endif
+ ldp x23, x24, [x0, #48] //AES block 3 - load plaintext
+#ifdef __AARCH64EB__
+ rev x23, x23
+ rev x24, x24
+#endif
+ eor x6, x6, x13 //AES block 0 - round 10 low
+ eor x7, x7, x14 //AES block 0 - round 10 high
+
+ eor x21, x21, x13 //AES block 2 - round 10 low
+ fmov d4, x6 //AES block 0 - mov low
+
+ eor x19, x19, x13 //AES block 1 - round 10 low
+ eor x22, x22, x14 //AES block 2 - round 10 high
+ fmov v4.d[1], x7 //AES block 0 - mov high
+
+ fmov d5, x19 //AES block 1 - mov low
+ eor x20, x20, x14 //AES block 1 - round 10 high
+
+ eor x23, x23, x13 //AES block 3 - round 10 low
+ fmov v5.d[1], x20 //AES block 1 - mov high
+
+ fmov d6, x21 //AES block 2 - mov low
+ eor x24, x24, x14 //AES block 3 - round 10 high
+ rev w9, w12 //CTR block 4
+
+ fmov v6.d[1], x22 //AES block 2 - mov high
+ orr x9, x11, x9, lsl #32 //CTR block 4
+
+ eor v4.16b, v4.16b, v0.16b //AES block 0 - result
+ fmov d0, x10 //CTR block 4
+ add w12, w12, #1 //CTR block 4
+
+ fmov v0.d[1], x9 //CTR block 4
+ rev w9, w12 //CTR block 5
+
+ eor v5.16b, v5.16b, v1.16b //AES block 1 - result
+ fmov d1, x10 //CTR block 5
+ orr x9, x11, x9, lsl #32 //CTR block 5
+
+ add w12, w12, #1 //CTR block 5
+ add x0, x0, #64 //AES input_ptr update
+ fmov v1.d[1], x9 //CTR block 5
+
+ fmov d7, x23 //AES block 3 - mov low
+ rev w9, w12 //CTR block 6
+ st1 { v4.16b}, [x2], #16 //AES block 0 - store result
+
+ fmov v7.d[1], x24 //AES block 3 - mov high
+ orr x9, x11, x9, lsl #32 //CTR block 6
+
+ add w12, w12, #1 //CTR block 6
+ eor v6.16b, v6.16b, v2.16b //AES block 2 - result
+ st1 { v5.16b}, [x2], #16 //AES block 1 - store result
+
+ fmov d2, x10 //CTR block 6
+ cmp x0, x5 //check if we have <= 8 blocks
+
+ fmov v2.d[1], x9 //CTR block 6
+ rev w9, w12 //CTR block 7
+ st1 { v6.16b}, [x2], #16 //AES block 2 - store result
+
+ orr x9, x11, x9, lsl #32 //CTR block 7
+
+ eor v7.16b, v7.16b, v3.16b //AES block 3 - result
+ st1 { v7.16b}, [x2], #16 //AES block 3 - store result
+ b.ge .L128_enc_prepretail //do prepretail
+
+.L128_enc_main_loop: //main loop start
+ ldp x23, x24, [x0, #48] //AES block 4k+3 - load plaintext
+#ifdef __AARCH64EB__
+ rev x23, x23
+ rev x24, x24
+#endif
+ rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free)
+ rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free)
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+ fmov d3, x10 //CTR block 4k+3
+
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+ rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free)
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ add w12, w12, #1 //CTR block 4k+3
+ fmov v3.d[1], x9 //CTR block 4k+3
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+ mov d31, v6.d[1] //GHASH block 4k+2 - mid
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+ mov d30, v5.d[1] //GHASH block 4k+1 - mid
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+ eor x24, x24, x14 //AES block 4k+3 - round 10 high
+
+ pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+ eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid
+ ldp x6, x7, [x0, #0] //AES block 4k+4 - load plaintext
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+ rev w9, w12 //CTR block 4k+8
+
+ eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid
+ mov d8, v4.d[1] //GHASH block 4k - mid
+ orr x9, x11, x9, lsl #32 //CTR block 4k+8
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+ add w12, w12, #1 //CTR block 4k+8
+ mov d10, v17.d[1] //GHASH block 4k - mid
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+ eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high
+
+ pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+ rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free)
+
+ pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid
+
+ pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+ ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid
+
+ pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+ eor x7, x7, x14 //AES block 4k+4 - round 10 high
+
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid
+ mov d30, v7.d[1] //GHASH block 4k+3 - mid
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+ eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+ eor x6, x6, x13 //AES block 4k+4 - round 10 low
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+ eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid
+
+ pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+ eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high
+
+ pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid
+
+ pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+ movi v8.8b, #0xc2
+
+ pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid
+ eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+ shl d8, d8, #56 //mod_constant
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+ ldp x19, x20, [x0, #16] //AES block 4k+5 - load plaintext
+#ifdef __AARCH64EB__
+ rev x19, x19
+ rev x20, x20
+#endif
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+ eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+ ldp x21, x22, [x0, #32] //AES block 4k+6 - load plaintext
+#ifdef __AARCH64EB__
+ rev x21, x21
+ rev x22, x22
+#endif
+ pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+ eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+ eor x19, x19, x13 //AES block 4k+5 - round 10 low
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+ eor x23, x23, x13 //AES block 4k+3 - round 10 low
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+ eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ fmov d4, x6 //AES block 4k+4 - mov low
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+ fmov v4.d[1], x7 //AES block 4k+4 - mov high
+
+ add x0, x0, #64 //AES input_ptr update
+ fmov d7, x23 //AES block 4k+3 - mov low
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+ fmov d5, x19 //AES block 4k+5 - mov low
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+ eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+ eor x20, x20, x14 //AES block 4k+5 - round 10 high
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+ fmov v5.d[1], x20 //AES block 4k+5 - mov high
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+ fmov v7.d[1], x24 //AES block 4k+3 - mov high
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+ cmp x0, x5 //.LOOP CONTROL
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+ eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid
+
+ aese v0.16b, v27.16b //AES block 4k+4 - round 9
+ eor x21, x21, x13 //AES block 4k+6 - round 10 low
+ eor x22, x22, x14 //AES block 4k+6 - round 10 high
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+ fmov d6, x21 //AES block 4k+6 - mov low
+
+ aese v1.16b, v27.16b //AES block 4k+5 - round 9
+ fmov v6.d[1], x22 //AES block 4k+6 - mov high
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+ eor v4.16b, v4.16b, v0.16b //AES block 4k+4 - result
+
+ fmov d0, x10 //CTR block 4k+8
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+
+ fmov v0.d[1], x9 //CTR block 4k+8
+ rev w9, w12 //CTR block 4k+9
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+ eor v5.16b, v5.16b, v1.16b //AES block 4k+5 - result
+
+ add w12, w12, #1 //CTR block 4k+9
+ orr x9, x11, x9, lsl #32 //CTR block 4k+9
+ fmov d1, x10 //CTR block 4k+9
+
+ pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+ fmov v1.d[1], x9 //CTR block 4k+9
+ rev w9, w12 //CTR block 4k+10
+
+ aese v2.16b, v27.16b //AES block 4k+6 - round 9
+ st1 { v4.16b}, [x2], #16 //AES block 4k+4 - store result
+ eor v6.16b, v6.16b, v2.16b //AES block 4k+6 - result
+ orr x9, x11, x9, lsl #32 //CTR block 4k+10
+
+ aese v3.16b, v27.16b //AES block 4k+7 - round 9
+ add w12, w12, #1 //CTR block 4k+10
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+ fmov d2, x10 //CTR block 4k+10
+
+ eor v11.16b, v11.16b, v9.16b //MODULO - fold into low
+ st1 { v5.16b}, [x2], #16 //AES block 4k+5 - store result
+
+ fmov v2.d[1], x9 //CTR block 4k+10
+ st1 { v6.16b}, [x2], #16 //AES block 4k+6 - store result
+ rev w9, w12 //CTR block 4k+11
+
+ orr x9, x11, x9, lsl #32 //CTR block 4k+11
+ eor v7.16b, v7.16b, v3.16b //AES block 4k+3 - result
+
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+ st1 { v7.16b}, [x2], #16 //AES block 4k+3 - store result
+ b.lt .L128_enc_main_loop
+
+.L128_enc_prepretail: //PREPRETAIL
+ rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free)
+ fmov d3, x10 //CTR block 4k+3
+ rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free)
+
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+ add w12, w12, #1 //CTR block 4k+3
+ fmov v3.d[1], x9 //CTR block 4k+3
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free)
+
+ pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+
+ rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free)
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+
+ pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+ mov d30, v5.d[1] //GHASH block 4k+1 - mid
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+ mov d8, v4.d[1] //GHASH block 4k - mid
+
+ mov d31, v6.d[1] //GHASH block 4k+2 - mid
+ mov d10, v17.d[1] //GHASH block 4k - mid
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+ eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid
+
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+ eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+
+ pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid
+ eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+ ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid
+ mov d30, v7.d[1] //GHASH block 4k+3 - mid
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+ eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high
+
+ pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid
+
+ pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+ eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid
+
+ pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+
+ pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+ eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+
+ pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+ movi v8.8b, #0xc2
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+ eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+
+ pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid
+ eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid
+ shl d8, d8, #56 //mod_constant
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+ eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+
+ pmull v28.1q, v9.1d, v8.1d
+ eor v10.16b, v10.16b, v9.16b //karatsuba tidy up
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+ ext v9.16b, v9.16b, v9.16b, #8
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+ eor v10.16b, v10.16b, v11.16b
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+ eor v10.16b, v10.16b, v28.16b
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+ eor v10.16b, v10.16b, v9.16b
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+
+ pmull v28.1q, v10.1d, v8.1d
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+ ext v10.16b, v10.16b, v10.16b, #8
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+ eor v11.16b, v11.16b, v28.16b
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+
+ aese v3.16b, v27.16b //AES block 4k+7 - round 9
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+
+ aese v0.16b, v27.16b //AES block 4k+4 - round 9
+
+ aese v1.16b, v27.16b //AES block 4k+5 - round 9
+ eor v11.16b, v11.16b, v10.16b
+
+ aese v2.16b, v27.16b //AES block 4k+6 - round 9
+.L128_enc_tail: //TAIL
+
+ sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process
+ ldp x6, x7, [x0], #16 //AES block 4k+4 - load plaintext
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ cmp x5, #48
+
+ ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag
+ eor x6, x6, x13 //AES block 4k+4 - round 10 low
+ eor x7, x7, x14 //AES block 4k+4 - round 10 high
+
+ fmov d4, x6 //AES block 4k+4 - mov low
+
+ fmov v4.d[1], x7 //AES block 4k+4 - mov high
+
+ eor v5.16b, v4.16b, v0.16b //AES block 4k+4 - result
+
+ b.gt .L128_enc_blocks_more_than_3
+
+ sub w12, w12, #1
+ movi v11.8b, #0
+ mov v3.16b, v2.16b
+
+ cmp x5, #32
+ mov v2.16b, v1.16b
+ movi v9.8b, #0
+
+ movi v10.8b, #0
+ b.gt .L128_enc_blocks_more_than_2
+
+ mov v3.16b, v1.16b
+ cmp x5, #16
+
+ sub w12, w12, #1
+ b.gt .L128_enc_blocks_more_than_1
+
+ sub w12, w12, #1
+ b .L128_enc_blocks_less_than_1
+.L128_enc_blocks_more_than_3: //blocks left > 3
+ st1 { v5.16b}, [x2], #16 //AES final-3 block - store result
+
+ ldp x6, x7, [x0], #16 //AES final-2 block - load input low & high
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ rev64 v4.16b, v5.16b //GHASH final-3 block
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+ eor x7, x7, x14 //AES final-2 block - round 10 high
+ eor x6, x6, x13 //AES final-2 block - round 10 low
+
+ fmov d5, x6 //AES final-2 block - mov low
+
+ movi v8.8b, #0 //suppress further partial tag feed in
+ fmov v5.d[1], x7 //AES final-2 block - mov high
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low
+ mov d22, v4.d[1] //GHASH final-3 block - mid
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high
+
+ mov d10, v17.d[1] //GHASH final-3 block - mid
+
+ eor v5.16b, v5.16b, v1.16b //AES final-2 block - result
+ eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid
+
+ pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid
+.L128_enc_blocks_more_than_2: //blocks left > 2
+
+ st1 { v5.16b}, [x2], #16 //AES final-2 block - store result
+
+ rev64 v4.16b, v5.16b //GHASH final-2 block
+ ldp x6, x7, [x0], #16 //AES final-1 block - load input low & high
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ eor x6, x6, x13 //AES final-1 block - round 10 low
+
+ fmov d5, x6 //AES final-1 block - mov low
+ eor x7, x7, x14 //AES final-1 block - round 10 high
+
+ pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high
+ fmov v5.d[1], x7 //AES final-1 block - mov high
+
+ mov d22, v4.d[1] //GHASH final-2 block - mid
+
+ pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid
+
+ eor v5.16b, v5.16b, v2.16b //AES final-1 block - result
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low
+
+ pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid
+
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid
+.L128_enc_blocks_more_than_1: //blocks left > 1
+
+ st1 { v5.16b}, [x2], #16 //AES final-1 block - store result
+
+ rev64 v4.16b, v5.16b //GHASH final-1 block
+ ldp x6, x7, [x0], #16 //AES final block - load input low & high
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ eor x7, x7, x14 //AES final block - round 10 high
+ eor x6, x6, x13 //AES final block - round 10 low
+
+ fmov d5, x6 //AES final block - mov low
+
+ pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high
+ fmov v5.d[1], x7 //AES final block - mov high
+
+ mov d22, v4.d[1] //GHASH final-1 block - mid
+
+ pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid
+
+ eor v5.16b, v5.16b, v3.16b //AES final block - result
+
+ ins v22.d[1], v22.d[0] //GHASH final-1 block - mid
+
+ pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high
+
+ eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid
+ movi v8.8b, #0 //suppress further partial tag feed in
+.L128_enc_blocks_less_than_1: //blocks left <= 1
+
+ and x1, x1, #127 //bit_length %= 128
+ mvn x13, xzr //rk10_l = 0xffffffffffffffff
+
+ mvn x14, xzr //rk10_h = 0xffffffffffffffff
+ sub x1, x1, #128 //bit_length -= 128
+
+ neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128])
+
+ and x1, x1, #127 //bit_length %= 128
+
+ lsr x14, x14, x1 //rk10_h is mask for top 64b of last block
+ cmp x1, #64
+
+ csel x6, x13, x14, lt
+ csel x7, x14, xzr, lt
+
+ fmov d0, x6 //ctr0b is mask for last block
+
+ fmov v0.d[1], x7
+
+ and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits
+
+ rev64 v4.16b, v5.16b //GHASH final block
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ mov d8, v4.d[1] //GHASH final block - mid
+
+ pmull v21.1q, v4.1d, v12.1d //GHASH final block - low
+ ld1 { v18.16b}, [x2] //load existing bytes where the possibly partial last block is to be stored
+
+ eor v8.8b, v8.8b, v4.8b //GHASH final block - mid
+#ifndef __AARCH64EB__
+ rev w9, w12
+#else
+ mov w9, w12
+#endif
+ pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high
+
+ pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final block - low
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final block - high
+
+ eor v10.16b, v10.16b, v8.16b //GHASH final block - mid
+ movi v8.8b, #0xc2
+
+ eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ shl d8, d8, #56 //mod_constant
+
+ eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up
+
+ pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid
+
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ bif v5.16b, v18.16b, v0.16b //insert existing bytes in top end of result before storing
+
+ eor v11.16b, v11.16b, v9.16b //MODULO - fold into low
+ st1 { v5.16b}, [x2] //store all 16B
+
+ str w9, [x16, #12] //store the updated counter
+
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+ mov x0, x15
+ st1 { v11.16b }, [x3]
+ ldp x21, x22, [sp, #16]
+ ldp x23, x24, [sp, #32]
+ ldp d8, d9, [sp, #48]
+ ldp d10, d11, [sp, #64]
+ ldp d12, d13, [sp, #80]
+ ldp d14, d15, [sp, #96]
+ ldp x19, x20, [sp], #112
+ ret
+
+.L128_enc_ret:
+ mov w0, #0x0
+ ret
+.size aes_gcm_enc_128_kernel,.-aes_gcm_enc_128_kernel
+.globl aes_gcm_dec_128_kernel
+.type aes_gcm_dec_128_kernel,%function
+.align 4
+aes_gcm_dec_128_kernel:
+ cbz x1, .L128_dec_ret
+ stp x19, x20, [sp, #-112]!
+ mov x16, x4
+ mov x8, x5
+ stp x21, x22, [sp, #16]
+ stp x23, x24, [sp, #32]
+ stp d8, d9, [sp, #48]
+ stp d10, d11, [sp, #64]
+ stp d12, d13, [sp, #80]
+ stp d14, d15, [sp, #96]
+
+ lsr x5, x1, #3 //byte_len
+ mov x15, x5
+ ldp x10, x11, [x16] //ctr96_b64, ctr96_t32
+#ifdef __AARCH64EB__
+ rev x10, x10
+ rev x11, x11
+#endif
+ ldp x13, x14, [x8, #160] //load rk10
+#ifdef __AARCH64EB__
+ ror x14, x14, 32
+ ror x13, x13, 32
+#endif
+ sub x5, x5, #1 //byte_len - 1
+ ld1 {v18.4s}, [x8], #16 //load rk0
+
+ and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail)
+ ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible
+
+ ldr q13, [x3, #64] //load h2l | h2h
+#ifndef __AARCH64EB__
+ ext v13.16b, v13.16b, v13.16b, #8
+#endif
+ lsr x12, x11, #32
+ fmov d2, x10 //CTR block 2
+
+ ld1 {v19.4s}, [x8], #16 //load rk1
+ orr w11, w11, w11
+ rev w12, w12 //rev_ctr32
+
+ fmov d1, x10 //CTR block 1
+ add w12, w12, #1 //increment rev_ctr32
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 0
+ rev w9, w12 //CTR block 1
+
+ orr x9, x11, x9, lsl #32 //CTR block 1
+ ld1 {v20.4s}, [x8], #16 //load rk2
+ add w12, w12, #1 //CTR block 1
+
+ fmov v1.d[1], x9 //CTR block 1
+ rev w9, w12 //CTR block 2
+ add w12, w12, #1 //CTR block 2
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 1
+ orr x9, x11, x9, lsl #32 //CTR block 2
+
+ fmov v2.d[1], x9 //CTR block 2
+ rev w9, w12 //CTR block 3
+
+ fmov d3, x10 //CTR block 3
+ orr x9, x11, x9, lsl #32 //CTR block 3
+ add w12, w12, #1 //CTR block 3
+
+ fmov v3.d[1], x9 //CTR block 3
+ add x4, x0, x1, lsr #3 //end_input_ptr
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 0
+ ld1 {v21.4s}, [x8], #16 //load rk3
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 2
+ ld1 {v22.4s}, [x8], #16 //load rk4
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 0
+ ld1 {v23.4s}, [x8], #16 //load rk5
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 1
+ ld1 {v24.4s}, [x8], #16 //load rk6
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 0
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 1
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 2
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 1
+ ld1 { v11.16b}, [x3]
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 3
+ ld1 {v25.4s}, [x8], #16 //load rk7
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 3
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 2
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 2
+ ld1 {v26.4s}, [x8], #16 //load rk8
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 4
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 3
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 3
+ ldr q14, [x3, #80] //load h3l | h3h
+#ifndef __AARCH64EB__
+ ext v14.16b, v14.16b, v14.16b, #8
+#endif
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 4
+ ld1 {v27.4s}, [x8], #16 //load rk9
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 5
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 4
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 4
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 5
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 5
+ ldr q12, [x3, #32] //load h1l | h1h
+#ifndef __AARCH64EB__
+ ext v12.16b, v12.16b, v12.16b, #8
+#endif
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 5
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 6
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 6
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 6
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 6
+ trn1 v8.2d, v12.2d, v13.2d //h2h | h1h
+
+ ldr q15, [x3, #112] //load h4l | h4h
+#ifndef __AARCH64EB__
+ ext v15.16b, v15.16b, v15.16b, #8
+#endif
+ trn2 v16.2d, v12.2d, v13.2d //h2l | h1l
+ add x5, x5, x0
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 7
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 7
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 7
+ eor v16.16b, v16.16b, v8.16b //h2k | h1k
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 7
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 8
+ trn2 v17.2d, v14.2d, v15.2d //h4l | h3l
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 8
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 8
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 8
+ trn1 v9.2d, v14.2d, v15.2d //h4h | h3h
+
+ aese v2.16b, v27.16b //AES block 2 - round 9
+
+ aese v3.16b, v27.16b //AES block 3 - round 9
+
+ aese v0.16b, v27.16b //AES block 0 - round 9
+ cmp x0, x5 //check if we have <= 4 blocks
+
+ aese v1.16b, v27.16b //AES block 1 - round 9
+ eor v17.16b, v17.16b, v9.16b //h4k | h3k
+ b.ge .L128_dec_tail //handle tail
+
+ ld1 {v4.16b, v5.16b}, [x0], #32 //AES block 0 - load ciphertext; AES block 1 - load ciphertext
+
+ eor v1.16b, v5.16b, v1.16b //AES block 1 - result
+ ld1 {v6.16b}, [x0], #16 //AES block 2 - load ciphertext
+
+ eor v0.16b, v4.16b, v0.16b //AES block 0 - result
+ rev64 v4.16b, v4.16b //GHASH block 0
+ rev w9, w12 //CTR block 4
+
+ orr x9, x11, x9, lsl #32 //CTR block 4
+ add w12, w12, #1 //CTR block 4
+ ld1 {v7.16b}, [x0], #16 //AES block 3 - load ciphertext
+
+ rev64 v5.16b, v5.16b //GHASH block 1
+ mov x19, v1.d[0] //AES block 1 - mov low
+
+ mov x20, v1.d[1] //AES block 1 - mov high
+
+ mov x6, v0.d[0] //AES block 0 - mov low
+ cmp x0, x5 //check if we have <= 8 blocks
+
+ mov x7, v0.d[1] //AES block 0 - mov high
+
+ fmov d0, x10 //CTR block 4
+
+ fmov v0.d[1], x9 //CTR block 4
+ rev w9, w12 //CTR block 5
+ eor x19, x19, x13 //AES block 1 - round 10 low
+#ifdef __AARCH64EB__
+ rev x19, x19
+#endif
+ fmov d1, x10 //CTR block 5
+ add w12, w12, #1 //CTR block 5
+ orr x9, x11, x9, lsl #32 //CTR block 5
+
+ fmov v1.d[1], x9 //CTR block 5
+ rev w9, w12 //CTR block 6
+ add w12, w12, #1 //CTR block 6
+
+ orr x9, x11, x9, lsl #32 //CTR block 6
+
+ eor x20, x20, x14 //AES block 1 - round 10 high
+#ifdef __AARCH64EB__
+ rev x20, x20
+#endif
+ eor x6, x6, x13 //AES block 0 - round 10 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ eor v2.16b, v6.16b, v2.16b //AES block 2 - result
+
+ eor x7, x7, x14 //AES block 0 - round 10 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ stp x6, x7, [x2], #16 //AES block 0 - store result
+
+ stp x19, x20, [x2], #16 //AES block 1 - store result
+ b.ge .L128_dec_prepretail //do prepretail
+
+.L128_dec_main_loop: //main loop start
+ eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+ mov x21, v2.d[0] //AES block 4k+2 - mov low
+
+ pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+ mov x22, v2.d[1] //AES block 4k+2 - mov high
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ fmov d2, x10 //CTR block 4k+6
+
+ rev64 v6.16b, v6.16b //GHASH block 4k+2
+ fmov v2.d[1], x9 //CTR block 4k+6
+ rev w9, w12 //CTR block 4k+7
+
+ mov x23, v3.d[0] //AES block 4k+3 - mov low
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+ mov d30, v5.d[1] //GHASH block 4k+1 - mid
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+ rev64 v7.16b, v7.16b //GHASH block 4k+3
+
+ pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+ mov x24, v3.d[1] //AES block 4k+3 - mov high
+ orr x9, x11, x9, lsl #32 //CTR block 4k+7
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+ fmov d3, x10 //CTR block 4k+7
+ eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+ fmov v3.d[1], x9 //CTR block 4k+7
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+ mov d10, v17.d[1] //GHASH block 4k - mid
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+ eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low
+
+ pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+ mov d8, v4.d[1] //GHASH block 4k - mid
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+ eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+
+ pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+ eor x23, x23, x13 //AES block 4k+3 - round 10 low
+#ifdef __AARCH64EB__
+ rev x23, x23
+#endif
+ pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid
+ eor x22, x22, x14 //AES block 4k+2 - round 10 high
+#ifdef __AARCH64EB__
+ rev x22, x22
+#endif
+ mov d31, v6.d[1] //GHASH block 4k+2 - mid
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+ eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+ eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid
+
+ pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+ ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid
+
+ pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+ mov d30, v7.d[1] //GHASH block 4k+3 - mid
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+ eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high
+
+ pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid
+ eor x24, x24, x14 //AES block 4k+3 - round 10 high
+#ifdef __AARCH64EB__
+ rev x24, x24
+#endif
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+ eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+ eor x21, x21, x13 //AES block 4k+2 - round 10 low
+#ifdef __AARCH64EB__
+ rev x21, x21
+#endif
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+ movi v8.8b, #0xc2
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+ eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+ eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+ stp x21, x22, [x2], #16 //AES block 4k+2 - store result
+
+ pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high
+ ld1 {v4.16b}, [x0], #16 //AES block 4k+3 - load ciphertext
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+ add w12, w12, #1 //CTR block 4k+7
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+ shl d8, d8, #56 //mod_constant
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+ stp x23, x24, [x2], #16 //AES block 4k+3 - store result
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+ eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+ rev w9, w12 //CTR block 4k+8
+
+ pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+ ld1 {v5.16b}, [x0], #16 //AES block 4k+4 - load ciphertext
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ aese v0.16b, v27.16b //AES block 4k+4 - round 9
+ orr x9, x11, x9, lsl #32 //CTR block 4k+8
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+ eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up
+
+ aese v1.16b, v27.16b //AES block 4k+5 - round 9
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+ eor v0.16b, v4.16b, v0.16b //AES block 4k+4 - result
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+ ld1 {v6.16b}, [x0], #16 //AES block 4k+5 - load ciphertext
+
+ add w12, w12, #1 //CTR block 4k+8
+ eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid
+ eor v1.16b, v5.16b, v1.16b //AES block 4k+5 - result
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+ ld1 {v7.16b}, [x0], #16 //AES block 4k+6 - load ciphertext
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+
+ rev64 v5.16b, v5.16b //GHASH block 4k+5
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+ mov x7, v0.d[1] //AES block 4k+4 - mov high
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+ mov x6, v0.d[0] //AES block 4k+4 - mov low
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+ fmov d0, x10 //CTR block 4k+8
+
+ pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+ fmov v0.d[1], x9 //CTR block 4k+8
+ rev w9, w12 //CTR block 4k+9
+
+ aese v2.16b, v27.16b //AES block 4k+6 - round 9
+ orr x9, x11, x9, lsl #32 //CTR block 4k+9
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+ eor x7, x7, x14 //AES block 4k+4 - round 10 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ eor v11.16b, v11.16b, v8.16b //MODULO - fold into low
+ mov x20, v1.d[1] //AES block 4k+5 - mov high
+ eor x6, x6, x13 //AES block 4k+4 - round 10 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ eor v2.16b, v6.16b, v2.16b //AES block 4k+6 - result
+ mov x19, v1.d[0] //AES block 4k+5 - mov low
+ add w12, w12, #1 //CTR block 4k+9
+
+ aese v3.16b, v27.16b //AES block 4k+7 - round 9
+ fmov d1, x10 //CTR block 4k+9
+ cmp x0, x5 //.LOOP CONTROL
+
+ rev64 v4.16b, v4.16b //GHASH block 4k+4
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+ fmov v1.d[1], x9 //CTR block 4k+9
+
+ rev w9, w12 //CTR block 4k+10
+ add w12, w12, #1 //CTR block 4k+10
+
+ eor x20, x20, x14 //AES block 4k+5 - round 10 high
+#ifdef __AARCH64EB__
+ rev x20, x20
+#endif
+ stp x6, x7, [x2], #16 //AES block 4k+4 - store result
+
+ eor x19, x19, x13 //AES block 4k+5 - round 10 low
+#ifdef __AARCH64EB__
+ rev x19, x19
+#endif
+ stp x19, x20, [x2], #16 //AES block 4k+5 - store result
+
+ orr x9, x11, x9, lsl #32 //CTR block 4k+10
+ b.lt .L128_dec_main_loop
+
+.L128_dec_prepretail: //PREPRETAIL
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+ mov x21, v2.d[0] //AES block 4k+2 - mov low
+ mov d30, v5.d[1] //GHASH block 4k+1 - mid
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+ eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ mov x22, v2.d[1] //AES block 4k+2 - mov high
+
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+ fmov d2, x10 //CTR block 4k+6
+ rev64 v6.16b, v6.16b //GHASH block 4k+2
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+ fmov v2.d[1], x9 //CTR block 4k+6
+
+ rev w9, w12 //CTR block 4k+7
+ mov x23, v3.d[0] //AES block 4k+3 - mov low
+ eor v30.8b, v30.8b, v5.8b //GHASH block 4k+1 - mid
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+ mov d10, v17.d[1] //GHASH block 4k - mid
+ mov x24, v3.d[1] //AES block 4k+3 - mov high
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+ mov d31, v6.d[1] //GHASH block 4k+2 - mid
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+ orr x9, x11, x9, lsl #32 //CTR block 4k+7
+
+ pmull v29.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+ mov d8, v4.d[1] //GHASH block 4k - mid
+ fmov d3, x10 //CTR block 4k+7
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+ fmov v3.d[1], x9 //CTR block 4k+7
+
+ pmull v30.1q, v30.1d, v17.1d //GHASH block 4k+1 - mid
+ eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid
+
+ rev64 v7.16b, v7.16b //GHASH block 4k+3
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+ ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid
+
+ pmull2 v28.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+ eor v11.16b, v11.16b, v29.16b //GHASH block 4k+1 - low
+
+ pmull v29.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+
+ pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid
+ eor v9.16b, v9.16b, v28.16b //GHASH block 4k+1 - high
+
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+1 - mid
+
+ pmull2 v4.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+
+ pmull2 v8.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+ mov d30, v7.d[1] //GHASH block 4k+3 - mid
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+ eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid
+
+ pmull v28.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+
+ eor v9.16b, v9.16b, v8.16b //GHASH block 4k+2 - high
+ movi v8.8b, #0xc2
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+ eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid
+
+ eor v11.16b, v11.16b, v28.16b //GHASH block 4k+2 - low
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+3 - high
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+ eor x23, x23, x13 //AES block 4k+3 - round 10 low
+#ifdef __AARCH64EB__
+ rev x23, x23
+#endif
+ pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid
+ eor x21, x21, x13 //AES block 4k+2 - round 10 low
+#ifdef __AARCH64EB__
+ rev x21, x21
+#endif
+ eor v11.16b, v11.16b, v29.16b //GHASH block 4k+3 - low
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+ shl d8, d8, #56 //mod_constant
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+ eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+ eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up
+
+ pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+ eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+
+ aese v1.16b, v27.16b //AES block 4k+5 - round 9
+
+ pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+ eor x24, x24, x14 //AES block 4k+3 - round 10 high
+#ifdef __AARCH64EB__
+ rev x24, x24
+#endif
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+ eor v11.16b, v11.16b, v8.16b //MODULO - fold into low
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+ eor x22, x22, x14 //AES block 4k+2 - round 10 high
+#ifdef __AARCH64EB__
+ rev x22, x22
+#endif
+ aese v0.16b, v27.16b //AES block 4k+4 - round 9
+ stp x21, x22, [x2], #16 //AES block 4k+2 - store result
+
+ aese v2.16b, v27.16b //AES block 4k+6 - round 9
+ add w12, w12, #1 //CTR block 4k+7
+ stp x23, x24, [x2], #16 //AES block 4k+3 - store result
+
+ aese v3.16b, v27.16b //AES block 4k+7 - round 9
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+.L128_dec_tail: //TAIL
+
+ sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process
+ ld1 { v5.16b}, [x0], #16 //AES block 4k+4 - load ciphertext
+
+ eor v0.16b, v5.16b, v0.16b //AES block 4k+4 - result
+
+ mov x7, v0.d[1] //AES block 4k+4 - mov high
+
+ mov x6, v0.d[0] //AES block 4k+4 - mov low
+
+ cmp x5, #48
+
+ eor x7, x7, x14 //AES block 4k+4 - round 10 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag
+ eor x6, x6, x13 //AES block 4k+4 - round 10 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ b.gt .L128_dec_blocks_more_than_3
+
+ mov v3.16b, v2.16b
+ sub w12, w12, #1
+ movi v11.8b, #0
+
+ movi v9.8b, #0
+ mov v2.16b, v1.16b
+
+ movi v10.8b, #0
+ cmp x5, #32
+ b.gt .L128_dec_blocks_more_than_2
+
+ cmp x5, #16
+
+ mov v3.16b, v1.16b
+ sub w12, w12, #1
+ b.gt .L128_dec_blocks_more_than_1
+
+ sub w12, w12, #1
+ b .L128_dec_blocks_less_than_1
+.L128_dec_blocks_more_than_3: //blocks left > 3
+ rev64 v4.16b, v5.16b //GHASH final-3 block
+ ld1 { v5.16b}, [x0], #16 //AES final-2 block - load ciphertext
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ mov d10, v17.d[1] //GHASH final-3 block - mid
+ stp x6, x7, [x2], #16 //AES final-3 block - store result
+ eor v0.16b, v5.16b, v1.16b //AES final-2 block - result
+
+ mov d22, v4.d[1] //GHASH final-3 block - mid
+ mov x7, v0.d[1] //AES final-2 block - mov high
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low
+ mov x6, v0.d[0] //AES final-2 block - mov low
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid
+
+ movi v8.8b, #0 //suppress further partial tag feed in
+ eor x7, x7, x14 //AES final-2 block - round 10 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid
+ eor x6, x6, x13 //AES final-2 block - round 10 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+.L128_dec_blocks_more_than_2: //blocks left > 2
+
+ rev64 v4.16b, v5.16b //GHASH final-2 block
+ ld1 { v5.16b}, [x0], #16 //AES final-1 block - load ciphertext
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ eor v0.16b, v5.16b, v2.16b //AES final-1 block - result
+ stp x6, x7, [x2], #16 //AES final-2 block - store result
+
+ mov d22, v4.d[1] //GHASH final-2 block - mid
+
+ pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low
+
+ pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high
+ mov x6, v0.d[0] //AES final-1 block - mov low
+
+ mov x7, v0.d[1] //AES final-1 block - mov high
+ eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid
+
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid
+
+ eor x6, x6, x13 //AES final-1 block - round 10 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high
+
+ eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid
+ eor x7, x7, x14 //AES final-1 block - round 10 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+.L128_dec_blocks_more_than_1: //blocks left > 1
+
+ rev64 v4.16b, v5.16b //GHASH final-1 block
+
+ ld1 { v5.16b}, [x0], #16 //AES final block - load ciphertext
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ mov d22, v4.d[1] //GHASH final-1 block - mid
+
+ eor v0.16b, v5.16b, v3.16b //AES final block - result
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid
+
+ stp x6, x7, [x2], #16 //AES final-1 block - store result
+ mov x6, v0.d[0] //AES final block - mov low
+
+ mov x7, v0.d[1] //AES final block - mov high
+ ins v22.d[1], v22.d[0] //GHASH final-1 block - mid
+
+ pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low
+
+ pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high
+
+ pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high
+ eor x7, x7, x14 //AES final block - round 10 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ eor x6, x6, x13 //AES final block - round 10 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid
+.L128_dec_blocks_less_than_1: //blocks left <= 1
+
+ mvn x14, xzr //rk10_h = 0xffffffffffffffff
+ and x1, x1, #127 //bit_length %= 128
+
+ mvn x13, xzr //rk10_l = 0xffffffffffffffff
+ sub x1, x1, #128 //bit_length -= 128
+
+ neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128])
+
+ and x1, x1, #127 //bit_length %= 128
+
+ lsr x14, x14, x1 //rk10_h is mask for top 64b of last block
+ cmp x1, #64
+
+ csel x10, x14, xzr, lt
+ csel x9, x13, x14, lt
+
+ fmov d0, x9 //ctr0b is mask for last block
+
+ mov v0.d[1], x10
+
+ and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits
+
+ rev64 v4.16b, v5.16b //GHASH final block
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ ldp x4, x5, [x2] //load existing bytes we need to not overwrite
+
+ and x7, x7, x10
+
+ pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high
+ mov d8, v4.d[1] //GHASH final block - mid
+
+ eor v8.8b, v8.8b, v4.8b //GHASH final block - mid
+ eor v9.16b, v9.16b, v20.16b //GHASH final block - high
+
+ pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid
+
+ pmull v21.1q, v4.1d, v12.1d //GHASH final block - low
+ bic x4, x4, x9 //mask out low existing bytes
+ and x6, x6, x9
+
+#ifndef __AARCH64EB__
+ rev w9, w12
+#else
+ mov w9, w12
+#endif
+
+ eor v10.16b, v10.16b, v8.16b //GHASH final block - mid
+ movi v8.8b, #0xc2
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final block - low
+
+ bic x5, x5, x10 //mask out high existing bytes
+ shl d8, d8, #56 //mod_constant
+
+ eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+
+ eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up
+
+ orr x6, x6, x4
+ str w9, [x16, #12] //store the updated counter
+
+ orr x7, x7, x5
+ stp x6, x7, [x2]
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid
+
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ eor v11.16b, v11.16b, v8.16b //MODULO - fold into low
+
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+ mov x0, x15
+ st1 { v11.16b }, [x3]
+
+ ldp x21, x22, [sp, #16]
+ ldp x23, x24, [sp, #32]
+ ldp d8, d9, [sp, #48]
+ ldp d10, d11, [sp, #64]
+ ldp d12, d13, [sp, #80]
+ ldp d14, d15, [sp, #96]
+ ldp x19, x20, [sp], #112
+ ret
+
+.L128_dec_ret:
+ mov w0, #0x0
+ ret
+.size aes_gcm_dec_128_kernel,.-aes_gcm_dec_128_kernel
+.globl aes_gcm_enc_192_kernel
+.type aes_gcm_enc_192_kernel,%function
+.align 4
+aes_gcm_enc_192_kernel:
+ cbz x1, .L192_enc_ret
+ stp x19, x20, [sp, #-112]!
+ mov x16, x4
+ mov x8, x5
+ stp x21, x22, [sp, #16]
+ stp x23, x24, [sp, #32]
+ stp d8, d9, [sp, #48]
+ stp d10, d11, [sp, #64]
+ stp d12, d13, [sp, #80]
+ stp d14, d15, [sp, #96]
+
+ ldp x10, x11, [x16] //ctr96_b64, ctr96_t32
+#ifdef __AARCH64EB__
+ rev x10, x10
+ rev x11, x11
+#endif
+ ldp x13, x14, [x8, #192] //load rk12
+#ifdef __AARCH64EB__
+ ror x13, x13, #32
+ ror x14, x14, #32
+#endif
+ ld1 {v18.4s}, [x8], #16 //load rk0
+
+ ld1 {v19.4s}, [x8], #16 //load rk1
+
+ ld1 {v20.4s}, [x8], #16 //load rk2
+
+ lsr x12, x11, #32
+ ld1 {v21.4s}, [x8], #16 //load rk3
+ orr w11, w11, w11
+
+ ld1 {v22.4s}, [x8], #16 //load rk4
+ rev w12, w12 //rev_ctr32
+
+ add w12, w12, #1 //increment rev_ctr32
+ fmov d3, x10 //CTR block 3
+
+ rev w9, w12 //CTR block 1
+ add w12, w12, #1 //CTR block 1
+ fmov d1, x10 //CTR block 1
+
+ orr x9, x11, x9, lsl #32 //CTR block 1
+ ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible
+
+ fmov v1.d[1], x9 //CTR block 1
+ rev w9, w12 //CTR block 2
+ add w12, w12, #1 //CTR block 2
+
+ fmov d2, x10 //CTR block 2
+ orr x9, x11, x9, lsl #32 //CTR block 2
+
+ fmov v2.d[1], x9 //CTR block 2
+ rev w9, w12 //CTR block 3
+
+ orr x9, x11, x9, lsl #32 //CTR block 3
+ ld1 {v23.4s}, [x8], #16 //load rk5
+
+ fmov v3.d[1], x9 //CTR block 3
+
+ ld1 {v24.4s}, [x8], #16 //load rk6
+
+ ld1 {v25.4s}, [x8], #16 //load rk7
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 0
+ ld1 { v11.16b}, [x3]
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 0
+ ld1 {v26.4s}, [x8], #16 //load rk8
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 0
+ ldr q15, [x3, #112] //load h4l | h4h
+#ifndef __AARCH64EB__
+ ext v15.16b, v15.16b, v15.16b, #8
+#endif
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 0
+ ld1 {v27.4s}, [x8], #16 //load rk9
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 1
+ ld1 {v28.4s}, [x8], #16 //load rk10
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 1
+ ldr q12, [x3, #32] //load h1l | h1h
+#ifndef __AARCH64EB__
+ ext v12.16b, v12.16b, v12.16b, #8
+#endif
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 1
+ ld1 {v29.4s}, [x8], #16 //load rk11
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 1
+ ldr q14, [x3, #80] //load h3l | h3h
+#ifndef __AARCH64EB__
+ ext v14.16b, v14.16b, v14.16b, #8
+#endif
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 2
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 2
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 2
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 3
+ trn1 v9.2d, v14.2d, v15.2d //h4h | h3h
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 3
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 2
+ trn2 v17.2d, v14.2d, v15.2d //h4l | h3l
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 4
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 3
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 3
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 5
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 4
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 4
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 6
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 4
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 5
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 5
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 5
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 6
+ ldr q13, [x3, #64] //load h2l | h2h
+#ifndef __AARCH64EB__
+ ext v13.16b, v13.16b, v13.16b, #8
+#endif
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 6
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 6
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 7
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 7
+ trn2 v16.2d, v12.2d, v13.2d //h2l | h1l
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 7
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 8
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 7
+ trn1 v8.2d, v12.2d, v13.2d //h2h | h1h
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 8
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 8
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 8
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 9
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 9
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 9
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 9
+
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 10
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 10
+
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 10
+ lsr x5, x1, #3 //byte_len
+ mov x15, x5
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 10
+ sub x5, x5, #1 //byte_len - 1
+
+ eor v16.16b, v16.16b, v8.16b //h2k | h1k
+ and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail)
+
+ eor v17.16b, v17.16b, v9.16b //h4k | h3k
+
+ aese v2.16b, v29.16b //AES block 2 - round 11
+ add x4, x0, x1, lsr #3 //end_input_ptr
+ add x5, x5, x0
+
+ aese v1.16b, v29.16b //AES block 1 - round 11
+ cmp x0, x5 //check if we have <= 4 blocks
+
+ aese v0.16b, v29.16b //AES block 0 - round 11
+ add w12, w12, #1 //CTR block 3
+
+ aese v3.16b, v29.16b //AES block 3 - round 11
+ b.ge .L192_enc_tail //handle tail
+
+ rev w9, w12 //CTR block 4
+ ldp x6, x7, [x0, #0] //AES block 0 - load plaintext
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ orr x9, x11, x9, lsl #32 //CTR block 4
+ ldp x21, x22, [x0, #32] //AES block 2 - load plaintext
+#ifdef __AARCH64EB__
+ rev x21, x21
+ rev x22, x22
+#endif
+ ldp x23, x24, [x0, #48] //AES block 3 - load plaintext
+#ifdef __AARCH64EB__
+ rev x23, x23
+ rev x24, x24
+#endif
+ ldp x19, x20, [x0, #16] //AES block 1 - load plaintext
+#ifdef __AARCH64EB__
+ rev x19, x19
+ rev x20, x20
+#endif
+ add x0, x0, #64 //AES input_ptr update
+ cmp x0, x5 //check if we have <= 8 blocks
+
+ eor x6, x6, x13 //AES block 0 - round 12 low
+
+ eor x7, x7, x14 //AES block 0 - round 12 high
+ eor x22, x22, x14 //AES block 2 - round 12 high
+ fmov d4, x6 //AES block 0 - mov low
+
+ eor x24, x24, x14 //AES block 3 - round 12 high
+ fmov v4.d[1], x7 //AES block 0 - mov high
+
+ eor x21, x21, x13 //AES block 2 - round 12 low
+ eor x19, x19, x13 //AES block 1 - round 12 low
+
+ fmov d5, x19 //AES block 1 - mov low
+ eor x20, x20, x14 //AES block 1 - round 12 high
+
+ fmov v5.d[1], x20 //AES block 1 - mov high
+
+ eor x23, x23, x13 //AES block 3 - round 12 low
+ fmov d6, x21 //AES block 2 - mov low
+
+ add w12, w12, #1 //CTR block 4
+ eor v4.16b, v4.16b, v0.16b //AES block 0 - result
+ fmov d0, x10 //CTR block 4
+
+ fmov v0.d[1], x9 //CTR block 4
+ rev w9, w12 //CTR block 5
+
+ orr x9, x11, x9, lsl #32 //CTR block 5
+ add w12, w12, #1 //CTR block 5
+
+ fmov d7, x23 //AES block 3 - mov low
+ st1 { v4.16b}, [x2], #16 //AES block 0 - store result
+
+ fmov v6.d[1], x22 //AES block 2 - mov high
+
+ eor v5.16b, v5.16b, v1.16b //AES block 1 - result
+ fmov d1, x10 //CTR block 5
+ st1 { v5.16b}, [x2], #16 //AES block 1 - store result
+
+ fmov v7.d[1], x24 //AES block 3 - mov high
+
+ fmov v1.d[1], x9 //CTR block 5
+ rev w9, w12 //CTR block 6
+
+ orr x9, x11, x9, lsl #32 //CTR block 6
+
+ add w12, w12, #1 //CTR block 6
+ eor v6.16b, v6.16b, v2.16b //AES block 2 - result
+ fmov d2, x10 //CTR block 6
+
+ fmov v2.d[1], x9 //CTR block 6
+ rev w9, w12 //CTR block 7
+
+ orr x9, x11, x9, lsl #32 //CTR block 7
+ st1 { v6.16b}, [x2], #16 //AES block 2 - store result
+
+ eor v7.16b, v7.16b, v3.16b //AES block 3 - result
+ st1 { v7.16b}, [x2], #16 //AES block 3 - store result
+ b.ge .L192_enc_prepretail //do prepretail
+
+.L192_enc_main_loop: //main loop start
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+ rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free)
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ ldp x19, x20, [x0, #16] //AES block 4k+5 - load plaintext
+#ifdef __AARCH64EB__
+ rev x19, x19
+ rev x20, x20
+#endif
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+ fmov d3, x10 //CTR block 4k+3
+ rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free)
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+ fmov v3.d[1], x9 //CTR block 4k+3
+
+ pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+ rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free)
+ ldp x21, x22, [x0, #32] //AES block 4k+6 - load plaintext
+#ifdef __AARCH64EB__
+ rev x21, x21
+ rev x22, x22
+#endif
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+ ldp x23, x24, [x0, #48] //AES block 4k+3 - load plaintext
+#ifdef __AARCH64EB__
+ rev x23, x23
+ rev x24, x24
+#endif
+ pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+ rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free)
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+ eor x24, x24, x14 //AES block 4k+3 - round 12 high
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+ mov d8, v4.d[1] //GHASH block 4k - mid
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+ eor x21, x21, x13 //AES block 4k+6 - round 12 low
+
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+ eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+ eor x19, x19, x13 //AES block 4k+5 - round 12 low
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+ mov d31, v6.d[1] //GHASH block 4k+2 - mid
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+ mov d4, v5.d[1] //GHASH block 4k+1 - mid
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+
+ mov d10, v17.d[1] //GHASH block 4k - mid
+ eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+ eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid
+
+ pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+ eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+
+ pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+ eor x20, x20, x14 //AES block 4k+5 - round 12 high
+ ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+ add w12, w12, #1 //CTR block 4k+3
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+ eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high
+
+ pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid
+ eor x22, x22, x14 //AES block 4k+6 - round 12 high
+
+ pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid
+ eor x23, x23, x13 //AES block 4k+3 - round 12 low
+ mov d30, v7.d[1] //GHASH block 4k+3 - mid
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+ rev w9, w12 //CTR block 4k+8
+
+ pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+ orr x9, x11, x9, lsl #32 //CTR block 4k+8
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+ eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+ ldp x6, x7, [x0, #0] //AES block 4k+4 - load plaintext
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+ eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+ add x0, x0, #64 //AES input_ptr update
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+ movi v8.8b, #0xc2
+
+ pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+ eor x7, x7, x14 //AES block 4k+4 - round 12 high
+ eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+ eor x6, x6, x13 //AES block 4k+4 - round 12 low
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+ shl d8, d8, #56 //mod_constant
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+ eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+ fmov d5, x19 //AES block 4k+5 - mov low
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+ eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+ fmov v5.d[1], x20 //AES block 4k+5 - mov high
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+ eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low
+
+ pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid
+ cmp x0, x5 //.LOOP CONTROL
+ fmov d4, x6 //AES block 4k+4 - mov low
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+ fmov v4.d[1], x7 //AES block 4k+4 - mov high
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+ fmov d7, x23 //AES block 4k+3 - mov low
+
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid
+ eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+ add w12, w12, #1 //CTR block 4k+8
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+ fmov v7.d[1], x24 //AES block 4k+3 - mov high
+
+ pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+ fmov d6, x21 //AES block 4k+6 - mov low
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 9
+ eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 9
+
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 10
+ eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 9
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 9
+
+ aese v0.16b, v29.16b //AES block 4k+4 - round 11
+
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 10
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 10
+
+ eor v4.16b, v4.16b, v0.16b //AES block 4k+4 - result
+ fmov d0, x10 //CTR block 4k+8
+
+ aese v1.16b, v29.16b //AES block 4k+5 - round 11
+ fmov v0.d[1], x9 //CTR block 4k+8
+ rev w9, w12 //CTR block 4k+9
+
+ pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+ fmov v6.d[1], x22 //AES block 4k+6 - mov high
+ st1 { v4.16b}, [x2], #16 //AES block 4k+4 - store result
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 10
+ orr x9, x11, x9, lsl #32 //CTR block 4k+9
+
+ eor v5.16b, v5.16b, v1.16b //AES block 4k+5 - result
+ add w12, w12, #1 //CTR block 4k+9
+ fmov d1, x10 //CTR block 4k+9
+
+ aese v2.16b, v29.16b //AES block 4k+6 - round 11
+ fmov v1.d[1], x9 //CTR block 4k+9
+ rev w9, w12 //CTR block 4k+10
+
+ add w12, w12, #1 //CTR block 4k+10
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+ orr x9, x11, x9, lsl #32 //CTR block 4k+10
+
+ st1 { v5.16b}, [x2], #16 //AES block 4k+5 - store result
+ eor v11.16b, v11.16b, v9.16b //MODULO - fold into low
+
+ aese v3.16b, v29.16b //AES block 4k+7 - round 11
+ eor v6.16b, v6.16b, v2.16b //AES block 4k+6 - result
+ fmov d2, x10 //CTR block 4k+10
+
+ st1 { v6.16b}, [x2], #16 //AES block 4k+6 - store result
+ fmov v2.d[1], x9 //CTR block 4k+10
+ rev w9, w12 //CTR block 4k+11
+
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+ orr x9, x11, x9, lsl #32 //CTR block 4k+11
+
+ eor v7.16b, v7.16b, v3.16b //AES block 4k+3 - result
+ st1 { v7.16b}, [x2], #16 //AES block 4k+3 - store result
+ b.lt .L192_enc_main_loop
+
+.L192_enc_prepretail: //PREPRETAIL
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+ rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free)
+
+ fmov d3, x10 //CTR block 4k+3
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+ add w12, w12, #1 //CTR block 4k+3
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free)
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+
+ fmov v3.d[1], x9 //CTR block 4k+3
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+ mov d10, v17.d[1] //GHASH block 4k - mid
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+ rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free)
+
+ pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+ mov d8, v4.d[1] //GHASH block 4k - mid
+
+ pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+ rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free)
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+ mov d4, v5.d[1] //GHASH block 4k+1 - mid
+
+ eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low
+ mov d31, v6.d[1] //GHASH block 4k+2 - mid
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+ eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high
+
+ pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+
+ eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid
+ eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+ eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+ mov d30, v7.d[1] //GHASH block 4k+3 - mid
+
+ pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+ ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+ eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+
+ pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid
+
+ pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid
+
+ pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid
+ eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high
+
+ pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+ eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+ eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+ eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+
+ pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+ movi v8.8b, #0xc2
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+ eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+ eor v10.16b, v10.16b, v9.16b //karatsuba tidy up
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+ shl d8, d8, #56 //mod_constant
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+ eor v10.16b, v10.16b, v11.16b
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+
+ pmull v30.1q, v9.1d, v8.1d
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+ ext v9.16b, v9.16b, v9.16b, #8
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+ eor v10.16b, v10.16b, v30.16b
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 9
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+ eor v10.16b, v10.16b, v9.16b
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 9
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 9
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 9
+
+ pmull v30.1q, v10.1d, v8.1d
+
+ ext v10.16b, v10.16b, v10.16b, #8
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 10
+
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 10
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 10
+
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 10
+ eor v11.16b, v11.16b, v30.16b
+
+ aese v0.16b, v29.16b //AES block 4k+4 - round 11
+
+ aese v3.16b, v29.16b //AES block 4k+7 - round 11
+
+ aese v2.16b, v29.16b //AES block 4k+6 - round 11
+
+ aese v1.16b, v29.16b //AES block 4k+5 - round 11
+ eor v11.16b, v11.16b, v10.16b
+.L192_enc_tail: //TAIL
+
+ sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process
+ ldp x6, x7, [x0], #16 //AES block 4k+4 - load plaintext
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ eor x6, x6, x13 //AES block 4k+4 - round 12 low
+ eor x7, x7, x14 //AES block 4k+4 - round 12 high
+
+ fmov d4, x6 //AES block 4k+4 - mov low
+
+ fmov v4.d[1], x7 //AES block 4k+4 - mov high
+ cmp x5, #48
+
+ eor v5.16b, v4.16b, v0.16b //AES block 4k+4 - result
+
+ ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag
+ b.gt .L192_enc_blocks_more_than_3
+
+ sub w12, w12, #1
+ movi v10.8b, #0
+
+ mov v3.16b, v2.16b
+ movi v9.8b, #0
+ cmp x5, #32
+
+ mov v2.16b, v1.16b
+ movi v11.8b, #0
+ b.gt .L192_enc_blocks_more_than_2
+
+ sub w12, w12, #1
+
+ mov v3.16b, v1.16b
+ cmp x5, #16
+ b.gt .L192_enc_blocks_more_than_1
+
+ sub w12, w12, #1
+ b .L192_enc_blocks_less_than_1
+.L192_enc_blocks_more_than_3: //blocks left > 3
+ st1 { v5.16b}, [x2], #16 //AES final-3 block - store result
+
+ ldp x6, x7, [x0], #16 //AES final-2 block - load input low & high
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ rev64 v4.16b, v5.16b //GHASH final-3 block
+
+ eor x6, x6, x13 //AES final-2 block - round 12 low
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ eor x7, x7, x14 //AES final-2 block - round 12 high
+ fmov d5, x6 //AES final-2 block - mov low
+
+ fmov v5.d[1], x7 //AES final-2 block - mov high
+
+ mov d22, v4.d[1] //GHASH final-3 block - mid
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low
+
+ mov d10, v17.d[1] //GHASH final-3 block - mid
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid
+
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high
+
+ pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid
+ eor v5.16b, v5.16b, v1.16b //AES final-2 block - result
+.L192_enc_blocks_more_than_2: //blocks left > 2
+
+ st1 { v5.16b}, [x2], #16 //AES final-2 block - store result
+
+ rev64 v4.16b, v5.16b //GHASH final-2 block
+ ldp x6, x7, [x0], #16 //AES final-1 block - load input low & high
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ eor x7, x7, x14 //AES final-1 block - round 12 high
+
+ pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high
+ mov d22, v4.d[1] //GHASH final-2 block - mid
+
+ pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low
+ eor x6, x6, x13 //AES final-1 block - round 12 low
+
+ fmov d5, x6 //AES final-1 block - mov low
+
+ fmov v5.d[1], x7 //AES final-1 block - mov high
+ eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high
+ eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low
+
+ pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid
+
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ eor v5.16b, v5.16b, v2.16b //AES final-1 block - result
+
+ eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid
+.L192_enc_blocks_more_than_1: //blocks left > 1
+
+ st1 { v5.16b}, [x2], #16 //AES final-1 block - store result
+
+ ldp x6, x7, [x0], #16 //AES final block - load input low & high
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ rev64 v4.16b, v5.16b //GHASH final-1 block
+
+ eor x6, x6, x13 //AES final block - round 12 low
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ mov d22, v4.d[1] //GHASH final-1 block - mid
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid
+ eor x7, x7, x14 //AES final block - round 12 high
+ fmov d5, x6 //AES final block - mov low
+
+ pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high
+ fmov v5.d[1], x7 //AES final block - mov high
+
+ ins v22.d[1], v22.d[0] //GHASH final-1 block - mid
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high
+
+ pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low
+
+ pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid
+
+ eor v5.16b, v5.16b, v3.16b //AES final block - result
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low
+
+ eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid
+.L192_enc_blocks_less_than_1: //blocks left <= 1
+
+ ld1 { v18.16b}, [x2] //load existing bytes where the possibly partial last block is to be stored
+#ifndef __AARCH64EB__
+ rev w9, w12
+#else
+ mov w9, w12
+#endif
+ and x1, x1, #127 //bit_length %= 128
+
+ sub x1, x1, #128 //bit_length -= 128
+ mvn x14, xzr //rk12_h = 0xffffffffffffffff
+
+ neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128])
+ mvn x13, xzr //rk12_l = 0xffffffffffffffff
+
+ and x1, x1, #127 //bit_length %= 128
+
+ lsr x14, x14, x1 //rk12_h is mask for top 64b of last block
+ cmp x1, #64
+
+ csel x6, x13, x14, lt
+ csel x7, x14, xzr, lt
+
+ fmov d0, x6 //ctr0b is mask for last block
+
+ fmov v0.d[1], x7
+
+ and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits
+
+ rev64 v4.16b, v5.16b //GHASH final block
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ mov d8, v4.d[1] //GHASH final block - mid
+
+ pmull v21.1q, v4.1d, v12.1d //GHASH final block - low
+
+ pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high
+
+ eor v8.8b, v8.8b, v4.8b //GHASH final block - mid
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final block - low
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final block - high
+
+ pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid
+
+ eor v10.16b, v10.16b, v8.16b //GHASH final block - mid
+ movi v8.8b, #0xc2
+
+ eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ shl d8, d8, #56 //mod_constant
+
+ bif v5.16b, v18.16b, v0.16b //insert existing bytes in top end of result before storing
+
+ eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up
+
+ pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid
+
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ eor v11.16b, v11.16b, v9.16b //MODULO - fold into low
+ str w9, [x16, #12] //store the updated counter
+
+ st1 { v5.16b}, [x2] //store all 16B
+
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+ mov x0, x15
+ st1 { v11.16b }, [x3]
+
+ ldp x21, x22, [sp, #16]
+ ldp x23, x24, [sp, #32]
+ ldp d8, d9, [sp, #48]
+ ldp d10, d11, [sp, #64]
+ ldp d12, d13, [sp, #80]
+ ldp d14, d15, [sp, #96]
+ ldp x19, x20, [sp], #112
+ ret
+
+.L192_enc_ret:
+ mov w0, #0x0
+ ret
+.size aes_gcm_enc_192_kernel,.-aes_gcm_enc_192_kernel
+.globl aes_gcm_dec_192_kernel
+.type aes_gcm_dec_192_kernel,%function
+.align 4
+aes_gcm_dec_192_kernel:
+ cbz x1, .L192_dec_ret
+ stp x19, x20, [sp, #-112]!
+ mov x16, x4
+ mov x8, x5
+ stp x21, x22, [sp, #16]
+ stp x23, x24, [sp, #32]
+ stp d8, d9, [sp, #48]
+ stp d10, d11, [sp, #64]
+ stp d12, d13, [sp, #80]
+ stp d14, d15, [sp, #96]
+
+ add x4, x0, x1, lsr #3 //end_input_ptr
+ ldp x10, x11, [x16] //ctr96_b64, ctr96_t32
+#ifdef __AARCH64EB__
+ rev x10, x10
+ rev x11, x11
+#endif
+ ldp x13, x14, [x8, #192] //load rk12
+#ifdef __AARCH64EB__
+ ror x13, x13, #32
+ ror x14, x14, #32
+#endif
+ ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible
+
+ ld1 {v18.4s}, [x8], #16 //load rk0
+
+ lsr x5, x1, #3 //byte_len
+ mov x15, x5
+ ld1 {v19.4s}, [x8], #16 //load rk1
+
+ lsr x12, x11, #32
+ orr w11, w11, w11
+ fmov d3, x10 //CTR block 3
+
+ rev w12, w12 //rev_ctr32
+ fmov d1, x10 //CTR block 1
+
+ add w12, w12, #1 //increment rev_ctr32
+ ld1 {v20.4s}, [x8], #16 //load rk2
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 0
+ rev w9, w12 //CTR block 1
+
+ add w12, w12, #1 //CTR block 1
+ orr x9, x11, x9, lsl #32 //CTR block 1
+ ld1 {v21.4s}, [x8], #16 //load rk3
+
+ fmov v1.d[1], x9 //CTR block 1
+ rev w9, w12 //CTR block 2
+ add w12, w12, #1 //CTR block 2
+
+ fmov d2, x10 //CTR block 2
+ orr x9, x11, x9, lsl #32 //CTR block 2
+
+ fmov v2.d[1], x9 //CTR block 2
+ rev w9, w12 //CTR block 3
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 1
+ orr x9, x11, x9, lsl #32 //CTR block 3
+
+ fmov v3.d[1], x9 //CTR block 3
+
+ ld1 {v22.4s}, [x8], #16 //load rk4
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 2
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 0
+ ld1 {v23.4s}, [x8], #16 //load rk5
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 0
+ ldr q15, [x3, #112] //load h4l | h4h
+#ifndef __AARCH64EB__
+ ext v15.16b, v15.16b, v15.16b, #8
+#endif
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 0
+ ldr q13, [x3, #64] //load h2l | h2h
+#ifndef __AARCH64EB__
+ ext v13.16b, v13.16b, v13.16b, #8
+#endif
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 1
+ ldr q14, [x3, #80] //load h3l | h3h
+#ifndef __AARCH64EB__
+ ext v14.16b, v14.16b, v14.16b, #8
+#endif
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 1
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 1
+ ldr q12, [x3, #32] //load h1l | h1h
+#ifndef __AARCH64EB__
+ ext v12.16b, v12.16b, v12.16b, #8
+#endif
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 2
+ ld1 {v24.4s}, [x8], #16 //load rk6
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 3
+ ld1 {v25.4s}, [x8], #16 //load rk7
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 2
+ ld1 {v26.4s}, [x8], #16 //load rk8
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 2
+ ld1 {v27.4s}, [x8], #16 //load rk9
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 3
+ ld1 { v11.16b}, [x3]
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 3
+ add w12, w12, #1 //CTR block 3
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 3
+ trn1 v9.2d, v14.2d, v15.2d //h4h | h3h
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 4
+ ld1 {v28.4s}, [x8], #16 //load rk10
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 4
+ trn2 v17.2d, v14.2d, v15.2d //h4l | h3l
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 4
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 4
+ trn2 v16.2d, v12.2d, v13.2d //h2l | h1l
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 5
+ ld1 {v29.4s}, [x8], #16 //load rk11
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 5
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 5
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 5
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 6
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 6
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 6
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 7
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 7
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 7
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 6
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 8
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 8
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 7
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 9
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 9
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 8
+ sub x5, x5, #1 //byte_len - 1
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 8
+ and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail)
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 10
+ add x5, x5, x0
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 9
+ cmp x0, x5 //check if we have <= 4 blocks
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 9
+ trn1 v8.2d, v12.2d, v13.2d //h2h | h1h
+
+ aese v3.16b, v29.16b //AES block 3 - round 11
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 10
+
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 10
+
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 10
+ eor v16.16b, v16.16b, v8.16b //h2k | h1k
+
+ aese v2.16b, v29.16b //AES block 2 - round 11
+
+ aese v1.16b, v29.16b //AES block 1 - round 11
+ eor v17.16b, v17.16b, v9.16b //h4k | h3k
+
+ aese v0.16b, v29.16b //AES block 0 - round 11
+ b.ge .L192_dec_tail //handle tail
+
+ ld1 {v4.16b, v5.16b}, [x0], #32 //AES block 0,1 - load ciphertext
+
+ eor v1.16b, v5.16b, v1.16b //AES block 1 - result
+
+ eor v0.16b, v4.16b, v0.16b //AES block 0 - result
+ rev w9, w12 //CTR block 4
+ ld1 {v6.16b, v7.16b}, [x0], #32 //AES block 2,3 - load ciphertext
+
+ mov x19, v1.d[0] //AES block 1 - mov low
+
+ mov x20, v1.d[1] //AES block 1 - mov high
+
+ mov x6, v0.d[0] //AES block 0 - mov low
+ orr x9, x11, x9, lsl #32 //CTR block 4
+ add w12, w12, #1 //CTR block 4
+
+ mov x7, v0.d[1] //AES block 0 - mov high
+ rev64 v4.16b, v4.16b //GHASH block 0
+
+ fmov d0, x10 //CTR block 4
+ rev64 v5.16b, v5.16b //GHASH block 1
+ cmp x0, x5 //check if we have <= 8 blocks
+
+ eor x19, x19, x13 //AES block 1 - round 12 low
+#ifdef __AARCH64EB__
+ rev x19, x19
+#endif
+ fmov v0.d[1], x9 //CTR block 4
+ rev w9, w12 //CTR block 5
+
+ orr x9, x11, x9, lsl #32 //CTR block 5
+ fmov d1, x10 //CTR block 5
+ eor x20, x20, x14 //AES block 1 - round 12 high
+#ifdef __AARCH64EB__
+ rev x20, x20
+#endif
+ add w12, w12, #1 //CTR block 5
+ fmov v1.d[1], x9 //CTR block 5
+ eor x6, x6, x13 //AES block 0 - round 12 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ rev w9, w12 //CTR block 6
+ eor x7, x7, x14 //AES block 0 - round 12 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ stp x6, x7, [x2], #16 //AES block 0 - store result
+ orr x9, x11, x9, lsl #32 //CTR block 6
+
+ stp x19, x20, [x2], #16 //AES block 1 - store result
+
+ add w12, w12, #1 //CTR block 6
+ eor v2.16b, v6.16b, v2.16b //AES block 2 - result
+ b.ge .L192_dec_prepretail //do prepretail
+
+.L192_dec_main_loop: //main loop start
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+
+ pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+ mov x21, v2.d[0] //AES block 4k+2 - mov low
+
+ mov x22, v2.d[1] //AES block 4k+2 - mov high
+ eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result
+ rev64 v7.16b, v7.16b //GHASH block 4k+3
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+ fmov d2, x10 //CTR block 4k+6
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+
+ pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+ fmov v2.d[1], x9 //CTR block 4k+6
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+ mov x24, v3.d[1] //AES block 4k+3 - mov high
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+ mov x23, v3.d[0] //AES block 4k+3 - mov low
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+ fmov d3, x10 //CTR block 4k+7
+ mov d8, v4.d[1] //GHASH block 4k - mid
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+ mov d10, v17.d[1] //GHASH block 4k - mid
+ rev w9, w12 //CTR block 4k+7
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+ orr x9, x11, x9, lsl #32 //CTR block 4k+7
+
+ fmov v3.d[1], x9 //CTR block 4k+7
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+ mov d4, v5.d[1] //GHASH block 4k+1 - mid
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+ eor x22, x22, x14 //AES block 4k+2 - round 12 high
+#ifdef __AARCH64EB__
+ rev x22, x22
+#endif
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+ eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+ rev64 v6.16b, v6.16b //GHASH block 4k+2
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+
+ pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid
+ eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low
+ eor x21, x21, x13 //AES block 4k+2 - round 12 low
+#ifdef __AARCH64EB__
+ rev x21, x21
+#endif
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+
+ eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid
+ mov d31, v6.d[1] //GHASH block 4k+2 - mid
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+ eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+
+ pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+ eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid
+
+ pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+
+ eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high
+ mov d30, v7.d[1] //GHASH block 4k+3 - mid
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+
+ pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+ eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+ ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+
+ pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid
+ eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+
+ pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid
+ eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+ movi v8.8b, #0xc2
+
+ pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+ eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 9
+ eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid
+
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 10
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 9
+ eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+ shl d8, d8, #56 //mod_constant
+
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 10
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+ ld1 {v4.16b}, [x0], #16 //AES block 4k+4 - load ciphertext
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+ eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up
+
+ pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+ ld1 {v5.16b}, [x0], #16 //AES block 4k+5 - load ciphertext
+ eor x23, x23, x13 //AES block 4k+3 - round 12 low
+#ifdef __AARCH64EB__
+ rev x23, x23
+#endif
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ aese v0.16b, v29.16b //AES block 4k+4 - round 11
+ add w12, w12, #1 //CTR block 4k+7
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+ eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+ ld1 {v6.16b}, [x0], #16 //AES block 4k+6 - load ciphertext
+
+ aese v1.16b, v29.16b //AES block 4k+5 - round 11
+ ld1 {v7.16b}, [x0], #16 //AES block 4k+7 - load ciphertext
+ rev w9, w12 //CTR block 4k+8
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+ stp x21, x22, [x2], #16 //AES block 4k+2 - store result
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 9
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ cmp x0, x5 //.LOOP CONTROL
+
+ eor v0.16b, v4.16b, v0.16b //AES block 4k+4 - result
+ eor x24, x24, x14 //AES block 4k+3 - round 12 high
+#ifdef __AARCH64EB__
+ rev x24, x24
+#endif
+ eor v1.16b, v5.16b, v1.16b //AES block 4k+5 - result
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 10
+ orr x9, x11, x9, lsl #32 //CTR block 4k+8
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 9
+
+ pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+ mov x19, v1.d[0] //AES block 4k+5 - mov low
+
+ mov x6, v0.d[0] //AES block 4k+4 - mov low
+ stp x23, x24, [x2], #16 //AES block 4k+3 - store result
+ rev64 v5.16b, v5.16b //GHASH block 4k+5
+
+ aese v2.16b, v29.16b //AES block 4k+6 - round 11
+ mov x7, v0.d[1] //AES block 4k+4 - mov high
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 10
+ mov x20, v1.d[1] //AES block 4k+5 - mov high
+
+ fmov d0, x10 //CTR block 4k+8
+ add w12, w12, #1 //CTR block 4k+8
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ eor v2.16b, v6.16b, v2.16b //AES block 4k+6 - result
+ fmov v0.d[1], x9 //CTR block 4k+8
+ rev w9, w12 //CTR block 4k+9
+
+ eor x6, x6, x13 //AES block 4k+4 - round 12 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ orr x9, x11, x9, lsl #32 //CTR block 4k+9
+ eor v11.16b, v11.16b, v8.16b //MODULO - fold into low
+
+ fmov d1, x10 //CTR block 4k+9
+ add w12, w12, #1 //CTR block 4k+9
+ eor x19, x19, x13 //AES block 4k+5 - round 12 low
+#ifdef __AARCH64EB__
+ rev x19, x19
+#endif
+ fmov v1.d[1], x9 //CTR block 4k+9
+ rev w9, w12 //CTR block 4k+10
+ eor x20, x20, x14 //AES block 4k+5 - round 12 high
+#ifdef __AARCH64EB__
+ rev x20, x20
+#endif
+ eor x7, x7, x14 //AES block 4k+4 - round 12 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ stp x6, x7, [x2], #16 //AES block 4k+4 - store result
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+
+ add w12, w12, #1 //CTR block 4k+10
+ rev64 v4.16b, v4.16b //GHASH block 4k+4
+ orr x9, x11, x9, lsl #32 //CTR block 4k+10
+
+ aese v3.16b, v29.16b //AES block 4k+7 - round 11
+ stp x19, x20, [x2], #16 //AES block 4k+5 - store result
+ b.lt .L192_dec_main_loop
+
+.L192_dec_prepretail: //PREPRETAIL
+ mov x22, v2.d[1] //AES block 4k+2 - mov high
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+ eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ mov x21, v2.d[0] //AES block 4k+2 - mov low
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+ mov d10, v17.d[1] //GHASH block 4k - mid
+
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+ fmov d2, x10 //CTR block 4k+6
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+ mov x23, v3.d[0] //AES block 4k+3 - mov low
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+ mov x24, v3.d[1] //AES block 4k+3 - mov high
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+ mov d8, v4.d[1] //GHASH block 4k - mid
+ fmov d3, x10 //CTR block 4k+7
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+ rev64 v6.16b, v6.16b //GHASH block 4k+2
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+ fmov v2.d[1], x9 //CTR block 4k+6
+ rev w9, w12 //CTR block 4k+7
+
+ orr x9, x11, x9, lsl #32 //CTR block 4k+7
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+ mov d4, v5.d[1] //GHASH block 4k+1 - mid
+
+ pmull v31.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+ eor x24, x24, x14 //AES block 4k+3 - round 12 high
+#ifdef __AARCH64EB__
+ rev x24, x24
+#endif
+ fmov v3.d[1], x9 //CTR block 4k+7
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+ eor x21, x21, x13 //AES block 4k+2 - round 12 low
+#ifdef __AARCH64EB__
+ rev x21, x21
+#endif
+ pmull2 v30.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+ eor x22, x22, x14 //AES block 4k+2 - round 12 high
+#ifdef __AARCH64EB__
+ rev x22, x22
+#endif
+ eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+ eor x23, x23, x13 //AES block 4k+3 - round 12 low
+#ifdef __AARCH64EB__
+ rev x23, x23
+#endif
+ stp x21, x22, [x2], #16 //AES block 4k+2 - store result
+
+ rev64 v7.16b, v7.16b //GHASH block 4k+3
+ stp x23, x24, [x2], #16 //AES block 4k+3 - store result
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+ eor v9.16b, v9.16b, v30.16b //GHASH block 4k+1 - high
+
+ pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid
+ add w12, w12, #1 //CTR block 4k+7
+
+ pmull2 v30.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+ eor v11.16b, v11.16b, v31.16b //GHASH block 4k+1 - low
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+
+ eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid
+ mov d31, v6.d[1] //GHASH block 4k+2 - mid
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+ eor v9.16b, v9.16b, v30.16b //GHASH block 4k+2 - high
+
+ eor v31.8b, v31.8b, v6.8b //GHASH block 4k+2 - mid
+
+ pmull v8.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+ mov d30, v7.d[1] //GHASH block 4k+3 - mid
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+ ins v31.d[1], v31.d[0] //GHASH block 4k+2 - mid
+
+ pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+ eor v30.8b, v30.8b, v7.8b //GHASH block 4k+3 - mid
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+
+ pmull2 v31.1q, v31.2d, v16.2d //GHASH block 4k+2 - mid
+ eor v11.16b, v11.16b, v8.16b //GHASH block 4k+2 - low
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+
+ pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+ movi v8.8b, #0xc2
+
+ pmull v30.1q, v30.1d, v16.1d //GHASH block 4k+3 - mid
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+
+ shl d8, d8, #56 //mod_constant
+ eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+ eor v10.16b, v10.16b, v31.16b //GHASH block 4k+2 - mid
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+
+ pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+ eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+ eor v10.16b, v10.16b, v30.16b //GHASH block 4k+3 - mid
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+ eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+ eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 9
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+ eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid
+
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 10
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 9
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 9
+
+ pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 9
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 10
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 10
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 10
+
+ aese v0.16b, v29.16b
+ eor v11.16b, v11.16b, v8.16b //MODULO - fold into low
+
+ aese v2.16b, v29.16b
+
+ aese v1.16b, v29.16b
+
+ aese v3.16b, v29.16b
+
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+.L192_dec_tail: //TAIL
+
+ sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process
+ ld1 { v5.16b}, [x0], #16 //AES block 4k+4 - load ciphertext
+
+ eor v0.16b, v5.16b, v0.16b //AES block 4k+4 - result
+
+ mov x7, v0.d[1] //AES block 4k+4 - mov high
+
+ mov x6, v0.d[0] //AES block 4k+4 - mov low
+
+ ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag
+
+ cmp x5, #48
+
+ eor x7, x7, x14 //AES block 4k+4 - round 12 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ eor x6, x6, x13 //AES block 4k+4 - round 12 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ b.gt .L192_dec_blocks_more_than_3
+
+ movi v11.8b, #0
+ movi v9.8b, #0
+
+ mov v3.16b, v2.16b
+ mov v2.16b, v1.16b
+ sub w12, w12, #1
+
+ movi v10.8b, #0
+ cmp x5, #32
+ b.gt .L192_dec_blocks_more_than_2
+
+ mov v3.16b, v1.16b
+ cmp x5, #16
+ sub w12, w12, #1
+
+ b.gt .L192_dec_blocks_more_than_1
+
+ sub w12, w12, #1
+ b .L192_dec_blocks_less_than_1
+.L192_dec_blocks_more_than_3: //blocks left > 3
+ rev64 v4.16b, v5.16b //GHASH final-3 block
+ ld1 { v5.16b}, [x0], #16 //AES final-2 block - load ciphertext
+
+ stp x6, x7, [x2], #16 //AES final-3 block - store result
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ eor v0.16b, v5.16b, v1.16b //AES final-2 block - result
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low
+ mov x6, v0.d[0] //AES final-2 block - mov low
+ mov d22, v4.d[1] //GHASH final-3 block - mid
+
+ mov x7, v0.d[1] //AES final-2 block - mov high
+
+ mov d10, v17.d[1] //GHASH final-3 block - mid
+ eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high
+
+ eor x6, x6, x13 //AES final-2 block - round 12 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid
+ eor x7, x7, x14 //AES final-2 block - round 12 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+.L192_dec_blocks_more_than_2: //blocks left > 2
+
+ rev64 v4.16b, v5.16b //GHASH final-2 block
+ ld1 { v5.16b}, [x0], #16 //AES final-1 block - load ciphertext
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ eor v0.16b, v5.16b, v2.16b //AES final-1 block - result
+
+ mov d22, v4.d[1] //GHASH final-2 block - mid
+
+ pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low
+
+ stp x6, x7, [x2], #16 //AES final-2 block - store result
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid
+ mov x7, v0.d[1] //AES final-1 block - mov high
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low
+ mov x6, v0.d[0] //AES final-1 block - mov low
+
+ pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high
+
+ pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high
+ eor x7, x7, x14 //AES final-1 block - round 12 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ eor x6, x6, x13 //AES final-1 block - round 12 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid
+.L192_dec_blocks_more_than_1: //blocks left > 1
+
+ rev64 v4.16b, v5.16b //GHASH final-1 block
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+ ld1 { v5.16b}, [x0], #16 //AES final block - load ciphertext
+
+ mov d22, v4.d[1] //GHASH final-1 block - mid
+
+ pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high
+
+ eor v0.16b, v5.16b, v3.16b //AES final block - result
+ stp x6, x7, [x2], #16 //AES final-1 block - store result
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high
+
+ pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low
+ mov x7, v0.d[1] //AES final block - mov high
+
+ ins v22.d[1], v22.d[0] //GHASH final-1 block - mid
+ mov x6, v0.d[0] //AES final block - mov low
+
+ pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid
+
+ movi v8.8b, #0 //suppress further partial tag feed in
+ eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low
+ eor x7, x7, x14 //AES final block - round 12 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ eor x6, x6, x13 //AES final block - round 12 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid
+.L192_dec_blocks_less_than_1: //blocks left <= 1
+
+ mvn x13, xzr //rk12_l = 0xffffffffffffffff
+ ldp x4, x5, [x2] //load existing bytes we need to not overwrite
+ and x1, x1, #127 //bit_length %= 128
+
+ sub x1, x1, #128 //bit_length -= 128
+
+ neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128])
+
+ and x1, x1, #127 //bit_length %= 128
+ mvn x14, xzr //rk12_h = 0xffffffffffffffff
+
+ lsr x14, x14, x1 //rk12_h is mask for top 64b of last block
+ cmp x1, #64
+
+ csel x9, x13, x14, lt
+ csel x10, x14, xzr, lt
+
+ fmov d0, x9 //ctr0b is mask for last block
+ and x6, x6, x9
+ bic x4, x4, x9 //mask out low existing bytes
+
+ orr x6, x6, x4
+ mov v0.d[1], x10
+#ifndef __AARCH64EB__
+ rev w9, w12
+#else
+ mov w9, w12
+#endif
+
+ and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits
+ str w9, [x16, #12] //store the updated counter
+
+ rev64 v4.16b, v5.16b //GHASH final block
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+ bic x5, x5, x10 //mask out high existing bytes
+
+ and x7, x7, x10
+
+ pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high
+ mov d8, v4.d[1] //GHASH final block - mid
+
+ pmull v21.1q, v4.1d, v12.1d //GHASH final block - low
+
+ eor v8.8b, v8.8b, v4.8b //GHASH final block - mid
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final block - high
+
+ pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final block - low
+
+ eor v10.16b, v10.16b, v8.16b //GHASH final block - mid
+ movi v8.8b, #0xc2
+
+ eor v30.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ shl d8, d8, #56 //mod_constant
+
+ eor v10.16b, v10.16b, v30.16b //MODULO - karatsuba tidy up
+
+ pmull v31.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+ orr x7, x7, x5
+ stp x6, x7, [x2]
+
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ eor v10.16b, v10.16b, v31.16b //MODULO - fold into mid
+
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+
+ eor v11.16b, v11.16b, v8.16b //MODULO - fold into low
+
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+ mov x0, x15
+ st1 { v11.16b }, [x3]
+
+ ldp x21, x22, [sp, #16]
+ ldp x23, x24, [sp, #32]
+ ldp d8, d9, [sp, #48]
+ ldp d10, d11, [sp, #64]
+ ldp d12, d13, [sp, #80]
+ ldp d14, d15, [sp, #96]
+ ldp x19, x20, [sp], #112
+ ret
+
+.L192_dec_ret:
+ mov w0, #0x0
+ ret
+.size aes_gcm_dec_192_kernel,.-aes_gcm_dec_192_kernel
+.globl aes_gcm_enc_256_kernel
+.type aes_gcm_enc_256_kernel,%function
+.align 4
+aes_gcm_enc_256_kernel:
+ cbz x1, .L256_enc_ret
+ stp x19, x20, [sp, #-112]!
+ mov x16, x4
+ mov x8, x5
+ stp x21, x22, [sp, #16]
+ stp x23, x24, [sp, #32]
+ stp d8, d9, [sp, #48]
+ stp d10, d11, [sp, #64]
+ stp d12, d13, [sp, #80]
+ stp d14, d15, [sp, #96]
+
+ add x4, x0, x1, lsr #3 //end_input_ptr
+ lsr x5, x1, #3 //byte_len
+ mov x15, x5
+ ldp x10, x11, [x16] //ctr96_b64, ctr96_t32
+#ifdef __AARCH64EB__
+ rev x10, x10
+ rev x11, x11
+#endif
+ ldp x13, x14, [x8, #224] //load rk14
+#ifdef __AARCH64EB__
+ ror x13, x13, #32
+ ror x14, x14, #32
+#endif
+ ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible
+ sub x5, x5, #1 //byte_len - 1
+
+ ld1 {v18.4s}, [x8], #16 //load rk0
+ and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail)
+
+ ld1 {v19.4s}, [x8], #16 //load rk1
+ add x5, x5, x0
+
+ lsr x12, x11, #32
+ fmov d2, x10 //CTR block 2
+ orr w11, w11, w11
+
+ rev w12, w12 //rev_ctr32
+ cmp x0, x5 //check if we have <= 4 blocks
+ fmov d1, x10 //CTR block 1
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 0
+ add w12, w12, #1 //increment rev_ctr32
+
+ rev w9, w12 //CTR block 1
+ fmov d3, x10 //CTR block 3
+
+ orr x9, x11, x9, lsl #32 //CTR block 1
+ add w12, w12, #1 //CTR block 1
+ ld1 {v20.4s}, [x8], #16 //load rk2
+
+ fmov v1.d[1], x9 //CTR block 1
+ rev w9, w12 //CTR block 2
+ add w12, w12, #1 //CTR block 2
+
+ orr x9, x11, x9, lsl #32 //CTR block 2
+ ld1 {v21.4s}, [x8], #16 //load rk3
+
+ fmov v2.d[1], x9 //CTR block 2
+ rev w9, w12 //CTR block 3
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 1
+ orr x9, x11, x9, lsl #32 //CTR block 3
+
+ fmov v3.d[1], x9 //CTR block 3
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 0
+ ld1 {v22.4s}, [x8], #16 //load rk4
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 2
+ ld1 {v23.4s}, [x8], #16 //load rk5
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 0
+ ld1 {v24.4s}, [x8], #16 //load rk6
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 1
+ ldr q14, [x3, #80] //load h3l | h3h
+#ifndef __AARCH64EB__
+ ext v14.16b, v14.16b, v14.16b, #8
+#endif
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 0
+ ld1 {v25.4s}, [x8], #16 //load rk7
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 1
+ ld1 {v26.4s}, [x8], #16 //load rk8
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 2
+ ldr q13, [x3, #64] //load h2l | h2h
+#ifndef __AARCH64EB__
+ ext v13.16b, v13.16b, v13.16b, #8
+#endif
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 1
+ ld1 {v27.4s}, [x8], #16 //load rk9
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 2
+ ldr q15, [x3, #112] //load h4l | h4h
+#ifndef __AARCH64EB__
+ ext v15.16b, v15.16b, v15.16b, #8
+#endif
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 3
+ ld1 {v28.4s}, [x8], #16 //load rk10
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 2
+ ld1 {v29.4s}, [x8], #16 //load rk11
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 3
+ add w12, w12, #1 //CTR block 3
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 3
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 3
+ ld1 { v11.16b}, [x3]
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 4
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 4
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 4
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 4
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 5
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 5
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 5
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 5
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 6
+ trn2 v17.2d, v14.2d, v15.2d //h4l | h3l
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 6
+ ld1 {v30.4s}, [x8], #16 //load rk12
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 6
+ ldr q12, [x3, #32] //load h1l | h1h
+#ifndef __AARCH64EB__
+ ext v12.16b, v12.16b, v12.16b, #8
+#endif
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 6
+ ld1 {v31.4s}, [x8], #16 //load rk13
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 7
+ trn1 v9.2d, v14.2d, v15.2d //h4h | h3h
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 7
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 7
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 7
+ trn2 v16.2d, v12.2d, v13.2d //h2l | h1l
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 8
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 8
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 8
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 9
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 9
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 8
+
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 10
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 9
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 9
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 10
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 10
+
+ aese v1.16b, v29.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 11
+
+ aese v2.16b, v29.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 11
+
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 10
+
+ aese v1.16b, v30.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 12
+
+ aese v2.16b, v30.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 12
+
+ aese v0.16b, v29.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 11
+ eor v17.16b, v17.16b, v9.16b //h4k | h3k
+
+ aese v3.16b, v29.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 11
+
+ aese v2.16b, v31.16b //AES block 2 - round 13
+ trn1 v8.2d, v12.2d, v13.2d //h2h | h1h
+
+ aese v0.16b, v30.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 12
+
+ aese v3.16b, v30.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 12
+
+ aese v1.16b, v31.16b //AES block 1 - round 13
+
+ aese v0.16b, v31.16b //AES block 0 - round 13
+
+ aese v3.16b, v31.16b //AES block 3 - round 13
+ eor v16.16b, v16.16b, v8.16b //h2k | h1k
+ b.ge .L256_enc_tail //handle tail
+
+ ldp x19, x20, [x0, #16] //AES block 1 - load plaintext
+#ifdef __AARCH64EB__
+ rev x19, x19
+ rev x20, x20
+#endif
+ rev w9, w12 //CTR block 4
+ ldp x6, x7, [x0, #0] //AES block 0 - load plaintext
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ ldp x23, x24, [x0, #48] //AES block 3 - load plaintext
+#ifdef __AARCH64EB__
+ rev x23, x23
+ rev x24, x24
+#endif
+ ldp x21, x22, [x0, #32] //AES block 2 - load plaintext
+#ifdef __AARCH64EB__
+ rev x21, x21
+ rev x22, x22
+#endif
+ add x0, x0, #64 //AES input_ptr update
+
+ eor x19, x19, x13 //AES block 1 - round 14 low
+ eor x20, x20, x14 //AES block 1 - round 14 high
+
+ fmov d5, x19 //AES block 1 - mov low
+ eor x6, x6, x13 //AES block 0 - round 14 low
+
+ eor x7, x7, x14 //AES block 0 - round 14 high
+ eor x24, x24, x14 //AES block 3 - round 14 high
+ fmov d4, x6 //AES block 0 - mov low
+
+ cmp x0, x5 //check if we have <= 8 blocks
+ fmov v4.d[1], x7 //AES block 0 - mov high
+ eor x23, x23, x13 //AES block 3 - round 14 low
+
+ eor x21, x21, x13 //AES block 2 - round 14 low
+ fmov v5.d[1], x20 //AES block 1 - mov high
+
+ fmov d6, x21 //AES block 2 - mov low
+ add w12, w12, #1 //CTR block 4
+
+ orr x9, x11, x9, lsl #32 //CTR block 4
+ fmov d7, x23 //AES block 3 - mov low
+ eor x22, x22, x14 //AES block 2 - round 14 high
+
+ fmov v6.d[1], x22 //AES block 2 - mov high
+
+ eor v4.16b, v4.16b, v0.16b //AES block 0 - result
+ fmov d0, x10 //CTR block 4
+
+ fmov v0.d[1], x9 //CTR block 4
+ rev w9, w12 //CTR block 5
+ add w12, w12, #1 //CTR block 5
+
+ eor v5.16b, v5.16b, v1.16b //AES block 1 - result
+ fmov d1, x10 //CTR block 5
+ orr x9, x11, x9, lsl #32 //CTR block 5
+
+ fmov v1.d[1], x9 //CTR block 5
+ rev w9, w12 //CTR block 6
+ st1 { v4.16b}, [x2], #16 //AES block 0 - store result
+
+ fmov v7.d[1], x24 //AES block 3 - mov high
+ orr x9, x11, x9, lsl #32 //CTR block 6
+ eor v6.16b, v6.16b, v2.16b //AES block 2 - result
+
+ st1 { v5.16b}, [x2], #16 //AES block 1 - store result
+
+ add w12, w12, #1 //CTR block 6
+ fmov d2, x10 //CTR block 6
+
+ fmov v2.d[1], x9 //CTR block 6
+ st1 { v6.16b}, [x2], #16 //AES block 2 - store result
+ rev w9, w12 //CTR block 7
+
+ orr x9, x11, x9, lsl #32 //CTR block 7
+
+ eor v7.16b, v7.16b, v3.16b //AES block 3 - result
+ st1 { v7.16b}, [x2], #16 //AES block 3 - store result
+ b.ge .L256_enc_prepretail //do prepretail
+
+.L256_enc_main_loop: //main loop start
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+ rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free)
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ fmov d3, x10 //CTR block 4k+3
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+ fmov v3.d[1], x9 //CTR block 4k+3
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+ ldp x23, x24, [x0, #48] //AES block 4k+7 - load plaintext
+#ifdef __AARCH64EB__
+ rev x23, x23
+ rev x24, x24
+#endif
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+ ldp x21, x22, [x0, #32] //AES block 4k+6 - load plaintext
+#ifdef __AARCH64EB__
+ rev x21, x21
+ rev x22, x22
+#endif
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+ eor x23, x23, x13 //AES block 4k+7 - round 14 low
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+ mov d10, v17.d[1] //GHASH block 4k - mid
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+ eor x22, x22, x14 //AES block 4k+6 - round 14 high
+ mov d8, v4.d[1] //GHASH block 4k - mid
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+ rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free)
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+ rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free)
+
+ pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+ rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free)
+
+ pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high
+ mov d4, v5.d[1] //GHASH block 4k+1 - mid
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+ eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+ mov d8, v6.d[1] //GHASH block 4k+2 - mid
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+ eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+ eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+
+ pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+ ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+ eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid
+
+ pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+
+ pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+
+ pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+ ldp x19, x20, [x0, #16] //AES block 4k+5 - load plaintext
+#ifdef __AARCH64EB__
+ rev x19, x19
+ rev x20, x20
+#endif
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+ mov d4, v7.d[1] //GHASH block 4k+3 - mid
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+ eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low
+
+ pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid
+
+ pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+ eor v4.8b, v4.8b, v7.8b //GHASH block 4k+3 - mid
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+ eor x19, x19, x13 //AES block 4k+5 - round 14 low
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 9
+ eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+ eor x21, x21, x13 //AES block 4k+6 - round 14 low
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 9
+ movi v8.8b, #0xc2
+
+ pmull v4.1q, v4.1d, v16.1d //GHASH block 4k+3 - mid
+ eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high
+ fmov d5, x19 //AES block 4k+5 - mov low
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+ ldp x6, x7, [x0, #0] //AES block 4k+4 - load plaintext
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 10
+ shl d8, d8, #56 //mod_constant
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+ eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 9
+
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 10
+ eor v10.16b, v10.16b, v4.16b //GHASH block 4k+3 - mid
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 9
+ add w12, w12, #1 //CTR block 4k+3
+
+ aese v0.16b, v29.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 11
+ eor v4.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ aese v1.16b, v29.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 11
+ add x0, x0, #64 //AES input_ptr update
+
+ pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+ rev w9, w12 //CTR block 4k+8
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 10
+ eor x6, x6, x13 //AES block 4k+4 - round 14 low
+
+ aese v1.16b, v30.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 12
+ eor v10.16b, v10.16b, v4.16b //MODULO - karatsuba tidy up
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 10
+ eor x7, x7, x14 //AES block 4k+4 - round 14 high
+
+ fmov d4, x6 //AES block 4k+4 - mov low
+ orr x9, x11, x9, lsl #32 //CTR block 4k+8
+ eor v7.16b, v9.16b, v7.16b //MODULO - fold into mid
+
+ aese v0.16b, v30.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 12
+ eor x20, x20, x14 //AES block 4k+5 - round 14 high
+
+ aese v2.16b, v29.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 11
+ eor x24, x24, x14 //AES block 4k+7 - round 14 high
+
+ aese v3.16b, v29.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 11
+ add w12, w12, #1 //CTR block 4k+8
+
+ aese v0.16b, v31.16b //AES block 4k+4 - round 13
+ fmov v4.d[1], x7 //AES block 4k+4 - mov high
+ eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid
+
+ aese v2.16b, v30.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 12
+ fmov d7, x23 //AES block 4k+7 - mov low
+
+ aese v1.16b, v31.16b //AES block 4k+5 - round 13
+ fmov v5.d[1], x20 //AES block 4k+5 - mov high
+
+ fmov d6, x21 //AES block 4k+6 - mov low
+ cmp x0, x5 //.LOOP CONTROL
+
+ fmov v6.d[1], x22 //AES block 4k+6 - mov high
+
+ pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+ eor v4.16b, v4.16b, v0.16b //AES block 4k+4 - result
+ fmov d0, x10 //CTR block 4k+8
+
+ fmov v0.d[1], x9 //CTR block 4k+8
+ rev w9, w12 //CTR block 4k+9
+ add w12, w12, #1 //CTR block 4k+9
+
+ eor v5.16b, v5.16b, v1.16b //AES block 4k+5 - result
+ fmov d1, x10 //CTR block 4k+9
+ orr x9, x11, x9, lsl #32 //CTR block 4k+9
+
+ aese v3.16b, v30.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 12
+ fmov v1.d[1], x9 //CTR block 4k+9
+
+ aese v2.16b, v31.16b //AES block 4k+6 - round 13
+ rev w9, w12 //CTR block 4k+10
+ st1 { v4.16b}, [x2], #16 //AES block 4k+4 - store result
+
+ orr x9, x11, x9, lsl #32 //CTR block 4k+10
+ eor v11.16b, v11.16b, v9.16b //MODULO - fold into low
+ fmov v7.d[1], x24 //AES block 4k+7 - mov high
+
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+ st1 { v5.16b}, [x2], #16 //AES block 4k+5 - store result
+ add w12, w12, #1 //CTR block 4k+10
+
+ aese v3.16b, v31.16b //AES block 4k+7 - round 13
+ eor v6.16b, v6.16b, v2.16b //AES block 4k+6 - result
+ fmov d2, x10 //CTR block 4k+10
+
+ st1 { v6.16b}, [x2], #16 //AES block 4k+6 - store result
+ fmov v2.d[1], x9 //CTR block 4k+10
+ rev w9, w12 //CTR block 4k+11
+
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+ orr x9, x11, x9, lsl #32 //CTR block 4k+11
+
+ eor v7.16b, v7.16b, v3.16b //AES block 4k+7 - result
+ st1 { v7.16b}, [x2], #16 //AES block 4k+7 - store result
+ b.lt .L256_enc_main_loop
+
+.L256_enc_prepretail: //PREPRETAIL
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ rev64 v6.16b, v6.16b //GHASH block 4k+2 (t0, t1, and t2 free)
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+ fmov d3, x10 //CTR block 4k+3
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+ rev64 v4.16b, v4.16b //GHASH block 4k (only t0 is free)
+
+ fmov v3.d[1], x9 //CTR block 4k+3
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+ rev64 v5.16b, v5.16b //GHASH block 4k+1 (t0 and t1 free)
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+ mov d10, v17.d[1] //GHASH block 4k - mid
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+ mov d8, v4.d[1] //GHASH block 4k - mid
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+
+ pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+
+ pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high
+ mov d4, v5.d[1] //GHASH block 4k+1 - mid
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+ eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+
+ eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid
+ mov d8, v6.d[1] //GHASH block 4k+2 - mid
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+ rev64 v7.16b, v7.16b //GHASH block 4k+3 (t0, t1, t2 and t3 free)
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+
+ pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid
+ eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid
+ add w12, w12, #1 //CTR block 4k+3
+
+ pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+ eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid
+
+ pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+
+ eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low
+ ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high
+ mov d4, v7.d[1] //GHASH block 4k+3 - mid
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+
+ pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid
+
+ eor v4.8b, v4.8b, v7.8b //GHASH block 4k+3 - mid
+
+ pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+
+ pmull v4.1q, v4.1d, v16.1d //GHASH block 4k+3 - mid
+ eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+ movi v8.8b, #0xc2
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+ eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+ shl d8, d8, #56 //mod_constant
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+ eor v10.16b, v10.16b, v4.16b //GHASH block 4k+3 - mid
+
+ pmull v6.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 9
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+ eor v11.16b, v11.16b, v6.16b //GHASH block 4k+3 - low
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 9
+
+ eor v10.16b, v10.16b, v9.16b //karatsuba tidy up
+
+ pmull v4.1q, v9.1d, v8.1d
+ ext v9.16b, v9.16b, v9.16b, #8
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 10
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+ eor v10.16b, v10.16b, v11.16b
+
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 10
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 9
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+
+ aese v1.16b, v29.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 11
+ eor v10.16b, v10.16b, v4.16b
+
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 10
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 9
+
+ aese v1.16b, v30.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 12
+
+ aese v0.16b, v29.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 11
+ eor v10.16b, v10.16b, v9.16b
+
+ aese v3.16b, v29.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 11
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 10
+
+ aese v0.16b, v30.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 12
+
+ pmull v4.1q, v10.1d, v8.1d
+
+ aese v2.16b, v29.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 11
+ ext v10.16b, v10.16b, v10.16b, #8
+
+ aese v3.16b, v30.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 12
+
+ aese v1.16b, v31.16b //AES block 4k+5 - round 13
+ eor v11.16b, v11.16b, v4.16b
+
+ aese v2.16b, v30.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 12
+
+ aese v3.16b, v31.16b //AES block 4k+7 - round 13
+
+ aese v0.16b, v31.16b //AES block 4k+4 - round 13
+
+ aese v2.16b, v31.16b //AES block 4k+6 - round 13
+ eor v11.16b, v11.16b, v10.16b
+.L256_enc_tail: //TAIL
+
+ ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag
+ sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process
+ ldp x6, x7, [x0], #16 //AES block 4k+4 - load plaintext
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ eor x6, x6, x13 //AES block 4k+4 - round 14 low
+ eor x7, x7, x14 //AES block 4k+4 - round 14 high
+
+ cmp x5, #48
+ fmov d4, x6 //AES block 4k+4 - mov low
+
+ fmov v4.d[1], x7 //AES block 4k+4 - mov high
+
+ eor v5.16b, v4.16b, v0.16b //AES block 4k+4 - result
+ b.gt .L256_enc_blocks_more_than_3
+
+ cmp x5, #32
+ mov v3.16b, v2.16b
+ movi v11.8b, #0
+
+ movi v9.8b, #0
+ sub w12, w12, #1
+
+ mov v2.16b, v1.16b
+ movi v10.8b, #0
+ b.gt .L256_enc_blocks_more_than_2
+
+ mov v3.16b, v1.16b
+ sub w12, w12, #1
+ cmp x5, #16
+
+ b.gt .L256_enc_blocks_more_than_1
+
+ sub w12, w12, #1
+ b .L256_enc_blocks_less_than_1
+.L256_enc_blocks_more_than_3: //blocks left > 3
+ st1 { v5.16b}, [x2], #16 //AES final-3 block - store result
+
+ ldp x6, x7, [x0], #16 //AES final-2 block - load input low & high
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ rev64 v4.16b, v5.16b //GHASH final-3 block
+
+ eor x6, x6, x13 //AES final-2 block - round 14 low
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ eor x7, x7, x14 //AES final-2 block - round 14 high
+
+ mov d22, v4.d[1] //GHASH final-3 block - mid
+ fmov d5, x6 //AES final-2 block - mov low
+
+ fmov v5.d[1], x7 //AES final-2 block - mov high
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ mov d10, v17.d[1] //GHASH final-3 block - mid
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high
+
+ pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid
+ eor v5.16b, v5.16b, v1.16b //AES final-2 block - result
+.L256_enc_blocks_more_than_2: //blocks left > 2
+
+ st1 { v5.16b}, [x2], #16 //AES final-2 block - store result
+
+ ldp x6, x7, [x0], #16 //AES final-1 block - load input low & high
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ rev64 v4.16b, v5.16b //GHASH final-2 block
+
+ eor x6, x6, x13 //AES final-1 block - round 14 low
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ fmov d5, x6 //AES final-1 block - mov low
+ eor x7, x7, x14 //AES final-1 block - round 14 high
+
+ fmov v5.d[1], x7 //AES final-1 block - mov high
+
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high
+ mov d22, v4.d[1] //GHASH final-2 block - mid
+
+ pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid
+
+ eor v5.16b, v5.16b, v2.16b //AES final-1 block - result
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high
+
+ pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low
+
+ eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid
+.L256_enc_blocks_more_than_1: //blocks left > 1
+
+ st1 { v5.16b}, [x2], #16 //AES final-1 block - store result
+
+ rev64 v4.16b, v5.16b //GHASH final-1 block
+
+ ldp x6, x7, [x0], #16 //AES final block - load input low & high
+#ifdef __AARCH64EB__
+ rev x6, x6
+ rev x7, x7
+#endif
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ eor x6, x6, x13 //AES final block - round 14 low
+ mov d22, v4.d[1] //GHASH final-1 block - mid
+
+ pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high
+ eor x7, x7, x14 //AES final block - round 14 high
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high
+
+ ins v22.d[1], v22.d[0] //GHASH final-1 block - mid
+ fmov d5, x6 //AES final block - mov low
+
+ fmov v5.d[1], x7 //AES final block - mov high
+
+ pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid
+
+ pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low
+
+ eor v5.16b, v5.16b, v3.16b //AES final block - result
+ eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low
+.L256_enc_blocks_less_than_1: //blocks left <= 1
+
+ and x1, x1, #127 //bit_length %= 128
+
+ mvn x13, xzr //rk14_l = 0xffffffffffffffff
+ sub x1, x1, #128 //bit_length -= 128
+
+ neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128])
+ ld1 { v18.16b}, [x2] //load existing bytes where the possibly partial last block is to be stored
+
+ mvn x14, xzr //rk14_h = 0xffffffffffffffff
+ and x1, x1, #127 //bit_length %= 128
+
+ lsr x14, x14, x1 //rk14_h is mask for top 64b of last block
+ cmp x1, #64
+
+ csel x6, x13, x14, lt
+ csel x7, x14, xzr, lt
+
+ fmov d0, x6 //ctr0b is mask for last block
+
+ fmov v0.d[1], x7
+
+ and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits
+
+ rev64 v4.16b, v5.16b //GHASH final block
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ bif v5.16b, v18.16b, v0.16b //insert existing bytes in top end of result before storing
+
+ pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high
+ mov d8, v4.d[1] //GHASH final block - mid
+#ifndef __AARCH64EB__
+ rev w9, w12
+#else
+ mov w9, w12
+#endif
+
+ pmull v21.1q, v4.1d, v12.1d //GHASH final block - low
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final block - high
+ eor v8.8b, v8.8b, v4.8b //GHASH final block - mid
+
+ pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final block - low
+
+ eor v10.16b, v10.16b, v8.16b //GHASH final block - mid
+ movi v8.8b, #0xc2
+
+ eor v4.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ shl d8, d8, #56 //mod_constant
+
+ eor v10.16b, v10.16b, v4.16b //MODULO - karatsuba tidy up
+
+ pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid
+
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ pmull v9.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ str w9, [x16, #12] //store the updated counter
+
+ st1 { v5.16b}, [x2] //store all 16B
+ eor v11.16b, v11.16b, v9.16b //MODULO - fold into low
+
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+ mov x0, x15
+ st1 { v11.16b }, [x3]
+
+ ldp x21, x22, [sp, #16]
+ ldp x23, x24, [sp, #32]
+ ldp d8, d9, [sp, #48]
+ ldp d10, d11, [sp, #64]
+ ldp d12, d13, [sp, #80]
+ ldp d14, d15, [sp, #96]
+ ldp x19, x20, [sp], #112
+ ret
+
+.L256_enc_ret:
+ mov w0, #0x0
+ ret
+.size aes_gcm_enc_256_kernel,.-aes_gcm_enc_256_kernel
+.globl aes_gcm_dec_256_kernel
+.type aes_gcm_dec_256_kernel,%function
+.align 4
+aes_gcm_dec_256_kernel:
+ cbz x1, .L256_dec_ret
+ stp x19, x20, [sp, #-112]!
+ mov x16, x4
+ mov x8, x5
+ stp x21, x22, [sp, #16]
+ stp x23, x24, [sp, #32]
+ stp d8, d9, [sp, #48]
+ stp d10, d11, [sp, #64]
+ stp d12, d13, [sp, #80]
+ stp d14, d15, [sp, #96]
+
+ lsr x5, x1, #3 //byte_len
+ mov x15, x5
+ ldp x10, x11, [x16] //ctr96_b64, ctr96_t32
+#ifdef __AARCH64EB__
+ rev x10, x10
+ rev x11, x11
+#endif
+ ldp x13, x14, [x8, #224] //load rk14
+#ifdef __AARCH64EB__
+ ror x14, x14, #32
+ ror x13, x13, #32
+#endif
+ ld1 {v18.4s}, [x8], #16 //load rk0
+ sub x5, x5, #1 //byte_len - 1
+
+ ld1 {v19.4s}, [x8], #16 //load rk1
+ and x5, x5, #0xffffffffffffffc0 //number of bytes to be processed in main loop (at least 1 byte must be handled by tail)
+
+ add x4, x0, x1, lsr #3 //end_input_ptr
+ ld1 {v20.4s}, [x8], #16 //load rk2
+
+ lsr x12, x11, #32
+ ld1 {v21.4s}, [x8], #16 //load rk3
+ orr w11, w11, w11
+
+ ld1 {v22.4s}, [x8], #16 //load rk4
+ add x5, x5, x0
+ rev w12, w12 //rev_ctr32
+
+ add w12, w12, #1 //increment rev_ctr32
+ fmov d3, x10 //CTR block 3
+
+ rev w9, w12 //CTR block 1
+ add w12, w12, #1 //CTR block 1
+ fmov d1, x10 //CTR block 1
+
+ orr x9, x11, x9, lsl #32 //CTR block 1
+ ld1 { v0.16b}, [x16] //special case vector load initial counter so we can start first AES block as quickly as possible
+
+ fmov v1.d[1], x9 //CTR block 1
+ rev w9, w12 //CTR block 2
+ add w12, w12, #1 //CTR block 2
+
+ fmov d2, x10 //CTR block 2
+ orr x9, x11, x9, lsl #32 //CTR block 2
+
+ fmov v2.d[1], x9 //CTR block 2
+ rev w9, w12 //CTR block 3
+
+ orr x9, x11, x9, lsl #32 //CTR block 3
+ ld1 {v23.4s}, [x8], #16 //load rk5
+
+ fmov v3.d[1], x9 //CTR block 3
+ add w12, w12, #1 //CTR block 3
+
+ ld1 {v24.4s}, [x8], #16 //load rk6
+
+ ld1 {v25.4s}, [x8], #16 //load rk7
+
+ ld1 {v26.4s}, [x8], #16 //load rk8
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 0
+ ldr q14, [x3, #80] //load h3l | h3h
+#ifndef __AARCH64EB__
+ ext v14.16b, v14.16b, v14.16b, #8
+#endif
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 0
+ ldr q15, [x3, #112] //load h4l | h4h
+#ifndef __AARCH64EB__
+ ext v15.16b, v15.16b, v15.16b, #8
+#endif
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 0
+ ldr q13, [x3, #64] //load h2l | h2h
+#ifndef __AARCH64EB__
+ ext v13.16b, v13.16b, v13.16b, #8
+#endif
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 0
+ ld1 {v27.4s}, [x8], #16 //load rk9
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 1
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 1
+ ld1 { v11.16b}, [x3]
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 1
+ ld1 {v28.4s}, [x8], #16 //load rk10
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 1
+ ld1 {v29.4s}, [x8], #16 //load rk11
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 2
+ ldr q12, [x3, #32] //load h1l | h1h
+#ifndef __AARCH64EB__
+ ext v12.16b, v12.16b, v12.16b, #8
+#endif
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 2
+ ld1 {v30.4s}, [x8], #16 //load rk12
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 2
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 3
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 2
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 3
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 4
+ cmp x0, x5 //check if we have <= 4 blocks
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 3
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 3
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 4
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 4
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 4
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 5
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 5
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 5
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 5
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 6
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 6
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 6
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 6
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 7
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 7
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 7
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 8
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 7
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 8
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 8
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 9
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 8
+ ld1 {v31.4s}, [x8], #16 //load rk13
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 9
+
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 10
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 9
+
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 10
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 9
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 10
+
+ aese v0.16b, v29.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 11
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 10
+
+ aese v3.16b, v29.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 11
+
+ aese v1.16b, v29.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 11
+
+ aese v2.16b, v29.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 11
+
+ trn1 v9.2d, v14.2d, v15.2d //h4h | h3h
+
+ trn2 v17.2d, v14.2d, v15.2d //h4l | h3l
+
+ trn1 v8.2d, v12.2d, v13.2d //h2h | h1h
+ trn2 v16.2d, v12.2d, v13.2d //h2l | h1l
+
+ aese v1.16b, v30.16b
+ aesmc v1.16b, v1.16b //AES block 1 - round 12
+
+ aese v0.16b, v30.16b
+ aesmc v0.16b, v0.16b //AES block 0 - round 12
+
+ aese v2.16b, v30.16b
+ aesmc v2.16b, v2.16b //AES block 2 - round 12
+
+ aese v3.16b, v30.16b
+ aesmc v3.16b, v3.16b //AES block 3 - round 12
+ eor v17.16b, v17.16b, v9.16b //h4k | h3k
+
+ aese v1.16b, v31.16b //AES block 1 - round 13
+
+ aese v2.16b, v31.16b //AES block 2 - round 13
+ eor v16.16b, v16.16b, v8.16b //h2k | h1k
+
+ aese v3.16b, v31.16b //AES block 3 - round 13
+
+ aese v0.16b, v31.16b //AES block 0 - round 13
+ b.ge .L256_dec_tail //handle tail
+
+ ld1 {v4.16b, v5.16b}, [x0], #32 //AES block 0,1 - load ciphertext
+
+ rev w9, w12 //CTR block 4
+
+ eor v0.16b, v4.16b, v0.16b //AES block 0 - result
+
+ eor v1.16b, v5.16b, v1.16b //AES block 1 - result
+ rev64 v5.16b, v5.16b //GHASH block 1
+ ld1 {v6.16b}, [x0], #16 //AES block 2 - load ciphertext
+
+ mov x7, v0.d[1] //AES block 0 - mov high
+
+ mov x6, v0.d[0] //AES block 0 - mov low
+ rev64 v4.16b, v4.16b //GHASH block 0
+ add w12, w12, #1 //CTR block 4
+
+ fmov d0, x10 //CTR block 4
+ orr x9, x11, x9, lsl #32 //CTR block 4
+
+ fmov v0.d[1], x9 //CTR block 4
+ rev w9, w12 //CTR block 5
+ add w12, w12, #1 //CTR block 5
+
+ mov x19, v1.d[0] //AES block 1 - mov low
+
+ orr x9, x11, x9, lsl #32 //CTR block 5
+ mov x20, v1.d[1] //AES block 1 - mov high
+ eor x7, x7, x14 //AES block 0 - round 14 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ eor x6, x6, x13 //AES block 0 - round 14 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ stp x6, x7, [x2], #16 //AES block 0 - store result
+ fmov d1, x10 //CTR block 5
+
+ ld1 {v7.16b}, [x0], #16 //AES block 3 - load ciphertext
+
+ fmov v1.d[1], x9 //CTR block 5
+ rev w9, w12 //CTR block 6
+ add w12, w12, #1 //CTR block 6
+
+ eor x19, x19, x13 //AES block 1 - round 14 low
+#ifdef __AARCH64EB__
+ rev x19, x19
+#endif
+ orr x9, x11, x9, lsl #32 //CTR block 6
+
+ eor x20, x20, x14 //AES block 1 - round 14 high
+#ifdef __AARCH64EB__
+ rev x20, x20
+#endif
+ stp x19, x20, [x2], #16 //AES block 1 - store result
+
+ eor v2.16b, v6.16b, v2.16b //AES block 2 - result
+ cmp x0, x5 //check if we have <= 8 blocks
+ b.ge .L256_dec_prepretail //do prepretail
+
+.L256_dec_main_loop: //main loop start
+ mov x21, v2.d[0] //AES block 4k+2 - mov low
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+ eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+ mov x22, v2.d[1] //AES block 4k+2 - mov high
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ fmov d2, x10 //CTR block 4k+6
+
+ fmov v2.d[1], x9 //CTR block 4k+6
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+ rev w9, w12 //CTR block 4k+7
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+ mov x24, v3.d[1] //AES block 4k+3 - mov high
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+ mov x23, v3.d[0] //AES block 4k+3 - mov low
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+ mov d8, v4.d[1] //GHASH block 4k - mid
+ fmov d3, x10 //CTR block 4k+7
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+ orr x9, x11, x9, lsl #32 //CTR block 4k+7
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+ fmov v3.d[1], x9 //CTR block 4k+7
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+ eor x22, x22, x14 //AES block 4k+2 - round 14 high
+#ifdef __AARCH64EB__
+ rev x22, x22
+#endif
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+ mov d10, v17.d[1] //GHASH block 4k - mid
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+ rev64 v6.16b, v6.16b //GHASH block 4k+2
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+ eor x21, x21, x13 //AES block 4k+2 - round 14 low
+#ifdef __AARCH64EB__
+ rev x21, x21
+#endif
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+ stp x21, x22, [x2], #16 //AES block 4k+2 - store result
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+
+ pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+ rev64 v7.16b, v7.16b //GHASH block 4k+3
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+ eor x23, x23, x13 //AES block 4k+3 - round 14 low
+#ifdef __AARCH64EB__
+ rev x23, x23
+#endif
+ pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+ eor x24, x24, x14 //AES block 4k+3 - round 14 high
+#ifdef __AARCH64EB__
+ rev x24, x24
+#endif
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+ mov d4, v5.d[1] //GHASH block 4k+1 - mid
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+ eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+ add w12, w12, #1 //CTR block 4k+7
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+ mov d8, v6.d[1] //GHASH block 4k+2 - mid
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+ eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid
+
+ pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+ eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+ eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low
+
+ pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid
+ rev w9, w12 //CTR block 4k+8
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+ ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+ add w12, w12, #1 //CTR block 4k+8
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+ eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+
+ pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+ mov d6, v7.d[1] //GHASH block 4k+3 - mid
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+
+ pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+
+ pmull v4.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+ orr x9, x11, x9, lsl #32 //CTR block 4k+8
+ eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid
+
+ pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 9
+ eor v6.8b, v6.8b, v7.8b //GHASH block 4k+3 - mid
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+ eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high
+
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 10
+
+ pmull v6.1q, v6.1d, v16.1d //GHASH block 4k+3 - mid
+ movi v8.8b, #0xc2
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+ eor v11.16b, v11.16b, v4.16b //GHASH block 4k+3 - low
+
+ aese v0.16b, v29.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 11
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+ shl d8, d8, #56 //mod_constant
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+ eor v10.16b, v10.16b, v6.16b //GHASH block 4k+3 - mid
+
+ aese v0.16b, v30.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 12
+
+ pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+ eor v6.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 9
+ ld1 {v4.16b}, [x0], #16 //AES block 4k+4 - load ciphertext
+
+ aese v0.16b, v31.16b //AES block 4k+4 - round 13
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 10
+ eor v10.16b, v10.16b, v6.16b //MODULO - karatsuba tidy up
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 9
+ ld1 {v5.16b}, [x0], #16 //AES block 4k+5 - load ciphertext
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+ eor v0.16b, v4.16b, v0.16b //AES block 4k+4 - result
+
+ aese v1.16b, v29.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 11
+ stp x23, x24, [x2], #16 //AES block 4k+3 - store result
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 10
+ eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 9
+ ld1 {v6.16b}, [x0], #16 //AES block 4k+6 - load ciphertext
+
+ aese v1.16b, v30.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 12
+ ld1 {v7.16b}, [x0], #16 //AES block 4k+7 - load ciphertext
+
+ aese v2.16b, v29.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 11
+ mov x7, v0.d[1] //AES block 4k+4 - mov high
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 10
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ aese v1.16b, v31.16b //AES block 4k+5 - round 13
+ mov x6, v0.d[0] //AES block 4k+4 - mov low
+
+ aese v2.16b, v30.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 12
+ fmov d0, x10 //CTR block 4k+8
+
+ aese v3.16b, v29.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 11
+ fmov v0.d[1], x9 //CTR block 4k+8
+
+ pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+ eor v1.16b, v5.16b, v1.16b //AES block 4k+5 - result
+ rev w9, w12 //CTR block 4k+9
+
+ aese v2.16b, v31.16b //AES block 4k+6 - round 13
+ orr x9, x11, x9, lsl #32 //CTR block 4k+9
+ cmp x0, x5 //.LOOP CONTROL
+
+ add w12, w12, #1 //CTR block 4k+9
+
+ eor x6, x6, x13 //AES block 4k+4 - round 14 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ eor x7, x7, x14 //AES block 4k+4 - round 14 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ mov x20, v1.d[1] //AES block 4k+5 - mov high
+ eor v2.16b, v6.16b, v2.16b //AES block 4k+6 - result
+ eor v11.16b, v11.16b, v8.16b //MODULO - fold into low
+
+ aese v3.16b, v30.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 12
+ mov x19, v1.d[0] //AES block 4k+5 - mov low
+
+ fmov d1, x10 //CTR block 4k+9
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ fmov v1.d[1], x9 //CTR block 4k+9
+ rev w9, w12 //CTR block 4k+10
+ add w12, w12, #1 //CTR block 4k+10
+
+ aese v3.16b, v31.16b //AES block 4k+7 - round 13
+ orr x9, x11, x9, lsl #32 //CTR block 4k+10
+
+ rev64 v5.16b, v5.16b //GHASH block 4k+5
+ eor x20, x20, x14 //AES block 4k+5 - round 14 high
+#ifdef __AARCH64EB__
+ rev x20, x20
+#endif
+ stp x6, x7, [x2], #16 //AES block 4k+4 - store result
+
+ eor x19, x19, x13 //AES block 4k+5 - round 14 low
+#ifdef __AARCH64EB__
+ rev x19, x19
+#endif
+ stp x19, x20, [x2], #16 //AES block 4k+5 - store result
+
+ rev64 v4.16b, v4.16b //GHASH block 4k+4
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+ b.lt .L256_dec_main_loop
+
+
+.L256_dec_prepretail: //PREPRETAIL
+ ext v11.16b, v11.16b, v11.16b, #8 //PRE 0
+ mov x21, v2.d[0] //AES block 4k+2 - mov low
+ eor v3.16b, v7.16b, v3.16b //AES block 4k+3 - result
+
+ aese v0.16b, v18.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 0
+ mov x22, v2.d[1] //AES block 4k+2 - mov high
+
+ aese v1.16b, v18.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 0
+ fmov d2, x10 //CTR block 4k+6
+
+ fmov v2.d[1], x9 //CTR block 4k+6
+ rev w9, w12 //CTR block 4k+7
+ eor v4.16b, v4.16b, v11.16b //PRE 1
+
+ rev64 v6.16b, v6.16b //GHASH block 4k+2
+ orr x9, x11, x9, lsl #32 //CTR block 4k+7
+ mov x23, v3.d[0] //AES block 4k+3 - mov low
+
+ aese v1.16b, v19.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 1
+ mov x24, v3.d[1] //AES block 4k+3 - mov high
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH block 4k - low
+ mov d8, v4.d[1] //GHASH block 4k - mid
+ fmov d3, x10 //CTR block 4k+7
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH block 4k - high
+ fmov v3.d[1], x9 //CTR block 4k+7
+
+ aese v2.16b, v18.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 0
+ mov d10, v17.d[1] //GHASH block 4k - mid
+
+ aese v0.16b, v19.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 1
+ eor v8.8b, v8.8b, v4.8b //GHASH block 4k - mid
+
+ pmull2 v4.1q, v5.2d, v14.2d //GHASH block 4k+1 - high
+
+ aese v2.16b, v19.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 1
+ rev64 v7.16b, v7.16b //GHASH block 4k+3
+
+ aese v3.16b, v18.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 0
+
+ pmull v10.1q, v8.1d, v10.1d //GHASH block 4k - mid
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+1 - high
+
+ pmull v8.1q, v5.1d, v14.1d //GHASH block 4k+1 - low
+
+ aese v3.16b, v19.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 1
+ mov d4, v5.d[1] //GHASH block 4k+1 - mid
+
+ aese v0.16b, v20.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 2
+
+ aese v1.16b, v20.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 2
+ eor v11.16b, v11.16b, v8.16b //GHASH block 4k+1 - low
+
+ aese v2.16b, v20.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 2
+
+ aese v0.16b, v21.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 3
+ mov d8, v6.d[1] //GHASH block 4k+2 - mid
+
+ aese v3.16b, v20.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 2
+ eor v4.8b, v4.8b, v5.8b //GHASH block 4k+1 - mid
+
+ pmull v5.1q, v6.1d, v13.1d //GHASH block 4k+2 - low
+
+ aese v0.16b, v22.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 4
+
+ aese v3.16b, v21.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 3
+ eor v8.8b, v8.8b, v6.8b //GHASH block 4k+2 - mid
+
+ pmull v4.1q, v4.1d, v17.1d //GHASH block 4k+1 - mid
+
+ aese v0.16b, v23.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 5
+ eor v11.16b, v11.16b, v5.16b //GHASH block 4k+2 - low
+
+ aese v3.16b, v22.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 4
+
+ pmull2 v5.1q, v7.2d, v12.2d //GHASH block 4k+3 - high
+ eor v10.16b, v10.16b, v4.16b //GHASH block 4k+1 - mid
+
+ pmull2 v4.1q, v6.2d, v13.2d //GHASH block 4k+2 - high
+
+ aese v3.16b, v23.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 5
+ ins v8.d[1], v8.d[0] //GHASH block 4k+2 - mid
+
+ aese v2.16b, v21.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 3
+
+ aese v1.16b, v21.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 3
+ eor v9.16b, v9.16b, v4.16b //GHASH block 4k+2 - high
+
+ pmull v4.1q, v7.1d, v12.1d //GHASH block 4k+3 - low
+
+ aese v2.16b, v22.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 4
+ mov d6, v7.d[1] //GHASH block 4k+3 - mid
+
+ aese v1.16b, v22.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 4
+
+ pmull2 v8.1q, v8.2d, v16.2d //GHASH block 4k+2 - mid
+
+ aese v2.16b, v23.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 5
+ eor v6.8b, v6.8b, v7.8b //GHASH block 4k+3 - mid
+
+ aese v1.16b, v23.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 5
+
+ aese v3.16b, v24.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 6
+ eor v10.16b, v10.16b, v8.16b //GHASH block 4k+2 - mid
+
+ aese v2.16b, v24.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 6
+
+ aese v0.16b, v24.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 6
+ movi v8.8b, #0xc2
+
+ aese v1.16b, v24.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 6
+ eor v11.16b, v11.16b, v4.16b //GHASH block 4k+3 - low
+
+ pmull v6.1q, v6.1d, v16.1d //GHASH block 4k+3 - mid
+
+ aese v3.16b, v25.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 7
+ eor v9.16b, v9.16b, v5.16b //GHASH block 4k+3 - high
+
+ aese v1.16b, v25.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 7
+
+ aese v0.16b, v25.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 7
+ eor v10.16b, v10.16b, v6.16b //GHASH block 4k+3 - mid
+
+ aese v3.16b, v26.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 8
+
+ aese v2.16b, v25.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 7
+ eor v6.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ aese v1.16b, v26.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 8
+
+ aese v0.16b, v26.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 8
+ shl d8, d8, #56 //mod_constant
+
+ aese v2.16b, v26.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 8
+
+ aese v1.16b, v27.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 9
+ eor v10.16b, v10.16b, v6.16b //MODULO - karatsuba tidy up
+
+ pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+
+ aese v2.16b, v27.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 9
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ aese v3.16b, v27.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 9
+
+ aese v0.16b, v27.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 9
+ eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid
+
+ aese v2.16b, v28.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 10
+
+ aese v3.16b, v28.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 10
+
+ aese v0.16b, v28.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 10
+ eor x22, x22, x14 //AES block 4k+2 - round 14 high
+#ifdef __AARCH64EB__
+ rev x22, x22
+#endif
+ aese v1.16b, v28.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 10
+ eor x23, x23, x13 //AES block 4k+3 - round 14 low
+#ifdef __AARCH64EB__
+ rev x23, x23
+#endif
+ aese v2.16b, v29.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 11
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ aese v0.16b, v29.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 11
+ add w12, w12, #1 //CTR block 4k+7
+
+ aese v1.16b, v29.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 11
+ eor x21, x21, x13 //AES block 4k+2 - round 14 low
+#ifdef __AARCH64EB__
+ rev x21, x21
+#endif
+
+ aese v2.16b, v30.16b
+ aesmc v2.16b, v2.16b //AES block 4k+6 - round 12
+
+ pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+ eor x24, x24, x14 //AES block 4k+3 - round 14 high
+#ifdef __AARCH64EB__
+ rev x24, x24
+#endif
+
+ aese v3.16b, v29.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 11
+ stp x21, x22, [x2], #16 //AES block 4k+2 - store result
+
+ aese v1.16b, v30.16b
+ aesmc v1.16b, v1.16b //AES block 4k+5 - round 12
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ aese v0.16b, v30.16b
+ aesmc v0.16b, v0.16b //AES block 4k+4 - round 12
+ stp x23, x24, [x2], #16 //AES block 4k+3 - store result
+
+ aese v3.16b, v30.16b
+ aesmc v3.16b, v3.16b //AES block 4k+7 - round 12
+ eor v11.16b, v11.16b, v8.16b //MODULO - fold into low
+
+ aese v1.16b, v31.16b //AES block 4k+5 - round 13
+
+ aese v0.16b, v31.16b //AES block 4k+4 - round 13
+
+ aese v3.16b, v31.16b //AES block 4k+7 - round 13
+
+ aese v2.16b, v31.16b //AES block 4k+6 - round 13
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+.L256_dec_tail: //TAIL
+
+ sub x5, x4, x0 //main_end_input_ptr is number of bytes left to process
+ ld1 { v5.16b}, [x0], #16 //AES block 4k+4 - load ciphertext
+
+ eor v0.16b, v5.16b, v0.16b //AES block 4k+4 - result
+
+ mov x6, v0.d[0] //AES block 4k+4 - mov low
+
+ mov x7, v0.d[1] //AES block 4k+4 - mov high
+ ext v8.16b, v11.16b, v11.16b, #8 //prepare final partial tag
+
+ cmp x5, #48
+
+ eor x6, x6, x13 //AES block 4k+4 - round 14 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+
+ eor x7, x7, x14 //AES block 4k+4 - round 14 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+ b.gt .L256_dec_blocks_more_than_3
+
+ sub w12, w12, #1
+ mov v3.16b, v2.16b
+ movi v10.8b, #0
+
+ movi v11.8b, #0
+ cmp x5, #32
+
+ movi v9.8b, #0
+ mov v2.16b, v1.16b
+ b.gt .L256_dec_blocks_more_than_2
+
+ sub w12, w12, #1
+
+ mov v3.16b, v1.16b
+ cmp x5, #16
+ b.gt .L256_dec_blocks_more_than_1
+
+ sub w12, w12, #1
+ b .L256_dec_blocks_less_than_1
+.L256_dec_blocks_more_than_3: //blocks left > 3
+ rev64 v4.16b, v5.16b //GHASH final-3 block
+ ld1 { v5.16b}, [x0], #16 //AES final-2 block - load ciphertext
+
+ stp x6, x7, [x2], #16 //AES final-3 block - store result
+
+ mov d10, v17.d[1] //GHASH final-3 block - mid
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ eor v0.16b, v5.16b, v1.16b //AES final-2 block - result
+
+ mov d22, v4.d[1] //GHASH final-3 block - mid
+
+ mov x6, v0.d[0] //AES final-2 block - mov low
+
+ mov x7, v0.d[1] //AES final-2 block - mov high
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-3 block - mid
+
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ pmull2 v9.1q, v4.2d, v15.2d //GHASH final-3 block - high
+
+ pmull v10.1q, v22.1d, v10.1d //GHASH final-3 block - mid
+ eor x6, x6, x13 //AES final-2 block - round 14 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+
+ pmull v11.1q, v4.1d, v15.1d //GHASH final-3 block - low
+ eor x7, x7, x14 //AES final-2 block - round 14 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+.L256_dec_blocks_more_than_2: //blocks left > 2
+
+ rev64 v4.16b, v5.16b //GHASH final-2 block
+ ld1 { v5.16b}, [x0], #16 //AES final-1 block - load ciphertext
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+ stp x6, x7, [x2], #16 //AES final-2 block - store result
+
+ eor v0.16b, v5.16b, v2.16b //AES final-1 block - result
+
+ mov d22, v4.d[1] //GHASH final-2 block - mid
+
+ pmull v21.1q, v4.1d, v14.1d //GHASH final-2 block - low
+
+ pmull2 v20.1q, v4.2d, v14.2d //GHASH final-2 block - high
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-2 block - mid
+ mov x6, v0.d[0] //AES final-1 block - mov low
+
+ mov x7, v0.d[1] //AES final-1 block - mov high
+ eor v11.16b, v11.16b, v21.16b //GHASH final-2 block - low
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ pmull v22.1q, v22.1d, v17.1d //GHASH final-2 block - mid
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final-2 block - high
+ eor x6, x6, x13 //AES final-1 block - round 14 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+
+ eor v10.16b, v10.16b, v22.16b //GHASH final-2 block - mid
+ eor x7, x7, x14 //AES final-1 block - round 14 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+.L256_dec_blocks_more_than_1: //blocks left > 1
+
+ stp x6, x7, [x2], #16 //AES final-1 block - store result
+ rev64 v4.16b, v5.16b //GHASH final-1 block
+
+ ld1 { v5.16b}, [x0], #16 //AES final block - load ciphertext
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+ movi v8.8b, #0 //suppress further partial tag feed in
+
+ mov d22, v4.d[1] //GHASH final-1 block - mid
+
+ eor v0.16b, v5.16b, v3.16b //AES final block - result
+
+ pmull2 v20.1q, v4.2d, v13.2d //GHASH final-1 block - high
+
+ eor v22.8b, v22.8b, v4.8b //GHASH final-1 block - mid
+
+ pmull v21.1q, v4.1d, v13.1d //GHASH final-1 block - low
+ mov x6, v0.d[0] //AES final block - mov low
+
+ ins v22.d[1], v22.d[0] //GHASH final-1 block - mid
+
+ mov x7, v0.d[1] //AES final block - mov high
+
+ pmull2 v22.1q, v22.2d, v16.2d //GHASH final-1 block - mid
+ eor x6, x6, x13 //AES final block - round 14 low
+#ifdef __AARCH64EB__
+ rev x6, x6
+#endif
+ eor v11.16b, v11.16b, v21.16b //GHASH final-1 block - low
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final-1 block - high
+
+ eor v10.16b, v10.16b, v22.16b //GHASH final-1 block - mid
+ eor x7, x7, x14 //AES final block - round 14 high
+#ifdef __AARCH64EB__
+ rev x7, x7
+#endif
+.L256_dec_blocks_less_than_1: //blocks left <= 1
+
+ and x1, x1, #127 //bit_length %= 128
+ mvn x14, xzr //rk14_h = 0xffffffffffffffff
+
+ sub x1, x1, #128 //bit_length -= 128
+ mvn x13, xzr //rk14_l = 0xffffffffffffffff
+
+ ldp x4, x5, [x2] //load existing bytes we need to not overwrite
+ neg x1, x1 //bit_length = 128 - #bits in input (in range [1,128])
+
+ and x1, x1, #127 //bit_length %= 128
+
+ lsr x14, x14, x1 //rk14_h is mask for top 64b of last block
+ cmp x1, #64
+
+ csel x9, x13, x14, lt
+ csel x10, x14, xzr, lt
+
+ fmov d0, x9 //ctr0b is mask for last block
+ and x6, x6, x9
+
+ mov v0.d[1], x10
+ bic x4, x4, x9 //mask out low existing bytes
+
+#ifndef __AARCH64EB__
+ rev w9, w12
+#else
+ mov w9, w12
+#endif
+
+ bic x5, x5, x10 //mask out high existing bytes
+
+ orr x6, x6, x4
+
+ and x7, x7, x10
+
+ orr x7, x7, x5
+
+ and v5.16b, v5.16b, v0.16b //possibly partial last block has zeroes in highest bits
+
+ rev64 v4.16b, v5.16b //GHASH final block
+
+ eor v4.16b, v4.16b, v8.16b //feed in partial tag
+
+ pmull v21.1q, v4.1d, v12.1d //GHASH final block - low
+
+ mov d8, v4.d[1] //GHASH final block - mid
+
+ eor v8.8b, v8.8b, v4.8b //GHASH final block - mid
+
+ pmull2 v20.1q, v4.2d, v12.2d //GHASH final block - high
+
+ pmull v8.1q, v8.1d, v16.1d //GHASH final block - mid
+
+ eor v9.16b, v9.16b, v20.16b //GHASH final block - high
+
+ eor v11.16b, v11.16b, v21.16b //GHASH final block - low
+
+ eor v10.16b, v10.16b, v8.16b //GHASH final block - mid
+ movi v8.8b, #0xc2
+
+ eor v6.16b, v11.16b, v9.16b //MODULO - karatsuba tidy up
+
+ shl d8, d8, #56 //mod_constant
+
+ eor v10.16b, v10.16b, v6.16b //MODULO - karatsuba tidy up
+
+ pmull v7.1q, v9.1d, v8.1d //MODULO - top 64b align with mid
+
+ ext v9.16b, v9.16b, v9.16b, #8 //MODULO - other top alignment
+
+ eor v10.16b, v10.16b, v7.16b //MODULO - fold into mid
+
+ eor v10.16b, v10.16b, v9.16b //MODULO - fold into mid
+
+ pmull v8.1q, v10.1d, v8.1d //MODULO - mid 64b align with low
+
+ ext v10.16b, v10.16b, v10.16b, #8 //MODULO - other mid alignment
+
+ eor v11.16b, v11.16b, v8.16b //MODULO - fold into low
+
+ stp x6, x7, [x2]
+
+ str w9, [x16, #12] //store the updated counter
+
+ eor v11.16b, v11.16b, v10.16b //MODULO - fold into low
+ ext v11.16b, v11.16b, v11.16b, #8
+ rev64 v11.16b, v11.16b
+ mov x0, x15
+ st1 { v11.16b }, [x3]
+
+ ldp x21, x22, [sp, #16]
+ ldp x23, x24, [sp, #32]
+ ldp d8, d9, [sp, #48]
+ ldp d10, d11, [sp, #64]
+ ldp d12, d13, [sp, #80]
+ ldp d14, d15, [sp, #96]
+ ldp x19, x20, [sp], #112
+ ret
+
+.L256_dec_ret:
+ mov w0, #0x0
+ ret
+.size aes_gcm_dec_256_kernel,.-aes_gcm_dec_256_kernel
+.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 2
+.align 2
+#endif
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/ghashv8-armx.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/ghashv8-armx.S
new file mode 100644
index 0000000..cf2eadb
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/modes/ghashv8-armx.S
@@ -0,0 +1,552 @@
+#include "arm_arch.h"
+
+#if __ARM_MAX_ARCH__>=7
+.arch armv8-a+crypto
+.text
+.globl gcm_init_v8
+.type gcm_init_v8,%function
+.align 4
+gcm_init_v8:
+ ld1 {v17.2d},[x1] //load input H
+ movi v19.16b,#0xe1
+ shl v19.2d,v19.2d,#57 //0xc2.0
+ ext v3.16b,v17.16b,v17.16b,#8
+ ushr v18.2d,v19.2d,#63
+ dup v17.4s,v17.s[1]
+ ext v16.16b,v18.16b,v19.16b,#8 //t0=0xc2....01
+ ushr v18.2d,v3.2d,#63
+ sshr v17.4s,v17.4s,#31 //broadcast carry bit
+ and v18.16b,v18.16b,v16.16b
+ shl v3.2d,v3.2d,#1
+ ext v18.16b,v18.16b,v18.16b,#8
+ and v16.16b,v16.16b,v17.16b
+ orr v3.16b,v3.16b,v18.16b //H<<<=1
+ eor v20.16b,v3.16b,v16.16b //twisted H
+ st1 {v20.2d},[x0],#16 //store Htable[0]
+
+ //calculate H^2
+ ext v16.16b,v20.16b,v20.16b,#8 //Karatsuba pre-processing
+ pmull v0.1q,v20.1d,v20.1d
+ eor v16.16b,v16.16b,v20.16b
+ pmull2 v2.1q,v20.2d,v20.2d
+ pmull v1.1q,v16.1d,v16.1d
+
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ eor v1.16b,v1.16b,v18.16b
+ pmull v18.1q,v0.1d,v19.1d //1st phase
+
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ eor v0.16b,v1.16b,v18.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase
+ pmull v0.1q,v0.1d,v19.1d
+ eor v18.16b,v18.16b,v2.16b
+ eor v22.16b,v0.16b,v18.16b
+
+ ext v17.16b,v22.16b,v22.16b,#8 //Karatsuba pre-processing
+ eor v17.16b,v17.16b,v22.16b
+ ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed
+ st1 {v21.2d,v22.2d},[x0],#32 //store Htable[1..2]
+ //calculate H^3 and H^4
+ pmull v0.1q,v20.1d, v22.1d
+ pmull v5.1q,v22.1d,v22.1d
+ pmull2 v2.1q,v20.2d, v22.2d
+ pmull2 v7.1q,v22.2d,v22.2d
+ pmull v1.1q,v16.1d,v17.1d
+ pmull v6.1q,v17.1d,v17.1d
+
+ ext v16.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ ext v17.16b,v5.16b,v7.16b,#8
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v16.16b
+ eor v4.16b,v5.16b,v7.16b
+ eor v6.16b,v6.16b,v17.16b
+ eor v1.16b,v1.16b,v18.16b
+ pmull v18.1q,v0.1d,v19.1d //1st phase
+ eor v6.16b,v6.16b,v4.16b
+ pmull v4.1q,v5.1d,v19.1d
+
+ ins v2.d[0],v1.d[1]
+ ins v7.d[0],v6.d[1]
+ ins v1.d[1],v0.d[0]
+ ins v6.d[1],v5.d[0]
+ eor v0.16b,v1.16b,v18.16b
+ eor v5.16b,v6.16b,v4.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase
+ ext v4.16b,v5.16b,v5.16b,#8
+ pmull v0.1q,v0.1d,v19.1d
+ pmull v5.1q,v5.1d,v19.1d
+ eor v18.16b,v18.16b,v2.16b
+ eor v4.16b,v4.16b,v7.16b
+ eor v20.16b, v0.16b,v18.16b //H^3
+ eor v22.16b,v5.16b,v4.16b //H^4
+
+ ext v16.16b,v20.16b, v20.16b,#8 //Karatsuba pre-processing
+ ext v17.16b,v22.16b,v22.16b,#8
+ eor v16.16b,v16.16b,v20.16b
+ eor v17.16b,v17.16b,v22.16b
+ ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed
+ st1 {v20.2d,v21.2d,v22.2d},[x0] //store Htable[3..5]
+ ret
+.size gcm_init_v8,.-gcm_init_v8
+.globl gcm_gmult_v8
+.type gcm_gmult_v8,%function
+.align 4
+gcm_gmult_v8:
+ ld1 {v17.2d},[x0] //load Xi
+ movi v19.16b,#0xe1
+ ld1 {v20.2d,v21.2d},[x1] //load twisted H, ...
+ shl v19.2d,v19.2d,#57
+#ifndef __AARCH64EB__
+ rev64 v17.16b,v17.16b
+#endif
+ ext v3.16b,v17.16b,v17.16b,#8
+
+ pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo
+ eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing
+ pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi
+ pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi)
+
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ eor v1.16b,v1.16b,v18.16b
+ pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
+
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ eor v0.16b,v1.16b,v18.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
+ pmull v0.1q,v0.1d,v19.1d
+ eor v18.16b,v18.16b,v2.16b
+ eor v0.16b,v0.16b,v18.16b
+
+#ifndef __AARCH64EB__
+ rev64 v0.16b,v0.16b
+#endif
+ ext v0.16b,v0.16b,v0.16b,#8
+ st1 {v0.2d},[x0] //write out Xi
+
+ ret
+.size gcm_gmult_v8,.-gcm_gmult_v8
+.globl gcm_ghash_v8
+.type gcm_ghash_v8,%function
+.align 4
+gcm_ghash_v8:
+ cmp x3,#64
+ b.hs .Lgcm_ghash_v8_4x
+ ld1 {v0.2d},[x0] //load [rotated] Xi
+ //"[rotated]" means that
+ //loaded value would have
+ //to be rotated in order to
+ //make it appear as in
+ //algorithm specification
+ subs x3,x3,#32 //see if x3 is 32 or larger
+ mov x12,#16 //x12 is used as post-
+ //increment for input pointer;
+ //as loop is modulo-scheduled
+ //x12 is zeroed just in time
+ //to preclude overstepping
+ //inp[len], which means that
+ //last block[s] are actually
+ //loaded twice, but last
+ //copy is not processed
+ ld1 {v20.2d,v21.2d},[x1],#32 //load twisted H, ..., H^2
+ movi v19.16b,#0xe1
+ ld1 {v22.2d},[x1]
+ csel x12,xzr,x12,eq //is it time to zero x12?
+ ext v0.16b,v0.16b,v0.16b,#8 //rotate Xi
+ ld1 {v16.2d},[x2],#16 //load [rotated] I[0]
+ shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant
+#ifndef __AARCH64EB__
+ rev64 v16.16b,v16.16b
+ rev64 v0.16b,v0.16b
+#endif
+ ext v3.16b,v16.16b,v16.16b,#8 //rotate I[0]
+ b.lo .Lodd_tail_v8 //x3 was less than 32
+ ld1 {v17.2d},[x2],x12 //load [rotated] I[1]
+#ifndef __AARCH64EB__
+ rev64 v17.16b,v17.16b
+#endif
+ ext v7.16b,v17.16b,v17.16b,#8
+ eor v3.16b,v3.16b,v0.16b //I[i]^=Xi
+ pmull v4.1q,v20.1d,v7.1d //H·Ii+1
+ eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing
+ pmull2 v6.1q,v20.2d,v7.2d
+ b .Loop_mod2x_v8
+
+.align 4
+.Loop_mod2x_v8:
+ ext v18.16b,v3.16b,v3.16b,#8
+ subs x3,x3,#32 //is there more data?
+ pmull v0.1q,v22.1d,v3.1d //H^2.lo·Xi.lo
+ csel x12,xzr,x12,lo //is it time to zero x12?
+
+ pmull v5.1q,v21.1d,v17.1d
+ eor v18.16b,v18.16b,v3.16b //Karatsuba pre-processing
+ pmull2 v2.1q,v22.2d,v3.2d //H^2.hi·Xi.hi
+ eor v0.16b,v0.16b,v4.16b //accumulate
+ pmull2 v1.1q,v21.2d,v18.2d //(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
+ ld1 {v16.2d},[x2],x12 //load [rotated] I[i+2]
+
+ eor v2.16b,v2.16b,v6.16b
+ csel x12,xzr,x12,eq //is it time to zero x12?
+ eor v1.16b,v1.16b,v5.16b
+
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ ld1 {v17.2d},[x2],x12 //load [rotated] I[i+3]
+#ifndef __AARCH64EB__
+ rev64 v16.16b,v16.16b
+#endif
+ eor v1.16b,v1.16b,v18.16b
+ pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
+
+#ifndef __AARCH64EB__
+ rev64 v17.16b,v17.16b
+#endif
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ ext v7.16b,v17.16b,v17.16b,#8
+ ext v3.16b,v16.16b,v16.16b,#8
+ eor v0.16b,v1.16b,v18.16b
+ pmull v4.1q,v20.1d,v7.1d //H·Ii+1
+ eor v3.16b,v3.16b,v2.16b //accumulate v3.16b early
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
+ pmull v0.1q,v0.1d,v19.1d
+ eor v3.16b,v3.16b,v18.16b
+ eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing
+ eor v3.16b,v3.16b,v0.16b
+ pmull2 v6.1q,v20.2d,v7.2d
+ b.hs .Loop_mod2x_v8 //there was at least 32 more bytes
+
+ eor v2.16b,v2.16b,v18.16b
+ ext v3.16b,v16.16b,v16.16b,#8 //re-construct v3.16b
+ adds x3,x3,#32 //re-construct x3
+ eor v0.16b,v0.16b,v2.16b //re-construct v0.16b
+ b.eq .Ldone_v8 //is x3 zero?
+.Lodd_tail_v8:
+ ext v18.16b,v0.16b,v0.16b,#8
+ eor v3.16b,v3.16b,v0.16b //inp^=Xi
+ eor v17.16b,v16.16b,v18.16b //v17.16b is rotated inp^Xi
+
+ pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo
+ eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing
+ pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi
+ pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi)
+
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ eor v1.16b,v1.16b,v18.16b
+ pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
+
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ eor v0.16b,v1.16b,v18.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
+ pmull v0.1q,v0.1d,v19.1d
+ eor v18.16b,v18.16b,v2.16b
+ eor v0.16b,v0.16b,v18.16b
+
+.Ldone_v8:
+#ifndef __AARCH64EB__
+ rev64 v0.16b,v0.16b
+#endif
+ ext v0.16b,v0.16b,v0.16b,#8
+ st1 {v0.2d},[x0] //write out Xi
+
+ ret
+.size gcm_ghash_v8,.-gcm_ghash_v8
+.type gcm_ghash_v8_4x,%function
+.align 4
+gcm_ghash_v8_4x:
+.Lgcm_ghash_v8_4x:
+ ld1 {v0.2d},[x0] //load [rotated] Xi
+ ld1 {v20.2d,v21.2d,v22.2d},[x1],#48 //load twisted H, ..., H^2
+ movi v19.16b,#0xe1
+ ld1 {v26.2d,v27.2d,v28.2d},[x1] //load twisted H^3, ..., H^4
+ shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant
+
+ ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64
+#ifndef __AARCH64EB__
+ rev64 v0.16b,v0.16b
+ rev64 v5.16b,v5.16b
+ rev64 v6.16b,v6.16b
+ rev64 v7.16b,v7.16b
+ rev64 v4.16b,v4.16b
+#endif
+ ext v25.16b,v7.16b,v7.16b,#8
+ ext v24.16b,v6.16b,v6.16b,#8
+ ext v23.16b,v5.16b,v5.16b,#8
+
+ pmull v29.1q,v20.1d,v25.1d //H·Ii+3
+ eor v7.16b,v7.16b,v25.16b
+ pmull2 v31.1q,v20.2d,v25.2d
+ pmull v30.1q,v21.1d,v7.1d
+
+ pmull v16.1q,v22.1d,v24.1d //H^2·Ii+2
+ eor v6.16b,v6.16b,v24.16b
+ pmull2 v24.1q,v22.2d,v24.2d
+ pmull2 v6.1q,v21.2d,v6.2d
+
+ eor v29.16b,v29.16b,v16.16b
+ eor v31.16b,v31.16b,v24.16b
+ eor v30.16b,v30.16b,v6.16b
+
+ pmull v7.1q,v26.1d,v23.1d //H^3·Ii+1
+ eor v5.16b,v5.16b,v23.16b
+ pmull2 v23.1q,v26.2d,v23.2d
+ pmull v5.1q,v27.1d,v5.1d
+
+ eor v29.16b,v29.16b,v7.16b
+ eor v31.16b,v31.16b,v23.16b
+ eor v30.16b,v30.16b,v5.16b
+
+ subs x3,x3,#128
+ b.lo .Ltail4x
+
+ b .Loop4x
+
+.align 4
+.Loop4x:
+ eor v16.16b,v4.16b,v0.16b
+ ld1 {v4.2d,v5.2d,v6.2d,v7.2d},[x2],#64
+ ext v3.16b,v16.16b,v16.16b,#8
+#ifndef __AARCH64EB__
+ rev64 v5.16b,v5.16b
+ rev64 v6.16b,v6.16b
+ rev64 v7.16b,v7.16b
+ rev64 v4.16b,v4.16b
+#endif
+
+ pmull v0.1q,v28.1d,v3.1d //H^4·(Xi+Ii)
+ eor v16.16b,v16.16b,v3.16b
+ pmull2 v2.1q,v28.2d,v3.2d
+ ext v25.16b,v7.16b,v7.16b,#8
+ pmull2 v1.1q,v27.2d,v16.2d
+
+ eor v0.16b,v0.16b,v29.16b
+ eor v2.16b,v2.16b,v31.16b
+ ext v24.16b,v6.16b,v6.16b,#8
+ eor v1.16b,v1.16b,v30.16b
+ ext v23.16b,v5.16b,v5.16b,#8
+
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ pmull v29.1q,v20.1d,v25.1d //H·Ii+3
+ eor v7.16b,v7.16b,v25.16b
+ eor v1.16b,v1.16b,v17.16b
+ pmull2 v31.1q,v20.2d,v25.2d
+ eor v1.16b,v1.16b,v18.16b
+ pmull v30.1q,v21.1d,v7.1d
+
+ pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ pmull v16.1q,v22.1d,v24.1d //H^2·Ii+2
+ eor v6.16b,v6.16b,v24.16b
+ pmull2 v24.1q,v22.2d,v24.2d
+ eor v0.16b,v1.16b,v18.16b
+ pmull2 v6.1q,v21.2d,v6.2d
+
+ eor v29.16b,v29.16b,v16.16b
+ eor v31.16b,v31.16b,v24.16b
+ eor v30.16b,v30.16b,v6.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
+ pmull v0.1q,v0.1d,v19.1d
+ pmull v7.1q,v26.1d,v23.1d //H^3·Ii+1
+ eor v5.16b,v5.16b,v23.16b
+ eor v18.16b,v18.16b,v2.16b
+ pmull2 v23.1q,v26.2d,v23.2d
+ pmull v5.1q,v27.1d,v5.1d
+
+ eor v0.16b,v0.16b,v18.16b
+ eor v29.16b,v29.16b,v7.16b
+ eor v31.16b,v31.16b,v23.16b
+ ext v0.16b,v0.16b,v0.16b,#8
+ eor v30.16b,v30.16b,v5.16b
+
+ subs x3,x3,#64
+ b.hs .Loop4x
+
+.Ltail4x:
+ eor v16.16b,v4.16b,v0.16b
+ ext v3.16b,v16.16b,v16.16b,#8
+
+ pmull v0.1q,v28.1d,v3.1d //H^4·(Xi+Ii)
+ eor v16.16b,v16.16b,v3.16b
+ pmull2 v2.1q,v28.2d,v3.2d
+ pmull2 v1.1q,v27.2d,v16.2d
+
+ eor v0.16b,v0.16b,v29.16b
+ eor v2.16b,v2.16b,v31.16b
+ eor v1.16b,v1.16b,v30.16b
+
+ adds x3,x3,#64
+ b.eq .Ldone4x
+
+ cmp x3,#32
+ b.lo .Lone
+ b.eq .Ltwo
+.Lthree:
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ ld1 {v4.2d,v5.2d,v6.2d},[x2]
+ eor v1.16b,v1.16b,v18.16b
+#ifndef __AARCH64EB__
+ rev64 v5.16b,v5.16b
+ rev64 v6.16b,v6.16b
+ rev64 v4.16b,v4.16b
+#endif
+
+ pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ ext v24.16b,v6.16b,v6.16b,#8
+ ext v23.16b,v5.16b,v5.16b,#8
+ eor v0.16b,v1.16b,v18.16b
+
+ pmull v29.1q,v20.1d,v24.1d //H·Ii+2
+ eor v6.16b,v6.16b,v24.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
+ pmull v0.1q,v0.1d,v19.1d
+ eor v18.16b,v18.16b,v2.16b
+ pmull2 v31.1q,v20.2d,v24.2d
+ pmull v30.1q,v21.1d,v6.1d
+ eor v0.16b,v0.16b,v18.16b
+ pmull v7.1q,v22.1d,v23.1d //H^2·Ii+1
+ eor v5.16b,v5.16b,v23.16b
+ ext v0.16b,v0.16b,v0.16b,#8
+
+ pmull2 v23.1q,v22.2d,v23.2d
+ eor v16.16b,v4.16b,v0.16b
+ pmull2 v5.1q,v21.2d,v5.2d
+ ext v3.16b,v16.16b,v16.16b,#8
+
+ eor v29.16b,v29.16b,v7.16b
+ eor v31.16b,v31.16b,v23.16b
+ eor v30.16b,v30.16b,v5.16b
+
+ pmull v0.1q,v26.1d,v3.1d //H^3·(Xi+Ii)
+ eor v16.16b,v16.16b,v3.16b
+ pmull2 v2.1q,v26.2d,v3.2d
+ pmull v1.1q,v27.1d,v16.1d
+
+ eor v0.16b,v0.16b,v29.16b
+ eor v2.16b,v2.16b,v31.16b
+ eor v1.16b,v1.16b,v30.16b
+ b .Ldone4x
+
+.align 4
+.Ltwo:
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ ld1 {v4.2d,v5.2d},[x2]
+ eor v1.16b,v1.16b,v18.16b
+#ifndef __AARCH64EB__
+ rev64 v5.16b,v5.16b
+ rev64 v4.16b,v4.16b
+#endif
+
+ pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ ext v23.16b,v5.16b,v5.16b,#8
+ eor v0.16b,v1.16b,v18.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
+ pmull v0.1q,v0.1d,v19.1d
+ eor v18.16b,v18.16b,v2.16b
+ eor v0.16b,v0.16b,v18.16b
+ ext v0.16b,v0.16b,v0.16b,#8
+
+ pmull v29.1q,v20.1d,v23.1d //H·Ii+1
+ eor v5.16b,v5.16b,v23.16b
+
+ eor v16.16b,v4.16b,v0.16b
+ ext v3.16b,v16.16b,v16.16b,#8
+
+ pmull2 v31.1q,v20.2d,v23.2d
+ pmull v30.1q,v21.1d,v5.1d
+
+ pmull v0.1q,v22.1d,v3.1d //H^2·(Xi+Ii)
+ eor v16.16b,v16.16b,v3.16b
+ pmull2 v2.1q,v22.2d,v3.2d
+ pmull2 v1.1q,v21.2d,v16.2d
+
+ eor v0.16b,v0.16b,v29.16b
+ eor v2.16b,v2.16b,v31.16b
+ eor v1.16b,v1.16b,v30.16b
+ b .Ldone4x
+
+.align 4
+.Lone:
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ ld1 {v4.2d},[x2]
+ eor v1.16b,v1.16b,v18.16b
+#ifndef __AARCH64EB__
+ rev64 v4.16b,v4.16b
+#endif
+
+ pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ eor v0.16b,v1.16b,v18.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
+ pmull v0.1q,v0.1d,v19.1d
+ eor v18.16b,v18.16b,v2.16b
+ eor v0.16b,v0.16b,v18.16b
+ ext v0.16b,v0.16b,v0.16b,#8
+
+ eor v16.16b,v4.16b,v0.16b
+ ext v3.16b,v16.16b,v16.16b,#8
+
+ pmull v0.1q,v20.1d,v3.1d
+ eor v16.16b,v16.16b,v3.16b
+ pmull2 v2.1q,v20.2d,v3.2d
+ pmull v1.1q,v21.1d,v16.1d
+
+.Ldone4x:
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ eor v1.16b,v1.16b,v18.16b
+
+ pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ eor v0.16b,v1.16b,v18.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
+ pmull v0.1q,v0.1d,v19.1d
+ eor v18.16b,v18.16b,v2.16b
+ eor v0.16b,v0.16b,v18.16b
+ ext v0.16b,v0.16b,v0.16b,#8
+
+#ifndef __AARCH64EB__
+ rev64 v0.16b,v0.16b
+#endif
+ st1 {v0.2d},[x0] //write out Xi
+
+ ret
+.size gcm_ghash_v8_4x,.-gcm_ghash_v8_4x
+.byte 71,72,65,83,72,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 2
+.align 2
+#endif
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/keccak1600-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/keccak1600-armv8.S
new file mode 100644
index 0000000..67e553f
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/keccak1600-armv8.S
@@ -0,0 +1,1009 @@
+.text
+
+.align 8 // strategic alignment and padding that allows to use
+ // address value as loop termination condition...
+.quad 0,0,0,0,0,0,0,0
+.type iotas,%object
+iotas:
+.quad 0x0000000000000001
+.quad 0x0000000000008082
+.quad 0x800000000000808a
+.quad 0x8000000080008000
+.quad 0x000000000000808b
+.quad 0x0000000080000001
+.quad 0x8000000080008081
+.quad 0x8000000000008009
+.quad 0x000000000000008a
+.quad 0x0000000000000088
+.quad 0x0000000080008009
+.quad 0x000000008000000a
+.quad 0x000000008000808b
+.quad 0x800000000000008b
+.quad 0x8000000000008089
+.quad 0x8000000000008003
+.quad 0x8000000000008002
+.quad 0x8000000000000080
+.quad 0x000000000000800a
+.quad 0x800000008000000a
+.quad 0x8000000080008081
+.quad 0x8000000000008080
+.quad 0x0000000080000001
+.quad 0x8000000080008008
+.size iotas,.-iotas
+.type KeccakF1600_int,%function
+.align 5
+KeccakF1600_int:
+ adr x28,iotas
+.inst 0xd503233f // paciasp
+ stp x28,x30,[sp,#16] // 32 bytes on top are mine
+ b .Loop
+.align 4
+.Loop:
+ ////////////////////////////////////////// Theta
+ eor x26,x0,x5
+ stp x4,x9,[sp,#0] // offload pair...
+ eor x27,x1,x6
+ eor x28,x2,x7
+ eor x30,x3,x8
+ eor x4,x4,x9
+ eor x26,x26,x10
+ eor x27,x27,x11
+ eor x28,x28,x12
+ eor x30,x30,x13
+ eor x4,x4,x14
+ eor x26,x26,x15
+ eor x27,x27,x16
+ eor x28,x28,x17
+ eor x30,x30,x25
+ eor x4,x4,x19
+ eor x26,x26,x20
+ eor x28,x28,x22
+ eor x27,x27,x21
+ eor x30,x30,x23
+ eor x4,x4,x24
+
+ eor x9,x26,x28,ror#63
+
+ eor x1,x1,x9
+ eor x6,x6,x9
+ eor x11,x11,x9
+ eor x16,x16,x9
+ eor x21,x21,x9
+
+ eor x9,x27,x30,ror#63
+ eor x28,x28,x4,ror#63
+ eor x30,x30,x26,ror#63
+ eor x4,x4,x27,ror#63
+
+ eor x27, x2,x9 // mov x27,x2
+ eor x7,x7,x9
+ eor x12,x12,x9
+ eor x17,x17,x9
+ eor x22,x22,x9
+
+ eor x0,x0,x4
+ eor x5,x5,x4
+ eor x10,x10,x4
+ eor x15,x15,x4
+ eor x20,x20,x4
+ ldp x4,x9,[sp,#0] // re-load offloaded data
+ eor x26, x3,x28 // mov x26,x3
+ eor x8,x8,x28
+ eor x13,x13,x28
+ eor x25,x25,x28
+ eor x23,x23,x28
+
+ eor x28, x4,x30 // mov x28,x4
+ eor x9,x9,x30
+ eor x14,x14,x30
+ eor x19,x19,x30
+ eor x24,x24,x30
+
+ ////////////////////////////////////////// Rho+Pi
+ mov x30,x1
+ ror x1,x6,#64-44
+ //mov x27,x2
+ ror x2,x12,#64-43
+ //mov x26,x3
+ ror x3,x25,#64-21
+ //mov x28,x4
+ ror x4,x24,#64-14
+
+ ror x6,x9,#64-20
+ ror x12,x13,#64-25
+ ror x25,x17,#64-15
+ ror x24,x21,#64-2
+
+ ror x9,x22,#64-61
+ ror x13,x19,#64-8
+ ror x17,x11,#64-10
+ ror x21,x8,#64-55
+
+ ror x22,x14,#64-39
+ ror x19,x23,#64-56
+ ror x11,x7,#64-6
+ ror x8,x16,#64-45
+
+ ror x14,x20,#64-18
+ ror x23,x15,#64-41
+ ror x7,x10,#64-3
+ ror x16,x5,#64-36
+
+ ror x5,x26,#64-28
+ ror x10,x30,#64-1
+ ror x15,x28,#64-27
+ ror x20,x27,#64-62
+
+ ////////////////////////////////////////// Chi+Iota
+ bic x26,x2,x1
+ bic x27,x3,x2
+ bic x28,x0,x4
+ bic x30,x1,x0
+ eor x0,x0,x26
+ bic x26,x4,x3
+ eor x1,x1,x27
+ ldr x27,[sp,#16]
+ eor x3,x3,x28
+ eor x4,x4,x30
+ eor x2,x2,x26
+ ldr x30,[x27],#8 // Iota[i++]
+
+ bic x26,x7,x6
+ tst x27,#255 // are we done?
+ str x27,[sp,#16]
+ bic x27,x8,x7
+ bic x28,x5,x9
+ eor x0,x0,x30 // A[0][0] ^= Iota
+ bic x30,x6,x5
+ eor x5,x5,x26
+ bic x26,x9,x8
+ eor x6,x6,x27
+ eor x8,x8,x28
+ eor x9,x9,x30
+ eor x7,x7,x26
+
+ bic x26,x12,x11
+ bic x27,x13,x12
+ bic x28,x10,x14
+ bic x30,x11,x10
+ eor x10,x10,x26
+ bic x26,x14,x13
+ eor x11,x11,x27
+ eor x13,x13,x28
+ eor x14,x14,x30
+ eor x12,x12,x26
+
+ bic x26,x17,x16
+ bic x27,x25,x17
+ bic x28,x15,x19
+ bic x30,x16,x15
+ eor x15,x15,x26
+ bic x26,x19,x25
+ eor x16,x16,x27
+ eor x25,x25,x28
+ eor x19,x19,x30
+ eor x17,x17,x26
+
+ bic x26,x22,x21
+ bic x27,x23,x22
+ bic x28,x20,x24
+ bic x30,x21,x20
+ eor x20,x20,x26
+ bic x26,x24,x23
+ eor x21,x21,x27
+ eor x23,x23,x28
+ eor x24,x24,x30
+ eor x22,x22,x26
+
+ bne .Loop
+
+ ldr x30,[sp,#24]
+.inst 0xd50323bf // autiasp
+ ret
+.size KeccakF1600_int,.-KeccakF1600_int
+
+.type KeccakF1600,%function
+.align 5
+KeccakF1600:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ sub sp,sp,#48
+
+ str x0,[sp,#32] // offload argument
+ mov x26,x0
+ ldp x0,x1,[x0,#16*0]
+ ldp x2,x3,[x26,#16*1]
+ ldp x4,x5,[x26,#16*2]
+ ldp x6,x7,[x26,#16*3]
+ ldp x8,x9,[x26,#16*4]
+ ldp x10,x11,[x26,#16*5]
+ ldp x12,x13,[x26,#16*6]
+ ldp x14,x15,[x26,#16*7]
+ ldp x16,x17,[x26,#16*8]
+ ldp x25,x19,[x26,#16*9]
+ ldp x20,x21,[x26,#16*10]
+ ldp x22,x23,[x26,#16*11]
+ ldr x24,[x26,#16*12]
+
+ bl KeccakF1600_int
+
+ ldr x26,[sp,#32]
+ stp x0,x1,[x26,#16*0]
+ stp x2,x3,[x26,#16*1]
+ stp x4,x5,[x26,#16*2]
+ stp x6,x7,[x26,#16*3]
+ stp x8,x9,[x26,#16*4]
+ stp x10,x11,[x26,#16*5]
+ stp x12,x13,[x26,#16*6]
+ stp x14,x15,[x26,#16*7]
+ stp x16,x17,[x26,#16*8]
+ stp x25,x19,[x26,#16*9]
+ stp x20,x21,[x26,#16*10]
+ stp x22,x23,[x26,#16*11]
+ str x24,[x26,#16*12]
+
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#48
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#128
+.inst 0xd50323bf // autiasp
+ ret
+.size KeccakF1600,.-KeccakF1600
+
+.globl SHA3_absorb
+.type SHA3_absorb,%function
+.align 5
+SHA3_absorb:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ sub sp,sp,#64
+
+ stp x0,x1,[sp,#32] // offload arguments
+ stp x2,x3,[sp,#48]
+
+ mov x26,x0 // uint64_t A[5][5]
+ mov x27,x1 // const void *inp
+ mov x28,x2 // size_t len
+ mov x30,x3 // size_t bsz
+ ldp x0,x1,[x26,#16*0]
+ ldp x2,x3,[x26,#16*1]
+ ldp x4,x5,[x26,#16*2]
+ ldp x6,x7,[x26,#16*3]
+ ldp x8,x9,[x26,#16*4]
+ ldp x10,x11,[x26,#16*5]
+ ldp x12,x13,[x26,#16*6]
+ ldp x14,x15,[x26,#16*7]
+ ldp x16,x17,[x26,#16*8]
+ ldp x25,x19,[x26,#16*9]
+ ldp x20,x21,[x26,#16*10]
+ ldp x22,x23,[x26,#16*11]
+ ldr x24,[x26,#16*12]
+ b .Loop_absorb
+
+.align 4
+.Loop_absorb:
+ subs x26,x28,x30 // len - bsz
+ blo .Labsorbed
+
+ str x26,[sp,#48] // save len - bsz
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x0,x0,x26
+ cmp x30,#8*(0+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x1,x1,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x2,x2,x26
+ cmp x30,#8*(2+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x3,x3,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x4,x4,x26
+ cmp x30,#8*(4+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x5,x5,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x6,x6,x26
+ cmp x30,#8*(6+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x7,x7,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x8,x8,x26
+ cmp x30,#8*(8+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x9,x9,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x10,x10,x26
+ cmp x30,#8*(10+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x11,x11,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x12,x12,x26
+ cmp x30,#8*(12+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x13,x13,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x14,x14,x26
+ cmp x30,#8*(14+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x15,x15,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x16,x16,x26
+ cmp x30,#8*(16+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x17,x17,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x25,x25,x26
+ cmp x30,#8*(18+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x19,x19,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x20,x20,x26
+ cmp x30,#8*(20+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x21,x21,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x22,x22,x26
+ cmp x30,#8*(22+2)
+ blo .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x23,x23,x26
+ beq .Lprocess_block
+ ldr x26,[x27],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev x26,x26
+#endif
+ eor x24,x24,x26
+
+.Lprocess_block:
+ str x27,[sp,#40] // save inp
+
+ bl KeccakF1600_int
+
+ ldr x27,[sp,#40] // restore arguments
+ ldp x28,x30,[sp,#48]
+ b .Loop_absorb
+
+.align 4
+.Labsorbed:
+ ldr x27,[sp,#32]
+ stp x0,x1,[x27,#16*0]
+ stp x2,x3,[x27,#16*1]
+ stp x4,x5,[x27,#16*2]
+ stp x6,x7,[x27,#16*3]
+ stp x8,x9,[x27,#16*4]
+ stp x10,x11,[x27,#16*5]
+ stp x12,x13,[x27,#16*6]
+ stp x14,x15,[x27,#16*7]
+ stp x16,x17,[x27,#16*8]
+ stp x25,x19,[x27,#16*9]
+ stp x20,x21,[x27,#16*10]
+ stp x22,x23,[x27,#16*11]
+ str x24,[x27,#16*12]
+
+ mov x0,x28 // return value
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#64
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#128
+.inst 0xd50323bf // autiasp
+ ret
+.size SHA3_absorb,.-SHA3_absorb
+.globl SHA3_squeeze
+.type SHA3_squeeze,%function
+.align 5
+SHA3_squeeze:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-48]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+
+ mov x19,x0 // put aside arguments
+ mov x20,x1
+ mov x21,x2
+ mov x22,x3
+
+.Loop_squeeze:
+ ldr x4,[x0],#8
+ cmp x21,#8
+ blo .Lsqueeze_tail
+#ifdef __AARCH64EB__
+ rev x4,x4
+#endif
+ str x4,[x20],#8
+ subs x21,x21,#8
+ beq .Lsqueeze_done
+
+ subs x3,x3,#8
+ bhi .Loop_squeeze
+
+ mov x0,x19
+ bl KeccakF1600
+ mov x0,x19
+ mov x3,x22
+ b .Loop_squeeze
+
+.align 4
+.Lsqueeze_tail:
+ strb w4,[x20],#1
+ lsr x4,x4,#8
+ subs x21,x21,#1
+ beq .Lsqueeze_done
+ strb w4,[x20],#1
+ lsr x4,x4,#8
+ subs x21,x21,#1
+ beq .Lsqueeze_done
+ strb w4,[x20],#1
+ lsr x4,x4,#8
+ subs x21,x21,#1
+ beq .Lsqueeze_done
+ strb w4,[x20],#1
+ lsr x4,x4,#8
+ subs x21,x21,#1
+ beq .Lsqueeze_done
+ strb w4,[x20],#1
+ lsr x4,x4,#8
+ subs x21,x21,#1
+ beq .Lsqueeze_done
+ strb w4,[x20],#1
+ lsr x4,x4,#8
+ subs x21,x21,#1
+ beq .Lsqueeze_done
+ strb w4,[x20],#1
+
+.Lsqueeze_done:
+ ldp x19,x20,[sp,#16]
+ ldp x21,x22,[sp,#32]
+ ldp x29,x30,[sp],#48
+.inst 0xd50323bf // autiasp
+ ret
+.size SHA3_squeeze,.-SHA3_squeeze
+.type KeccakF1600_ce,%function
+.align 5
+KeccakF1600_ce:
+ mov x9,#24
+ adr x10,iotas
+ b .Loop_ce
+.align 4
+.Loop_ce:
+ ////////////////////////////////////////////////// Theta
+.inst 0xce0f2a99 //eor3 v25.16b,v20.16b,v15.16b,v10.16b
+.inst 0xce102eba //eor3 v26.16b,v21.16b,v16.16b,v11.16b
+.inst 0xce1132db //eor3 v27.16b,v22.16b,v17.16b,v12.16b
+.inst 0xce1236fc //eor3 v28.16b,v23.16b,v18.16b,v13.16b
+.inst 0xce133b1d //eor3 v29.16b,v24.16b,v19.16b,v14.16b
+.inst 0xce050339 //eor3 v25.16b,v25.16b, v5.16b,v0.16b
+.inst 0xce06075a //eor3 v26.16b,v26.16b, v6.16b,v1.16b
+.inst 0xce070b7b //eor3 v27.16b,v27.16b, v7.16b,v2.16b
+.inst 0xce080f9c //eor3 v28.16b,v28.16b, v8.16b,v3.16b
+.inst 0xce0913bd //eor3 v29.16b,v29.16b, v9.16b,v4.16b
+
+.inst 0xce7b8f3e //rax1 v30.16b,v25.16b,v27.16b // D[1]
+.inst 0xce7c8f5f //rax1 v31.16b,v26.16b,v28.16b // D[2]
+.inst 0xce7d8f7b //rax1 v27.16b,v27.16b,v29.16b // D[3]
+.inst 0xce798f9c //rax1 v28.16b,v28.16b,v25.16b // D[4]
+.inst 0xce7a8fbd //rax1 v29.16b,v29.16b,v26.16b // D[0]
+
+ ////////////////////////////////////////////////// Theta+Rho+Pi
+.inst 0xce9efc39 //xar v25.16b, v1.16b,v30.16b,#64-1 // C[0]=A[2][0]
+
+.inst 0xce9e50c1 //xar v1.16b,v6.16b,v30.16b,#64-44
+.inst 0xce9cb126 //xar v6.16b,v9.16b,v28.16b,#64-20
+.inst 0xce9f0ec9 //xar v9.16b,v22.16b,v31.16b,#64-61
+.inst 0xce9c65d6 //xar v22.16b,v14.16b,v28.16b,#64-39
+.inst 0xce9dba8e //xar v14.16b,v20.16b,v29.16b,#64-18
+
+.inst 0xce9f085a //xar v26.16b, v2.16b,v31.16b,#64-62 // C[1]=A[4][0]
+
+.inst 0xce9f5582 //xar v2.16b,v12.16b,v31.16b,#64-43
+.inst 0xce9b9dac //xar v12.16b,v13.16b,v27.16b,#64-25
+.inst 0xce9ce26d //xar v13.16b,v19.16b,v28.16b,#64-8
+.inst 0xce9b22f3 //xar v19.16b,v23.16b,v27.16b,#64-56
+.inst 0xce9d5df7 //xar v23.16b,v15.16b,v29.16b,#64-41
+
+.inst 0xce9c948f //xar v15.16b,v4.16b,v28.16b,#64-27
+
+.inst 0xce9ccb1c //xar v28.16b, v24.16b,v28.16b,#64-14 // D[4]=A[0][4]
+.inst 0xce9efab8 //xar v24.16b,v21.16b,v30.16b,#64-2
+.inst 0xce9b2508 //xar v8.16b,v8.16b,v27.16b,#64-55 // A[1][3]=A[4][1]
+.inst 0xce9e4e04 //xar v4.16b,v16.16b,v30.16b,#64-45 // A[0][4]=A[1][3]
+.inst 0xce9d70b0 //xar v16.16b,v5.16b,v29.16b,#64-36
+
+.inst 0xce9b9065 //xar v5.16b,v3.16b,v27.16b,#64-28
+
+ eor v0.16b,v0.16b,v29.16b
+
+.inst 0xce9bae5b //xar v27.16b, v18.16b,v27.16b,#64-21 // D[3]=A[0][3]
+.inst 0xce9fc623 //xar v3.16b,v17.16b,v31.16b,#64-15 // A[0][3]=A[3][3]
+.inst 0xce9ed97e //xar v30.16b, v11.16b,v30.16b,#64-10 // D[1]=A[3][2]
+.inst 0xce9fe8ff //xar v31.16b, v7.16b,v31.16b,#64-6 // D[2]=A[2][1]
+.inst 0xce9df55d //xar v29.16b, v10.16b,v29.16b,#64-3 // D[0]=A[1][2]
+
+ ////////////////////////////////////////////////// Chi+Iota
+.inst 0xce362354 //bcax v20.16b,v26.16b, v22.16b,v8.16b // A[1][3]=A[4][1]
+.inst 0xce375915 //bcax v21.16b,v8.16b,v23.16b,v22.16b // A[1][3]=A[4][1]
+.inst 0xce385ed6 //bcax v22.16b,v22.16b,v24.16b,v23.16b
+.inst 0xce3a62f7 //bcax v23.16b,v23.16b,v26.16b, v24.16b
+.inst 0xce286b18 //bcax v24.16b,v24.16b,v8.16b,v26.16b // A[1][3]=A[4][1]
+
+ ld1r {v26.2d},[x10],#8
+
+.inst 0xce330fd1 //bcax v17.16b,v30.16b, v19.16b,v3.16b // A[0][3]=A[3][3]
+.inst 0xce2f4c72 //bcax v18.16b,v3.16b,v15.16b,v19.16b // A[0][3]=A[3][3]
+.inst 0xce303e73 //bcax v19.16b,v19.16b,v16.16b,v15.16b
+.inst 0xce3e41ef //bcax v15.16b,v15.16b,v30.16b, v16.16b
+.inst 0xce237a10 //bcax v16.16b,v16.16b,v3.16b,v30.16b // A[0][3]=A[3][3]
+
+.inst 0xce2c7f2a //bcax v10.16b,v25.16b, v12.16b,v31.16b
+.inst 0xce2d33eb //bcax v11.16b,v31.16b, v13.16b,v12.16b
+.inst 0xce2e358c //bcax v12.16b,v12.16b,v14.16b,v13.16b
+.inst 0xce3939ad //bcax v13.16b,v13.16b,v25.16b, v14.16b
+.inst 0xce3f65ce //bcax v14.16b,v14.16b,v31.16b, v25.16b
+
+.inst 0xce2913a7 //bcax v7.16b,v29.16b, v9.16b,v4.16b // A[0][4]=A[1][3]
+.inst 0xce252488 //bcax v8.16b,v4.16b,v5.16b,v9.16b // A[0][4]=A[1][3]
+.inst 0xce261529 //bcax v9.16b,v9.16b,v6.16b,v5.16b
+.inst 0xce3d18a5 //bcax v5.16b,v5.16b,v29.16b, v6.16b
+.inst 0xce2474c6 //bcax v6.16b,v6.16b,v4.16b,v29.16b // A[0][4]=A[1][3]
+
+.inst 0xce207363 //bcax v3.16b,v27.16b, v0.16b,v28.16b
+.inst 0xce210384 //bcax v4.16b,v28.16b, v1.16b,v0.16b
+.inst 0xce220400 //bcax v0.16b,v0.16b,v2.16b,v1.16b
+.inst 0xce3b0821 //bcax v1.16b,v1.16b,v27.16b, v2.16b
+.inst 0xce3c6c42 //bcax v2.16b,v2.16b,v28.16b, v27.16b
+
+ eor v0.16b,v0.16b,v26.16b
+
+ subs x9,x9,#1
+ bne .Loop_ce
+
+ ret
+.size KeccakF1600_ce,.-KeccakF1600_ce
+
+.type KeccakF1600_cext,%function
+.align 5
+KeccakF1600_cext:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-80]!
+ add x29,sp,#0
+ stp d8,d9,[sp,#16] // per ABI requirement
+ stp d10,d11,[sp,#32]
+ stp d12,d13,[sp,#48]
+ stp d14,d15,[sp,#64]
+ ldp d0,d1,[x0,#8*0]
+ ldp d2,d3,[x0,#8*2]
+ ldp d4,d5,[x0,#8*4]
+ ldp d6,d7,[x0,#8*6]
+ ldp d8,d9,[x0,#8*8]
+ ldp d10,d11,[x0,#8*10]
+ ldp d12,d13,[x0,#8*12]
+ ldp d14,d15,[x0,#8*14]
+ ldp d16,d17,[x0,#8*16]
+ ldp d18,d19,[x0,#8*18]
+ ldp d20,d21,[x0,#8*20]
+ ldp d22,d23,[x0,#8*22]
+ ldr d24,[x0,#8*24]
+ bl KeccakF1600_ce
+ ldr x30,[sp,#8]
+ stp d0,d1,[x0,#8*0]
+ stp d2,d3,[x0,#8*2]
+ stp d4,d5,[x0,#8*4]
+ stp d6,d7,[x0,#8*6]
+ stp d8,d9,[x0,#8*8]
+ stp d10,d11,[x0,#8*10]
+ stp d12,d13,[x0,#8*12]
+ stp d14,d15,[x0,#8*14]
+ stp d16,d17,[x0,#8*16]
+ stp d18,d19,[x0,#8*18]
+ stp d20,d21,[x0,#8*20]
+ stp d22,d23,[x0,#8*22]
+ str d24,[x0,#8*24]
+
+ ldp d8,d9,[sp,#16]
+ ldp d10,d11,[sp,#32]
+ ldp d12,d13,[sp,#48]
+ ldp d14,d15,[sp,#64]
+ ldr x29,[sp],#80
+.inst 0xd50323bf // autiasp
+ ret
+.size KeccakF1600_cext,.-KeccakF1600_cext
+.globl SHA3_absorb_cext
+.type SHA3_absorb_cext,%function
+.align 5
+SHA3_absorb_cext:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-80]!
+ add x29,sp,#0
+ stp d8,d9,[sp,#16] // per ABI requirement
+ stp d10,d11,[sp,#32]
+ stp d12,d13,[sp,#48]
+ stp d14,d15,[sp,#64]
+ ldp d0,d1,[x0,#8*0]
+ ldp d2,d3,[x0,#8*2]
+ ldp d4,d5,[x0,#8*4]
+ ldp d6,d7,[x0,#8*6]
+ ldp d8,d9,[x0,#8*8]
+ ldp d10,d11,[x0,#8*10]
+ ldp d12,d13,[x0,#8*12]
+ ldp d14,d15,[x0,#8*14]
+ ldp d16,d17,[x0,#8*16]
+ ldp d18,d19,[x0,#8*18]
+ ldp d20,d21,[x0,#8*20]
+ ldp d22,d23,[x0,#8*22]
+ ldr d24,[x0,#8*24]
+ b .Loop_absorb_ce
+
+.align 4
+.Loop_absorb_ce:
+ subs x2,x2,x3 // len - bsz
+ blo .Labsorbed_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v0.16b,v0.16b,v31.16b
+ cmp x3,#8*(0+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v1.16b,v1.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v2.16b,v2.16b,v31.16b
+ cmp x3,#8*(2+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v3.16b,v3.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v4.16b,v4.16b,v31.16b
+ cmp x3,#8*(4+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v5.16b,v5.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v6.16b,v6.16b,v31.16b
+ cmp x3,#8*(6+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v7.16b,v7.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v8.16b,v8.16b,v31.16b
+ cmp x3,#8*(8+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v9.16b,v9.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v10.16b,v10.16b,v31.16b
+ cmp x3,#8*(10+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v11.16b,v11.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v12.16b,v12.16b,v31.16b
+ cmp x3,#8*(12+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v13.16b,v13.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v14.16b,v14.16b,v31.16b
+ cmp x3,#8*(14+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v15.16b,v15.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v16.16b,v16.16b,v31.16b
+ cmp x3,#8*(16+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v17.16b,v17.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v18.16b,v18.16b,v31.16b
+ cmp x3,#8*(18+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v19.16b,v19.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v20.16b,v20.16b,v31.16b
+ cmp x3,#8*(20+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v21.16b,v21.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v22.16b,v22.16b,v31.16b
+ cmp x3,#8*(22+2)
+ blo .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v23.16b,v23.16b,v31.16b
+ beq .Lprocess_block_ce
+ ldr d31,[x1],#8 // *inp++
+#ifdef __AARCH64EB__
+ rev64 v31.16b,v31.16b
+#endif
+ eor v24.16b,v24.16b,v31.16b
+
+.Lprocess_block_ce:
+
+ bl KeccakF1600_ce
+
+ b .Loop_absorb_ce
+
+.align 4
+.Labsorbed_ce:
+ stp d0,d1,[x0,#8*0]
+ stp d2,d3,[x0,#8*2]
+ stp d4,d5,[x0,#8*4]
+ stp d6,d7,[x0,#8*6]
+ stp d8,d9,[x0,#8*8]
+ stp d10,d11,[x0,#8*10]
+ stp d12,d13,[x0,#8*12]
+ stp d14,d15,[x0,#8*14]
+ stp d16,d17,[x0,#8*16]
+ stp d18,d19,[x0,#8*18]
+ stp d20,d21,[x0,#8*20]
+ stp d22,d23,[x0,#8*22]
+ str d24,[x0,#8*24]
+ add x0,x2,x3 // return value
+
+ ldp d8,d9,[sp,#16]
+ ldp d10,d11,[sp,#32]
+ ldp d12,d13,[sp,#48]
+ ldp d14,d15,[sp,#64]
+ ldp x29,x30,[sp],#80
+.inst 0xd50323bf // autiasp
+ ret
+.size SHA3_absorb_cext,.-SHA3_absorb_cext
+.globl SHA3_squeeze_cext
+.type SHA3_squeeze_cext,%function
+.align 5
+SHA3_squeeze_cext:
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ mov x9,x0
+ mov x10,x3
+
+.Loop_squeeze_ce:
+ ldr x4,[x9],#8
+ cmp x2,#8
+ blo .Lsqueeze_tail_ce
+#ifdef __AARCH64EB__
+ rev x4,x4
+#endif
+ str x4,[x1],#8
+ beq .Lsqueeze_done_ce
+
+ sub x2,x2,#8
+ subs x10,x10,#8
+ bhi .Loop_squeeze_ce
+
+ bl KeccakF1600_cext
+ ldr x30,[sp,#8]
+ mov x9,x0
+ mov x10,x3
+ b .Loop_squeeze_ce
+
+.align 4
+.Lsqueeze_tail_ce:
+ strb w4,[x1],#1
+ lsr x4,x4,#8
+ subs x2,x2,#1
+ beq .Lsqueeze_done_ce
+ strb w4,[x1],#1
+ lsr x4,x4,#8
+ subs x2,x2,#1
+ beq .Lsqueeze_done_ce
+ strb w4,[x1],#1
+ lsr x4,x4,#8
+ subs x2,x2,#1
+ beq .Lsqueeze_done_ce
+ strb w4,[x1],#1
+ lsr x4,x4,#8
+ subs x2,x2,#1
+ beq .Lsqueeze_done_ce
+ strb w4,[x1],#1
+ lsr x4,x4,#8
+ subs x2,x2,#1
+ beq .Lsqueeze_done_ce
+ strb w4,[x1],#1
+ lsr x4,x4,#8
+ subs x2,x2,#1
+ beq .Lsqueeze_done_ce
+ strb w4,[x1],#1
+
+.Lsqueeze_done_ce:
+ ldr x29,[sp],#16
+.inst 0xd50323bf // autiasp
+ ret
+.size SHA3_squeeze_cext,.-SHA3_squeeze_cext
+.byte 75,101,99,99,97,107,45,49,54,48,48,32,97,98,115,111,114,98,32,97,110,100,32,115,113,117,101,101,122,101,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 2
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha1-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha1-armv8.S
new file mode 100644
index 0000000..7f6d5be
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha1-armv8.S
@@ -0,0 +1,1211 @@
+#ifndef __KERNEL__
+# include "arm_arch.h"
+
+.hidden OPENSSL_armcap_P
+#endif
+
+.text
+
+.globl sha1_block_data_order
+.type sha1_block_data_order,%function
+.align 6
+sha1_block_data_order:
+ adrp x16,OPENSSL_armcap_P
+ ldr w16,[x16,#:lo12:OPENSSL_armcap_P]
+ tst w16,#ARMV8_SHA1
+ b.ne .Lv8_entry
+
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+
+ ldp w20,w21,[x0]
+ ldp w22,w23,[x0,#8]
+ ldr w24,[x0,#16]
+
+.Loop:
+ ldr x3,[x1],#64
+ movz w28,#0x7999
+ sub x2,x2,#1
+ movk w28,#0x5a82,lsl#16
+#ifdef __AARCH64EB__
+ ror x3,x3,#32
+#else
+ rev32 x3,x3
+#endif
+ add w24,w24,w28 // warm it up
+ add w24,w24,w3
+ lsr x4,x3,#32
+ ldur x5,[x1,#-56]
+ bic w25,w23,w21
+ and w26,w22,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ orr w25,w25,w26
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ add w23,w23,w4 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+#ifdef __AARCH64EB__
+ ror x5,x5,#32
+#else
+ rev32 x5,x5
+#endif
+ bic w25,w22,w20
+ and w26,w21,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ orr w25,w25,w26
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ add w22,w22,w5 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ lsr x6,x5,#32
+ ldur x7,[x1,#-48]
+ bic w25,w21,w24
+ and w26,w20,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ orr w25,w25,w26
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ add w21,w21,w6 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+#ifdef __AARCH64EB__
+ ror x7,x7,#32
+#else
+ rev32 x7,x7
+#endif
+ bic w25,w20,w23
+ and w26,w24,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ orr w25,w25,w26
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ add w20,w20,w7 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ lsr x8,x7,#32
+ ldur x9,[x1,#-40]
+ bic w25,w24,w22
+ and w26,w23,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ orr w25,w25,w26
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ add w24,w24,w8 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+#ifdef __AARCH64EB__
+ ror x9,x9,#32
+#else
+ rev32 x9,x9
+#endif
+ bic w25,w23,w21
+ and w26,w22,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ orr w25,w25,w26
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ add w23,w23,w9 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ lsr x10,x9,#32
+ ldur x11,[x1,#-32]
+ bic w25,w22,w20
+ and w26,w21,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ orr w25,w25,w26
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ add w22,w22,w10 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+#ifdef __AARCH64EB__
+ ror x11,x11,#32
+#else
+ rev32 x11,x11
+#endif
+ bic w25,w21,w24
+ and w26,w20,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ orr w25,w25,w26
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ add w21,w21,w11 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ lsr x12,x11,#32
+ ldur x13,[x1,#-24]
+ bic w25,w20,w23
+ and w26,w24,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ orr w25,w25,w26
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ add w20,w20,w12 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+#ifdef __AARCH64EB__
+ ror x13,x13,#32
+#else
+ rev32 x13,x13
+#endif
+ bic w25,w24,w22
+ and w26,w23,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ orr w25,w25,w26
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ add w24,w24,w13 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ lsr x14,x13,#32
+ ldur x15,[x1,#-16]
+ bic w25,w23,w21
+ and w26,w22,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ orr w25,w25,w26
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ add w23,w23,w14 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+#ifdef __AARCH64EB__
+ ror x15,x15,#32
+#else
+ rev32 x15,x15
+#endif
+ bic w25,w22,w20
+ and w26,w21,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ orr w25,w25,w26
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ add w22,w22,w15 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ lsr x16,x15,#32
+ ldur x17,[x1,#-8]
+ bic w25,w21,w24
+ and w26,w20,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ orr w25,w25,w26
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ add w21,w21,w16 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+#ifdef __AARCH64EB__
+ ror x17,x17,#32
+#else
+ rev32 x17,x17
+#endif
+ bic w25,w20,w23
+ and w26,w24,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ orr w25,w25,w26
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ add w20,w20,w17 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ lsr x19,x17,#32
+ eor w3,w3,w5
+ bic w25,w24,w22
+ and w26,w23,w22
+ ror w27,w21,#27
+ eor w3,w3,w11
+ add w24,w24,w28 // future e+=K
+ orr w25,w25,w26
+ add w20,w20,w27 // e+=rot(a,5)
+ eor w3,w3,w16
+ ror w22,w22,#2
+ add w24,w24,w19 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w3,w3,#31
+ eor w4,w4,w6
+ bic w25,w23,w21
+ and w26,w22,w21
+ ror w27,w20,#27
+ eor w4,w4,w12
+ add w23,w23,w28 // future e+=K
+ orr w25,w25,w26
+ add w24,w24,w27 // e+=rot(a,5)
+ eor w4,w4,w17
+ ror w21,w21,#2
+ add w23,w23,w3 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w4,w4,#31
+ eor w5,w5,w7
+ bic w25,w22,w20
+ and w26,w21,w20
+ ror w27,w24,#27
+ eor w5,w5,w13
+ add w22,w22,w28 // future e+=K
+ orr w25,w25,w26
+ add w23,w23,w27 // e+=rot(a,5)
+ eor w5,w5,w19
+ ror w20,w20,#2
+ add w22,w22,w4 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w5,w5,#31
+ eor w6,w6,w8
+ bic w25,w21,w24
+ and w26,w20,w24
+ ror w27,w23,#27
+ eor w6,w6,w14
+ add w21,w21,w28 // future e+=K
+ orr w25,w25,w26
+ add w22,w22,w27 // e+=rot(a,5)
+ eor w6,w6,w3
+ ror w24,w24,#2
+ add w21,w21,w5 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w6,w6,#31
+ eor w7,w7,w9
+ bic w25,w20,w23
+ and w26,w24,w23
+ ror w27,w22,#27
+ eor w7,w7,w15
+ add w20,w20,w28 // future e+=K
+ orr w25,w25,w26
+ add w21,w21,w27 // e+=rot(a,5)
+ eor w7,w7,w4
+ ror w23,w23,#2
+ add w20,w20,w6 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w7,w7,#31
+ movz w28,#0xeba1
+ movk w28,#0x6ed9,lsl#16
+ eor w8,w8,w10
+ bic w25,w24,w22
+ and w26,w23,w22
+ ror w27,w21,#27
+ eor w8,w8,w16
+ add w24,w24,w28 // future e+=K
+ orr w25,w25,w26
+ add w20,w20,w27 // e+=rot(a,5)
+ eor w8,w8,w5
+ ror w22,w22,#2
+ add w24,w24,w7 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w8,w8,#31
+ eor w9,w9,w11
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w9,w9,w17
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w9,w9,w6
+ add w23,w23,w8 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w9,w9,#31
+ eor w10,w10,w12
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w10,w10,w19
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w10,w10,w7
+ add w22,w22,w9 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w10,w10,#31
+ eor w11,w11,w13
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w11,w11,w3
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w11,w11,w8
+ add w21,w21,w10 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w11,w11,#31
+ eor w12,w12,w14
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w12,w12,w4
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w12,w12,w9
+ add w20,w20,w11 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w12,w12,#31
+ eor w13,w13,w15
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w13,w13,w5
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w13,w13,w10
+ add w24,w24,w12 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w13,w13,#31
+ eor w14,w14,w16
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w14,w14,w6
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w14,w14,w11
+ add w23,w23,w13 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w14,w14,#31
+ eor w15,w15,w17
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w15,w15,w7
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w15,w15,w12
+ add w22,w22,w14 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w15,w15,#31
+ eor w16,w16,w19
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w16,w16,w8
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w16,w16,w13
+ add w21,w21,w15 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w16,w16,#31
+ eor w17,w17,w3
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w17,w17,w9
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w17,w17,w14
+ add w20,w20,w16 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w17,w17,#31
+ eor w19,w19,w4
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w19,w19,w10
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w19,w19,w15
+ add w24,w24,w17 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w19,w19,#31
+ eor w3,w3,w5
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w3,w3,w11
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w3,w3,w16
+ add w23,w23,w19 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w3,w3,#31
+ eor w4,w4,w6
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w4,w4,w12
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w4,w4,w17
+ add w22,w22,w3 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w4,w4,#31
+ eor w5,w5,w7
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w5,w5,w13
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w5,w5,w19
+ add w21,w21,w4 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w5,w5,#31
+ eor w6,w6,w8
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w6,w6,w14
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w6,w6,w3
+ add w20,w20,w5 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w6,w6,#31
+ eor w7,w7,w9
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w7,w7,w15
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w7,w7,w4
+ add w24,w24,w6 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w7,w7,#31
+ eor w8,w8,w10
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w8,w8,w16
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w8,w8,w5
+ add w23,w23,w7 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w8,w8,#31
+ eor w9,w9,w11
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w9,w9,w17
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w9,w9,w6
+ add w22,w22,w8 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w9,w9,#31
+ eor w10,w10,w12
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w10,w10,w19
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w10,w10,w7
+ add w21,w21,w9 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w10,w10,#31
+ eor w11,w11,w13
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w11,w11,w3
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w11,w11,w8
+ add w20,w20,w10 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w11,w11,#31
+ movz w28,#0xbcdc
+ movk w28,#0x8f1b,lsl#16
+ eor w12,w12,w14
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w12,w12,w4
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w12,w12,w9
+ add w24,w24,w11 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w12,w12,#31
+ orr w25,w21,w22
+ and w26,w21,w22
+ eor w13,w13,w15
+ ror w27,w20,#27
+ and w25,w25,w23
+ add w23,w23,w28 // future e+=K
+ eor w13,w13,w5
+ add w24,w24,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w21,w21,#2
+ eor w13,w13,w10
+ add w23,w23,w12 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w13,w13,#31
+ orr w25,w20,w21
+ and w26,w20,w21
+ eor w14,w14,w16
+ ror w27,w24,#27
+ and w25,w25,w22
+ add w22,w22,w28 // future e+=K
+ eor w14,w14,w6
+ add w23,w23,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w20,w20,#2
+ eor w14,w14,w11
+ add w22,w22,w13 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w14,w14,#31
+ orr w25,w24,w20
+ and w26,w24,w20
+ eor w15,w15,w17
+ ror w27,w23,#27
+ and w25,w25,w21
+ add w21,w21,w28 // future e+=K
+ eor w15,w15,w7
+ add w22,w22,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w24,w24,#2
+ eor w15,w15,w12
+ add w21,w21,w14 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w15,w15,#31
+ orr w25,w23,w24
+ and w26,w23,w24
+ eor w16,w16,w19
+ ror w27,w22,#27
+ and w25,w25,w20
+ add w20,w20,w28 // future e+=K
+ eor w16,w16,w8
+ add w21,w21,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w23,w23,#2
+ eor w16,w16,w13
+ add w20,w20,w15 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w16,w16,#31
+ orr w25,w22,w23
+ and w26,w22,w23
+ eor w17,w17,w3
+ ror w27,w21,#27
+ and w25,w25,w24
+ add w24,w24,w28 // future e+=K
+ eor w17,w17,w9
+ add w20,w20,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w22,w22,#2
+ eor w17,w17,w14
+ add w24,w24,w16 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w17,w17,#31
+ orr w25,w21,w22
+ and w26,w21,w22
+ eor w19,w19,w4
+ ror w27,w20,#27
+ and w25,w25,w23
+ add w23,w23,w28 // future e+=K
+ eor w19,w19,w10
+ add w24,w24,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w21,w21,#2
+ eor w19,w19,w15
+ add w23,w23,w17 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w19,w19,#31
+ orr w25,w20,w21
+ and w26,w20,w21
+ eor w3,w3,w5
+ ror w27,w24,#27
+ and w25,w25,w22
+ add w22,w22,w28 // future e+=K
+ eor w3,w3,w11
+ add w23,w23,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w20,w20,#2
+ eor w3,w3,w16
+ add w22,w22,w19 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w3,w3,#31
+ orr w25,w24,w20
+ and w26,w24,w20
+ eor w4,w4,w6
+ ror w27,w23,#27
+ and w25,w25,w21
+ add w21,w21,w28 // future e+=K
+ eor w4,w4,w12
+ add w22,w22,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w24,w24,#2
+ eor w4,w4,w17
+ add w21,w21,w3 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w4,w4,#31
+ orr w25,w23,w24
+ and w26,w23,w24
+ eor w5,w5,w7
+ ror w27,w22,#27
+ and w25,w25,w20
+ add w20,w20,w28 // future e+=K
+ eor w5,w5,w13
+ add w21,w21,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w23,w23,#2
+ eor w5,w5,w19
+ add w20,w20,w4 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w5,w5,#31
+ orr w25,w22,w23
+ and w26,w22,w23
+ eor w6,w6,w8
+ ror w27,w21,#27
+ and w25,w25,w24
+ add w24,w24,w28 // future e+=K
+ eor w6,w6,w14
+ add w20,w20,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w22,w22,#2
+ eor w6,w6,w3
+ add w24,w24,w5 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w6,w6,#31
+ orr w25,w21,w22
+ and w26,w21,w22
+ eor w7,w7,w9
+ ror w27,w20,#27
+ and w25,w25,w23
+ add w23,w23,w28 // future e+=K
+ eor w7,w7,w15
+ add w24,w24,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w21,w21,#2
+ eor w7,w7,w4
+ add w23,w23,w6 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w7,w7,#31
+ orr w25,w20,w21
+ and w26,w20,w21
+ eor w8,w8,w10
+ ror w27,w24,#27
+ and w25,w25,w22
+ add w22,w22,w28 // future e+=K
+ eor w8,w8,w16
+ add w23,w23,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w20,w20,#2
+ eor w8,w8,w5
+ add w22,w22,w7 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w8,w8,#31
+ orr w25,w24,w20
+ and w26,w24,w20
+ eor w9,w9,w11
+ ror w27,w23,#27
+ and w25,w25,w21
+ add w21,w21,w28 // future e+=K
+ eor w9,w9,w17
+ add w22,w22,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w24,w24,#2
+ eor w9,w9,w6
+ add w21,w21,w8 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w9,w9,#31
+ orr w25,w23,w24
+ and w26,w23,w24
+ eor w10,w10,w12
+ ror w27,w22,#27
+ and w25,w25,w20
+ add w20,w20,w28 // future e+=K
+ eor w10,w10,w19
+ add w21,w21,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w23,w23,#2
+ eor w10,w10,w7
+ add w20,w20,w9 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w10,w10,#31
+ orr w25,w22,w23
+ and w26,w22,w23
+ eor w11,w11,w13
+ ror w27,w21,#27
+ and w25,w25,w24
+ add w24,w24,w28 // future e+=K
+ eor w11,w11,w3
+ add w20,w20,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w22,w22,#2
+ eor w11,w11,w8
+ add w24,w24,w10 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w11,w11,#31
+ orr w25,w21,w22
+ and w26,w21,w22
+ eor w12,w12,w14
+ ror w27,w20,#27
+ and w25,w25,w23
+ add w23,w23,w28 // future e+=K
+ eor w12,w12,w4
+ add w24,w24,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w21,w21,#2
+ eor w12,w12,w9
+ add w23,w23,w11 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w12,w12,#31
+ orr w25,w20,w21
+ and w26,w20,w21
+ eor w13,w13,w15
+ ror w27,w24,#27
+ and w25,w25,w22
+ add w22,w22,w28 // future e+=K
+ eor w13,w13,w5
+ add w23,w23,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w20,w20,#2
+ eor w13,w13,w10
+ add w22,w22,w12 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w13,w13,#31
+ orr w25,w24,w20
+ and w26,w24,w20
+ eor w14,w14,w16
+ ror w27,w23,#27
+ and w25,w25,w21
+ add w21,w21,w28 // future e+=K
+ eor w14,w14,w6
+ add w22,w22,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w24,w24,#2
+ eor w14,w14,w11
+ add w21,w21,w13 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w14,w14,#31
+ orr w25,w23,w24
+ and w26,w23,w24
+ eor w15,w15,w17
+ ror w27,w22,#27
+ and w25,w25,w20
+ add w20,w20,w28 // future e+=K
+ eor w15,w15,w7
+ add w21,w21,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w23,w23,#2
+ eor w15,w15,w12
+ add w20,w20,w14 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w15,w15,#31
+ movz w28,#0xc1d6
+ movk w28,#0xca62,lsl#16
+ orr w25,w22,w23
+ and w26,w22,w23
+ eor w16,w16,w19
+ ror w27,w21,#27
+ and w25,w25,w24
+ add w24,w24,w28 // future e+=K
+ eor w16,w16,w8
+ add w20,w20,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w22,w22,#2
+ eor w16,w16,w13
+ add w24,w24,w15 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w16,w16,#31
+ eor w17,w17,w3
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w17,w17,w9
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w17,w17,w14
+ add w23,w23,w16 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w17,w17,#31
+ eor w19,w19,w4
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w19,w19,w10
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w19,w19,w15
+ add w22,w22,w17 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w19,w19,#31
+ eor w3,w3,w5
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w3,w3,w11
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w3,w3,w16
+ add w21,w21,w19 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w3,w3,#31
+ eor w4,w4,w6
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w4,w4,w12
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w4,w4,w17
+ add w20,w20,w3 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w4,w4,#31
+ eor w5,w5,w7
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w5,w5,w13
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w5,w5,w19
+ add w24,w24,w4 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w5,w5,#31
+ eor w6,w6,w8
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w6,w6,w14
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w6,w6,w3
+ add w23,w23,w5 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w6,w6,#31
+ eor w7,w7,w9
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w7,w7,w15
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w7,w7,w4
+ add w22,w22,w6 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w7,w7,#31
+ eor w8,w8,w10
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w8,w8,w16
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w8,w8,w5
+ add w21,w21,w7 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w8,w8,#31
+ eor w9,w9,w11
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w9,w9,w17
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w9,w9,w6
+ add w20,w20,w8 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w9,w9,#31
+ eor w10,w10,w12
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w10,w10,w19
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w10,w10,w7
+ add w24,w24,w9 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w10,w10,#31
+ eor w11,w11,w13
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w11,w11,w3
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w11,w11,w8
+ add w23,w23,w10 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w11,w11,#31
+ eor w12,w12,w14
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w12,w12,w4
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w12,w12,w9
+ add w22,w22,w11 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w12,w12,#31
+ eor w13,w13,w15
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w13,w13,w5
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w13,w13,w10
+ add w21,w21,w12 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w13,w13,#31
+ eor w14,w14,w16
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w14,w14,w6
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w14,w14,w11
+ add w20,w20,w13 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w14,w14,#31
+ eor w15,w15,w17
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w15,w15,w7
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w15,w15,w12
+ add w24,w24,w14 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w15,w15,#31
+ eor w16,w16,w19
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w16,w16,w8
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w16,w16,w13
+ add w23,w23,w15 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w16,w16,#31
+ eor w17,w17,w3
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w17,w17,w9
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w17,w17,w14
+ add w22,w22,w16 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w17,w17,#31
+ eor w19,w19,w4
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w19,w19,w10
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w19,w19,w15
+ add w21,w21,w17 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w19,w19,#31
+ ldp w4,w5,[x0]
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ add w20,w20,w19 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ldp w6,w7,[x0,#8]
+ eor w25,w24,w22
+ ror w27,w21,#27
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ ldr w8,[x0,#16]
+ add w20,w20,w25 // e+=F(b,c,d)
+ add w21,w21,w5
+ add w22,w22,w6
+ add w20,w20,w4
+ add w23,w23,w7
+ add w24,w24,w8
+ stp w20,w21,[x0]
+ stp w22,w23,[x0,#8]
+ str w24,[x0,#16]
+ cbnz x2,.Loop
+
+ ldp x19,x20,[sp,#16]
+ ldp x21,x22,[sp,#32]
+ ldp x23,x24,[sp,#48]
+ ldp x25,x26,[sp,#64]
+ ldp x27,x28,[sp,#80]
+ ldr x29,[sp],#96
+ ret
+.size sha1_block_data_order,.-sha1_block_data_order
+.type sha1_block_armv8,%function
+.align 6
+sha1_block_armv8:
+.Lv8_entry:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ adr x4,.Lconst
+ eor v1.16b,v1.16b,v1.16b
+ ld1 {v0.4s},[x0],#16
+ ld1 {v1.s}[0],[x0]
+ sub x0,x0,#16
+ ld1 {v16.4s,v17.4s,v18.4s,v19.4s},[x4]
+
+.Loop_hw:
+ ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64
+ sub x2,x2,#1
+ rev32 v4.16b,v4.16b
+ rev32 v5.16b,v5.16b
+
+ add v20.4s,v16.4s,v4.4s
+ rev32 v6.16b,v6.16b
+ orr v22.16b,v0.16b,v0.16b // offload
+
+ add v21.4s,v16.4s,v5.4s
+ rev32 v7.16b,v7.16b
+.inst 0x5e280803 //sha1h v3.16b,v0.16b
+.inst 0x5e140020 //sha1c v0.16b,v1.16b,v20.4s // 0
+ add v20.4s,v16.4s,v6.4s
+.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b
+.inst 0x5e280802 //sha1h v2.16b,v0.16b // 1
+.inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s
+ add v21.4s,v16.4s,v7.4s
+.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b
+.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b
+.inst 0x5e280803 //sha1h v3.16b,v0.16b // 2
+.inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s
+ add v20.4s,v16.4s,v4.4s
+.inst 0x5e281885 //sha1su1 v5.16b,v4.16b
+.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b
+.inst 0x5e280802 //sha1h v2.16b,v0.16b // 3
+.inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s
+ add v21.4s,v17.4s,v5.4s
+.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b
+.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b
+.inst 0x5e280803 //sha1h v3.16b,v0.16b // 4
+.inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s
+ add v20.4s,v17.4s,v6.4s
+.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b
+.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b
+.inst 0x5e280802 //sha1h v2.16b,v0.16b // 5
+.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+ add v21.4s,v17.4s,v7.4s
+.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b
+.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b
+.inst 0x5e280803 //sha1h v3.16b,v0.16b // 6
+.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s
+ add v20.4s,v17.4s,v4.4s
+.inst 0x5e281885 //sha1su1 v5.16b,v4.16b
+.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b
+.inst 0x5e280802 //sha1h v2.16b,v0.16b // 7
+.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+ add v21.4s,v17.4s,v5.4s
+.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b
+.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b
+.inst 0x5e280803 //sha1h v3.16b,v0.16b // 8
+.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s
+ add v20.4s,v18.4s,v6.4s
+.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b
+.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b
+.inst 0x5e280802 //sha1h v2.16b,v0.16b // 9
+.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+ add v21.4s,v18.4s,v7.4s
+.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b
+.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b
+.inst 0x5e280803 //sha1h v3.16b,v0.16b // 10
+.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s
+ add v20.4s,v18.4s,v4.4s
+.inst 0x5e281885 //sha1su1 v5.16b,v4.16b
+.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b
+.inst 0x5e280802 //sha1h v2.16b,v0.16b // 11
+.inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s
+ add v21.4s,v18.4s,v5.4s
+.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b
+.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b
+.inst 0x5e280803 //sha1h v3.16b,v0.16b // 12
+.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s
+ add v20.4s,v18.4s,v6.4s
+.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b
+.inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b
+.inst 0x5e280802 //sha1h v2.16b,v0.16b // 13
+.inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s
+ add v21.4s,v19.4s,v7.4s
+.inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b
+.inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b
+.inst 0x5e280803 //sha1h v3.16b,v0.16b // 14
+.inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s
+ add v20.4s,v19.4s,v4.4s
+.inst 0x5e281885 //sha1su1 v5.16b,v4.16b
+.inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b
+.inst 0x5e280802 //sha1h v2.16b,v0.16b // 15
+.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+ add v21.4s,v19.4s,v5.4s
+.inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b
+.inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b
+.inst 0x5e280803 //sha1h v3.16b,v0.16b // 16
+.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s
+ add v20.4s,v19.4s,v6.4s
+.inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b
+.inst 0x5e280802 //sha1h v2.16b,v0.16b // 17
+.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+ add v21.4s,v19.4s,v7.4s
+
+.inst 0x5e280803 //sha1h v3.16b,v0.16b // 18
+.inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s
+
+.inst 0x5e280802 //sha1h v2.16b,v0.16b // 19
+.inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+
+ add v1.4s,v1.4s,v2.4s
+ add v0.4s,v0.4s,v22.4s
+
+ cbnz x2,.Loop_hw
+
+ st1 {v0.4s},[x0],#16
+ st1 {v1.s}[0],[x0]
+
+ ldr x29,[sp],#16
+ ret
+.size sha1_block_armv8,.-sha1_block_armv8
+.align 6
+.Lconst:
+.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 //K_00_19
+.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39
+.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59
+.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79
+.byte 83,72,65,49,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 2
+.align 2
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha256-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha256-armv8.S
new file mode 100644
index 0000000..92a5964
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha256-armv8.S
@@ -0,0 +1,2000 @@
+// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You may not use
+// this file except in compliance with the License. You can obtain a copy
+// in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+#ifndef __KERNEL__
+# include "arm_arch.h"
+
+.hidden OPENSSL_armcap_P
+#endif
+
+.text
+
+.globl sha256_block_data_order
+.type sha256_block_data_order,%function
+.align 6
+sha256_block_data_order:
+#ifndef __KERNEL__
+ adrp x16,OPENSSL_armcap_P
+ ldr w16,[x16,#:lo12:OPENSSL_armcap_P]
+ tst w16,#ARMV8_SHA256
+ b.ne .Lv8_entry
+ tst w16,#ARMV7_NEON
+ b.ne .Lneon_entry
+#endif
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ sub sp,sp,#4*4
+
+ ldp w20,w21,[x0] // load context
+ ldp w22,w23,[x0,#2*4]
+ ldp w24,w25,[x0,#4*4]
+ add x2,x1,x2,lsl#6 // end of input
+ ldp w26,w27,[x0,#6*4]
+ adr x30,.LK256
+ stp x0,x2,[x29,#96]
+
+.Loop:
+ ldp w3,w4,[x1],#2*4
+ ldr w19,[x30],#4 // *K++
+ eor w28,w21,w22 // magic seed
+ str x1,[x29,#112]
+#ifndef __AARCH64EB__
+ rev w3,w3 // 0
+#endif
+ ror w16,w24,#6
+ add w27,w27,w19 // h+=K[i]
+ eor w6,w24,w24,ror#14
+ and w17,w25,w24
+ bic w19,w26,w24
+ add w27,w27,w3 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w20,w21 // a^b, b^c in next round
+ eor w16,w16,w6,ror#11 // Sigma1(e)
+ ror w6,w20,#2
+ add w27,w27,w17 // h+=Ch(e,f,g)
+ eor w17,w20,w20,ror#9
+ add w27,w27,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w23,w23,w27 // d+=h
+ eor w28,w28,w21 // Maj(a,b,c)
+ eor w17,w6,w17,ror#13 // Sigma0(a)
+ add w27,w27,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w27,w27,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w4,w4 // 1
+#endif
+ ldp w5,w6,[x1],#2*4
+ add w27,w27,w17 // h+=Sigma0(a)
+ ror w16,w23,#6
+ add w26,w26,w28 // h+=K[i]
+ eor w7,w23,w23,ror#14
+ and w17,w24,w23
+ bic w28,w25,w23
+ add w26,w26,w4 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w27,w20 // a^b, b^c in next round
+ eor w16,w16,w7,ror#11 // Sigma1(e)
+ ror w7,w27,#2
+ add w26,w26,w17 // h+=Ch(e,f,g)
+ eor w17,w27,w27,ror#9
+ add w26,w26,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w22,w22,w26 // d+=h
+ eor w19,w19,w20 // Maj(a,b,c)
+ eor w17,w7,w17,ror#13 // Sigma0(a)
+ add w26,w26,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w26,w26,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w5,w5 // 2
+#endif
+ add w26,w26,w17 // h+=Sigma0(a)
+ ror w16,w22,#6
+ add w25,w25,w19 // h+=K[i]
+ eor w8,w22,w22,ror#14
+ and w17,w23,w22
+ bic w19,w24,w22
+ add w25,w25,w5 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w26,w27 // a^b, b^c in next round
+ eor w16,w16,w8,ror#11 // Sigma1(e)
+ ror w8,w26,#2
+ add w25,w25,w17 // h+=Ch(e,f,g)
+ eor w17,w26,w26,ror#9
+ add w25,w25,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w21,w21,w25 // d+=h
+ eor w28,w28,w27 // Maj(a,b,c)
+ eor w17,w8,w17,ror#13 // Sigma0(a)
+ add w25,w25,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w25,w25,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w6,w6 // 3
+#endif
+ ldp w7,w8,[x1],#2*4
+ add w25,w25,w17 // h+=Sigma0(a)
+ ror w16,w21,#6
+ add w24,w24,w28 // h+=K[i]
+ eor w9,w21,w21,ror#14
+ and w17,w22,w21
+ bic w28,w23,w21
+ add w24,w24,w6 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w25,w26 // a^b, b^c in next round
+ eor w16,w16,w9,ror#11 // Sigma1(e)
+ ror w9,w25,#2
+ add w24,w24,w17 // h+=Ch(e,f,g)
+ eor w17,w25,w25,ror#9
+ add w24,w24,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w20,w20,w24 // d+=h
+ eor w19,w19,w26 // Maj(a,b,c)
+ eor w17,w9,w17,ror#13 // Sigma0(a)
+ add w24,w24,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w24,w24,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w7,w7 // 4
+#endif
+ add w24,w24,w17 // h+=Sigma0(a)
+ ror w16,w20,#6
+ add w23,w23,w19 // h+=K[i]
+ eor w10,w20,w20,ror#14
+ and w17,w21,w20
+ bic w19,w22,w20
+ add w23,w23,w7 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w24,w25 // a^b, b^c in next round
+ eor w16,w16,w10,ror#11 // Sigma1(e)
+ ror w10,w24,#2
+ add w23,w23,w17 // h+=Ch(e,f,g)
+ eor w17,w24,w24,ror#9
+ add w23,w23,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w27,w27,w23 // d+=h
+ eor w28,w28,w25 // Maj(a,b,c)
+ eor w17,w10,w17,ror#13 // Sigma0(a)
+ add w23,w23,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w23,w23,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w8,w8 // 5
+#endif
+ ldp w9,w10,[x1],#2*4
+ add w23,w23,w17 // h+=Sigma0(a)
+ ror w16,w27,#6
+ add w22,w22,w28 // h+=K[i]
+ eor w11,w27,w27,ror#14
+ and w17,w20,w27
+ bic w28,w21,w27
+ add w22,w22,w8 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w23,w24 // a^b, b^c in next round
+ eor w16,w16,w11,ror#11 // Sigma1(e)
+ ror w11,w23,#2
+ add w22,w22,w17 // h+=Ch(e,f,g)
+ eor w17,w23,w23,ror#9
+ add w22,w22,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w26,w26,w22 // d+=h
+ eor w19,w19,w24 // Maj(a,b,c)
+ eor w17,w11,w17,ror#13 // Sigma0(a)
+ add w22,w22,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w22,w22,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w9,w9 // 6
+#endif
+ add w22,w22,w17 // h+=Sigma0(a)
+ ror w16,w26,#6
+ add w21,w21,w19 // h+=K[i]
+ eor w12,w26,w26,ror#14
+ and w17,w27,w26
+ bic w19,w20,w26
+ add w21,w21,w9 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w22,w23 // a^b, b^c in next round
+ eor w16,w16,w12,ror#11 // Sigma1(e)
+ ror w12,w22,#2
+ add w21,w21,w17 // h+=Ch(e,f,g)
+ eor w17,w22,w22,ror#9
+ add w21,w21,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w25,w25,w21 // d+=h
+ eor w28,w28,w23 // Maj(a,b,c)
+ eor w17,w12,w17,ror#13 // Sigma0(a)
+ add w21,w21,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w21,w21,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w10,w10 // 7
+#endif
+ ldp w11,w12,[x1],#2*4
+ add w21,w21,w17 // h+=Sigma0(a)
+ ror w16,w25,#6
+ add w20,w20,w28 // h+=K[i]
+ eor w13,w25,w25,ror#14
+ and w17,w26,w25
+ bic w28,w27,w25
+ add w20,w20,w10 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w21,w22 // a^b, b^c in next round
+ eor w16,w16,w13,ror#11 // Sigma1(e)
+ ror w13,w21,#2
+ add w20,w20,w17 // h+=Ch(e,f,g)
+ eor w17,w21,w21,ror#9
+ add w20,w20,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w24,w24,w20 // d+=h
+ eor w19,w19,w22 // Maj(a,b,c)
+ eor w17,w13,w17,ror#13 // Sigma0(a)
+ add w20,w20,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w20,w20,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w11,w11 // 8
+#endif
+ add w20,w20,w17 // h+=Sigma0(a)
+ ror w16,w24,#6
+ add w27,w27,w19 // h+=K[i]
+ eor w14,w24,w24,ror#14
+ and w17,w25,w24
+ bic w19,w26,w24
+ add w27,w27,w11 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w20,w21 // a^b, b^c in next round
+ eor w16,w16,w14,ror#11 // Sigma1(e)
+ ror w14,w20,#2
+ add w27,w27,w17 // h+=Ch(e,f,g)
+ eor w17,w20,w20,ror#9
+ add w27,w27,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w23,w23,w27 // d+=h
+ eor w28,w28,w21 // Maj(a,b,c)
+ eor w17,w14,w17,ror#13 // Sigma0(a)
+ add w27,w27,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w27,w27,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w12,w12 // 9
+#endif
+ ldp w13,w14,[x1],#2*4
+ add w27,w27,w17 // h+=Sigma0(a)
+ ror w16,w23,#6
+ add w26,w26,w28 // h+=K[i]
+ eor w15,w23,w23,ror#14
+ and w17,w24,w23
+ bic w28,w25,w23
+ add w26,w26,w12 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w27,w20 // a^b, b^c in next round
+ eor w16,w16,w15,ror#11 // Sigma1(e)
+ ror w15,w27,#2
+ add w26,w26,w17 // h+=Ch(e,f,g)
+ eor w17,w27,w27,ror#9
+ add w26,w26,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w22,w22,w26 // d+=h
+ eor w19,w19,w20 // Maj(a,b,c)
+ eor w17,w15,w17,ror#13 // Sigma0(a)
+ add w26,w26,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w26,w26,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w13,w13 // 10
+#endif
+ add w26,w26,w17 // h+=Sigma0(a)
+ ror w16,w22,#6
+ add w25,w25,w19 // h+=K[i]
+ eor w0,w22,w22,ror#14
+ and w17,w23,w22
+ bic w19,w24,w22
+ add w25,w25,w13 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w26,w27 // a^b, b^c in next round
+ eor w16,w16,w0,ror#11 // Sigma1(e)
+ ror w0,w26,#2
+ add w25,w25,w17 // h+=Ch(e,f,g)
+ eor w17,w26,w26,ror#9
+ add w25,w25,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w21,w21,w25 // d+=h
+ eor w28,w28,w27 // Maj(a,b,c)
+ eor w17,w0,w17,ror#13 // Sigma0(a)
+ add w25,w25,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w25,w25,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w14,w14 // 11
+#endif
+ ldp w15,w0,[x1],#2*4
+ add w25,w25,w17 // h+=Sigma0(a)
+ str w6,[sp,#12]
+ ror w16,w21,#6
+ add w24,w24,w28 // h+=K[i]
+ eor w6,w21,w21,ror#14
+ and w17,w22,w21
+ bic w28,w23,w21
+ add w24,w24,w14 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w25,w26 // a^b, b^c in next round
+ eor w16,w16,w6,ror#11 // Sigma1(e)
+ ror w6,w25,#2
+ add w24,w24,w17 // h+=Ch(e,f,g)
+ eor w17,w25,w25,ror#9
+ add w24,w24,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w20,w20,w24 // d+=h
+ eor w19,w19,w26 // Maj(a,b,c)
+ eor w17,w6,w17,ror#13 // Sigma0(a)
+ add w24,w24,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w24,w24,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w15,w15 // 12
+#endif
+ add w24,w24,w17 // h+=Sigma0(a)
+ str w7,[sp,#0]
+ ror w16,w20,#6
+ add w23,w23,w19 // h+=K[i]
+ eor w7,w20,w20,ror#14
+ and w17,w21,w20
+ bic w19,w22,w20
+ add w23,w23,w15 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w24,w25 // a^b, b^c in next round
+ eor w16,w16,w7,ror#11 // Sigma1(e)
+ ror w7,w24,#2
+ add w23,w23,w17 // h+=Ch(e,f,g)
+ eor w17,w24,w24,ror#9
+ add w23,w23,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w27,w27,w23 // d+=h
+ eor w28,w28,w25 // Maj(a,b,c)
+ eor w17,w7,w17,ror#13 // Sigma0(a)
+ add w23,w23,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w23,w23,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w0,w0 // 13
+#endif
+ ldp w1,w2,[x1]
+ add w23,w23,w17 // h+=Sigma0(a)
+ str w8,[sp,#4]
+ ror w16,w27,#6
+ add w22,w22,w28 // h+=K[i]
+ eor w8,w27,w27,ror#14
+ and w17,w20,w27
+ bic w28,w21,w27
+ add w22,w22,w0 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w23,w24 // a^b, b^c in next round
+ eor w16,w16,w8,ror#11 // Sigma1(e)
+ ror w8,w23,#2
+ add w22,w22,w17 // h+=Ch(e,f,g)
+ eor w17,w23,w23,ror#9
+ add w22,w22,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w26,w26,w22 // d+=h
+ eor w19,w19,w24 // Maj(a,b,c)
+ eor w17,w8,w17,ror#13 // Sigma0(a)
+ add w22,w22,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w22,w22,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w1,w1 // 14
+#endif
+ ldr w6,[sp,#12]
+ add w22,w22,w17 // h+=Sigma0(a)
+ str w9,[sp,#8]
+ ror w16,w26,#6
+ add w21,w21,w19 // h+=K[i]
+ eor w9,w26,w26,ror#14
+ and w17,w27,w26
+ bic w19,w20,w26
+ add w21,w21,w1 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w22,w23 // a^b, b^c in next round
+ eor w16,w16,w9,ror#11 // Sigma1(e)
+ ror w9,w22,#2
+ add w21,w21,w17 // h+=Ch(e,f,g)
+ eor w17,w22,w22,ror#9
+ add w21,w21,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w25,w25,w21 // d+=h
+ eor w28,w28,w23 // Maj(a,b,c)
+ eor w17,w9,w17,ror#13 // Sigma0(a)
+ add w21,w21,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w21,w21,w17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev w2,w2 // 15
+#endif
+ ldr w7,[sp,#0]
+ add w21,w21,w17 // h+=Sigma0(a)
+ str w10,[sp,#12]
+ ror w16,w25,#6
+ add w20,w20,w28 // h+=K[i]
+ ror w9,w4,#7
+ and w17,w26,w25
+ ror w8,w1,#17
+ bic w28,w27,w25
+ ror w10,w21,#2
+ add w20,w20,w2 // h+=X[i]
+ eor w16,w16,w25,ror#11
+ eor w9,w9,w4,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w21,w22 // a^b, b^c in next round
+ eor w16,w16,w25,ror#25 // Sigma1(e)
+ eor w10,w10,w21,ror#13
+ add w20,w20,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w8,w8,w1,ror#19
+ eor w9,w9,w4,lsr#3 // sigma0(X[i+1])
+ add w20,w20,w16 // h+=Sigma1(e)
+ eor w19,w19,w22 // Maj(a,b,c)
+ eor w17,w10,w21,ror#22 // Sigma0(a)
+ eor w8,w8,w1,lsr#10 // sigma1(X[i+14])
+ add w3,w3,w12
+ add w24,w24,w20 // d+=h
+ add w20,w20,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w3,w3,w9
+ add w20,w20,w17 // h+=Sigma0(a)
+ add w3,w3,w8
+.Loop_16_xx:
+ ldr w8,[sp,#4]
+ str w11,[sp,#0]
+ ror w16,w24,#6
+ add w27,w27,w19 // h+=K[i]
+ ror w10,w5,#7
+ and w17,w25,w24
+ ror w9,w2,#17
+ bic w19,w26,w24
+ ror w11,w20,#2
+ add w27,w27,w3 // h+=X[i]
+ eor w16,w16,w24,ror#11
+ eor w10,w10,w5,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w20,w21 // a^b, b^c in next round
+ eor w16,w16,w24,ror#25 // Sigma1(e)
+ eor w11,w11,w20,ror#13
+ add w27,w27,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w9,w9,w2,ror#19
+ eor w10,w10,w5,lsr#3 // sigma0(X[i+1])
+ add w27,w27,w16 // h+=Sigma1(e)
+ eor w28,w28,w21 // Maj(a,b,c)
+ eor w17,w11,w20,ror#22 // Sigma0(a)
+ eor w9,w9,w2,lsr#10 // sigma1(X[i+14])
+ add w4,w4,w13
+ add w23,w23,w27 // d+=h
+ add w27,w27,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w4,w4,w10
+ add w27,w27,w17 // h+=Sigma0(a)
+ add w4,w4,w9
+ ldr w9,[sp,#8]
+ str w12,[sp,#4]
+ ror w16,w23,#6
+ add w26,w26,w28 // h+=K[i]
+ ror w11,w6,#7
+ and w17,w24,w23
+ ror w10,w3,#17
+ bic w28,w25,w23
+ ror w12,w27,#2
+ add w26,w26,w4 // h+=X[i]
+ eor w16,w16,w23,ror#11
+ eor w11,w11,w6,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w27,w20 // a^b, b^c in next round
+ eor w16,w16,w23,ror#25 // Sigma1(e)
+ eor w12,w12,w27,ror#13
+ add w26,w26,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w10,w10,w3,ror#19
+ eor w11,w11,w6,lsr#3 // sigma0(X[i+1])
+ add w26,w26,w16 // h+=Sigma1(e)
+ eor w19,w19,w20 // Maj(a,b,c)
+ eor w17,w12,w27,ror#22 // Sigma0(a)
+ eor w10,w10,w3,lsr#10 // sigma1(X[i+14])
+ add w5,w5,w14
+ add w22,w22,w26 // d+=h
+ add w26,w26,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w5,w5,w11
+ add w26,w26,w17 // h+=Sigma0(a)
+ add w5,w5,w10
+ ldr w10,[sp,#12]
+ str w13,[sp,#8]
+ ror w16,w22,#6
+ add w25,w25,w19 // h+=K[i]
+ ror w12,w7,#7
+ and w17,w23,w22
+ ror w11,w4,#17
+ bic w19,w24,w22
+ ror w13,w26,#2
+ add w25,w25,w5 // h+=X[i]
+ eor w16,w16,w22,ror#11
+ eor w12,w12,w7,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w26,w27 // a^b, b^c in next round
+ eor w16,w16,w22,ror#25 // Sigma1(e)
+ eor w13,w13,w26,ror#13
+ add w25,w25,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w11,w11,w4,ror#19
+ eor w12,w12,w7,lsr#3 // sigma0(X[i+1])
+ add w25,w25,w16 // h+=Sigma1(e)
+ eor w28,w28,w27 // Maj(a,b,c)
+ eor w17,w13,w26,ror#22 // Sigma0(a)
+ eor w11,w11,w4,lsr#10 // sigma1(X[i+14])
+ add w6,w6,w15
+ add w21,w21,w25 // d+=h
+ add w25,w25,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w6,w6,w12
+ add w25,w25,w17 // h+=Sigma0(a)
+ add w6,w6,w11
+ ldr w11,[sp,#0]
+ str w14,[sp,#12]
+ ror w16,w21,#6
+ add w24,w24,w28 // h+=K[i]
+ ror w13,w8,#7
+ and w17,w22,w21
+ ror w12,w5,#17
+ bic w28,w23,w21
+ ror w14,w25,#2
+ add w24,w24,w6 // h+=X[i]
+ eor w16,w16,w21,ror#11
+ eor w13,w13,w8,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w25,w26 // a^b, b^c in next round
+ eor w16,w16,w21,ror#25 // Sigma1(e)
+ eor w14,w14,w25,ror#13
+ add w24,w24,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w12,w12,w5,ror#19
+ eor w13,w13,w8,lsr#3 // sigma0(X[i+1])
+ add w24,w24,w16 // h+=Sigma1(e)
+ eor w19,w19,w26 // Maj(a,b,c)
+ eor w17,w14,w25,ror#22 // Sigma0(a)
+ eor w12,w12,w5,lsr#10 // sigma1(X[i+14])
+ add w7,w7,w0
+ add w20,w20,w24 // d+=h
+ add w24,w24,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w7,w7,w13
+ add w24,w24,w17 // h+=Sigma0(a)
+ add w7,w7,w12
+ ldr w12,[sp,#4]
+ str w15,[sp,#0]
+ ror w16,w20,#6
+ add w23,w23,w19 // h+=K[i]
+ ror w14,w9,#7
+ and w17,w21,w20
+ ror w13,w6,#17
+ bic w19,w22,w20
+ ror w15,w24,#2
+ add w23,w23,w7 // h+=X[i]
+ eor w16,w16,w20,ror#11
+ eor w14,w14,w9,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w24,w25 // a^b, b^c in next round
+ eor w16,w16,w20,ror#25 // Sigma1(e)
+ eor w15,w15,w24,ror#13
+ add w23,w23,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w13,w13,w6,ror#19
+ eor w14,w14,w9,lsr#3 // sigma0(X[i+1])
+ add w23,w23,w16 // h+=Sigma1(e)
+ eor w28,w28,w25 // Maj(a,b,c)
+ eor w17,w15,w24,ror#22 // Sigma0(a)
+ eor w13,w13,w6,lsr#10 // sigma1(X[i+14])
+ add w8,w8,w1
+ add w27,w27,w23 // d+=h
+ add w23,w23,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w8,w8,w14
+ add w23,w23,w17 // h+=Sigma0(a)
+ add w8,w8,w13
+ ldr w13,[sp,#8]
+ str w0,[sp,#4]
+ ror w16,w27,#6
+ add w22,w22,w28 // h+=K[i]
+ ror w15,w10,#7
+ and w17,w20,w27
+ ror w14,w7,#17
+ bic w28,w21,w27
+ ror w0,w23,#2
+ add w22,w22,w8 // h+=X[i]
+ eor w16,w16,w27,ror#11
+ eor w15,w15,w10,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w23,w24 // a^b, b^c in next round
+ eor w16,w16,w27,ror#25 // Sigma1(e)
+ eor w0,w0,w23,ror#13
+ add w22,w22,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w14,w14,w7,ror#19
+ eor w15,w15,w10,lsr#3 // sigma0(X[i+1])
+ add w22,w22,w16 // h+=Sigma1(e)
+ eor w19,w19,w24 // Maj(a,b,c)
+ eor w17,w0,w23,ror#22 // Sigma0(a)
+ eor w14,w14,w7,lsr#10 // sigma1(X[i+14])
+ add w9,w9,w2
+ add w26,w26,w22 // d+=h
+ add w22,w22,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w9,w9,w15
+ add w22,w22,w17 // h+=Sigma0(a)
+ add w9,w9,w14
+ ldr w14,[sp,#12]
+ str w1,[sp,#8]
+ ror w16,w26,#6
+ add w21,w21,w19 // h+=K[i]
+ ror w0,w11,#7
+ and w17,w27,w26
+ ror w15,w8,#17
+ bic w19,w20,w26
+ ror w1,w22,#2
+ add w21,w21,w9 // h+=X[i]
+ eor w16,w16,w26,ror#11
+ eor w0,w0,w11,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w22,w23 // a^b, b^c in next round
+ eor w16,w16,w26,ror#25 // Sigma1(e)
+ eor w1,w1,w22,ror#13
+ add w21,w21,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w15,w15,w8,ror#19
+ eor w0,w0,w11,lsr#3 // sigma0(X[i+1])
+ add w21,w21,w16 // h+=Sigma1(e)
+ eor w28,w28,w23 // Maj(a,b,c)
+ eor w17,w1,w22,ror#22 // Sigma0(a)
+ eor w15,w15,w8,lsr#10 // sigma1(X[i+14])
+ add w10,w10,w3
+ add w25,w25,w21 // d+=h
+ add w21,w21,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w10,w10,w0
+ add w21,w21,w17 // h+=Sigma0(a)
+ add w10,w10,w15
+ ldr w15,[sp,#0]
+ str w2,[sp,#12]
+ ror w16,w25,#6
+ add w20,w20,w28 // h+=K[i]
+ ror w1,w12,#7
+ and w17,w26,w25
+ ror w0,w9,#17
+ bic w28,w27,w25
+ ror w2,w21,#2
+ add w20,w20,w10 // h+=X[i]
+ eor w16,w16,w25,ror#11
+ eor w1,w1,w12,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w21,w22 // a^b, b^c in next round
+ eor w16,w16,w25,ror#25 // Sigma1(e)
+ eor w2,w2,w21,ror#13
+ add w20,w20,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w0,w0,w9,ror#19
+ eor w1,w1,w12,lsr#3 // sigma0(X[i+1])
+ add w20,w20,w16 // h+=Sigma1(e)
+ eor w19,w19,w22 // Maj(a,b,c)
+ eor w17,w2,w21,ror#22 // Sigma0(a)
+ eor w0,w0,w9,lsr#10 // sigma1(X[i+14])
+ add w11,w11,w4
+ add w24,w24,w20 // d+=h
+ add w20,w20,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w11,w11,w1
+ add w20,w20,w17 // h+=Sigma0(a)
+ add w11,w11,w0
+ ldr w0,[sp,#4]
+ str w3,[sp,#0]
+ ror w16,w24,#6
+ add w27,w27,w19 // h+=K[i]
+ ror w2,w13,#7
+ and w17,w25,w24
+ ror w1,w10,#17
+ bic w19,w26,w24
+ ror w3,w20,#2
+ add w27,w27,w11 // h+=X[i]
+ eor w16,w16,w24,ror#11
+ eor w2,w2,w13,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w20,w21 // a^b, b^c in next round
+ eor w16,w16,w24,ror#25 // Sigma1(e)
+ eor w3,w3,w20,ror#13
+ add w27,w27,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w1,w1,w10,ror#19
+ eor w2,w2,w13,lsr#3 // sigma0(X[i+1])
+ add w27,w27,w16 // h+=Sigma1(e)
+ eor w28,w28,w21 // Maj(a,b,c)
+ eor w17,w3,w20,ror#22 // Sigma0(a)
+ eor w1,w1,w10,lsr#10 // sigma1(X[i+14])
+ add w12,w12,w5
+ add w23,w23,w27 // d+=h
+ add w27,w27,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w12,w12,w2
+ add w27,w27,w17 // h+=Sigma0(a)
+ add w12,w12,w1
+ ldr w1,[sp,#8]
+ str w4,[sp,#4]
+ ror w16,w23,#6
+ add w26,w26,w28 // h+=K[i]
+ ror w3,w14,#7
+ and w17,w24,w23
+ ror w2,w11,#17
+ bic w28,w25,w23
+ ror w4,w27,#2
+ add w26,w26,w12 // h+=X[i]
+ eor w16,w16,w23,ror#11
+ eor w3,w3,w14,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w27,w20 // a^b, b^c in next round
+ eor w16,w16,w23,ror#25 // Sigma1(e)
+ eor w4,w4,w27,ror#13
+ add w26,w26,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w2,w2,w11,ror#19
+ eor w3,w3,w14,lsr#3 // sigma0(X[i+1])
+ add w26,w26,w16 // h+=Sigma1(e)
+ eor w19,w19,w20 // Maj(a,b,c)
+ eor w17,w4,w27,ror#22 // Sigma0(a)
+ eor w2,w2,w11,lsr#10 // sigma1(X[i+14])
+ add w13,w13,w6
+ add w22,w22,w26 // d+=h
+ add w26,w26,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w13,w13,w3
+ add w26,w26,w17 // h+=Sigma0(a)
+ add w13,w13,w2
+ ldr w2,[sp,#12]
+ str w5,[sp,#8]
+ ror w16,w22,#6
+ add w25,w25,w19 // h+=K[i]
+ ror w4,w15,#7
+ and w17,w23,w22
+ ror w3,w12,#17
+ bic w19,w24,w22
+ ror w5,w26,#2
+ add w25,w25,w13 // h+=X[i]
+ eor w16,w16,w22,ror#11
+ eor w4,w4,w15,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w26,w27 // a^b, b^c in next round
+ eor w16,w16,w22,ror#25 // Sigma1(e)
+ eor w5,w5,w26,ror#13
+ add w25,w25,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w3,w3,w12,ror#19
+ eor w4,w4,w15,lsr#3 // sigma0(X[i+1])
+ add w25,w25,w16 // h+=Sigma1(e)
+ eor w28,w28,w27 // Maj(a,b,c)
+ eor w17,w5,w26,ror#22 // Sigma0(a)
+ eor w3,w3,w12,lsr#10 // sigma1(X[i+14])
+ add w14,w14,w7
+ add w21,w21,w25 // d+=h
+ add w25,w25,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w14,w14,w4
+ add w25,w25,w17 // h+=Sigma0(a)
+ add w14,w14,w3
+ ldr w3,[sp,#0]
+ str w6,[sp,#12]
+ ror w16,w21,#6
+ add w24,w24,w28 // h+=K[i]
+ ror w5,w0,#7
+ and w17,w22,w21
+ ror w4,w13,#17
+ bic w28,w23,w21
+ ror w6,w25,#2
+ add w24,w24,w14 // h+=X[i]
+ eor w16,w16,w21,ror#11
+ eor w5,w5,w0,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w25,w26 // a^b, b^c in next round
+ eor w16,w16,w21,ror#25 // Sigma1(e)
+ eor w6,w6,w25,ror#13
+ add w24,w24,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w4,w4,w13,ror#19
+ eor w5,w5,w0,lsr#3 // sigma0(X[i+1])
+ add w24,w24,w16 // h+=Sigma1(e)
+ eor w19,w19,w26 // Maj(a,b,c)
+ eor w17,w6,w25,ror#22 // Sigma0(a)
+ eor w4,w4,w13,lsr#10 // sigma1(X[i+14])
+ add w15,w15,w8
+ add w20,w20,w24 // d+=h
+ add w24,w24,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w15,w15,w5
+ add w24,w24,w17 // h+=Sigma0(a)
+ add w15,w15,w4
+ ldr w4,[sp,#4]
+ str w7,[sp,#0]
+ ror w16,w20,#6
+ add w23,w23,w19 // h+=K[i]
+ ror w6,w1,#7
+ and w17,w21,w20
+ ror w5,w14,#17
+ bic w19,w22,w20
+ ror w7,w24,#2
+ add w23,w23,w15 // h+=X[i]
+ eor w16,w16,w20,ror#11
+ eor w6,w6,w1,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w24,w25 // a^b, b^c in next round
+ eor w16,w16,w20,ror#25 // Sigma1(e)
+ eor w7,w7,w24,ror#13
+ add w23,w23,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w5,w5,w14,ror#19
+ eor w6,w6,w1,lsr#3 // sigma0(X[i+1])
+ add w23,w23,w16 // h+=Sigma1(e)
+ eor w28,w28,w25 // Maj(a,b,c)
+ eor w17,w7,w24,ror#22 // Sigma0(a)
+ eor w5,w5,w14,lsr#10 // sigma1(X[i+14])
+ add w0,w0,w9
+ add w27,w27,w23 // d+=h
+ add w23,w23,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w0,w0,w6
+ add w23,w23,w17 // h+=Sigma0(a)
+ add w0,w0,w5
+ ldr w5,[sp,#8]
+ str w8,[sp,#4]
+ ror w16,w27,#6
+ add w22,w22,w28 // h+=K[i]
+ ror w7,w2,#7
+ and w17,w20,w27
+ ror w6,w15,#17
+ bic w28,w21,w27
+ ror w8,w23,#2
+ add w22,w22,w0 // h+=X[i]
+ eor w16,w16,w27,ror#11
+ eor w7,w7,w2,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w23,w24 // a^b, b^c in next round
+ eor w16,w16,w27,ror#25 // Sigma1(e)
+ eor w8,w8,w23,ror#13
+ add w22,w22,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w6,w6,w15,ror#19
+ eor w7,w7,w2,lsr#3 // sigma0(X[i+1])
+ add w22,w22,w16 // h+=Sigma1(e)
+ eor w19,w19,w24 // Maj(a,b,c)
+ eor w17,w8,w23,ror#22 // Sigma0(a)
+ eor w6,w6,w15,lsr#10 // sigma1(X[i+14])
+ add w1,w1,w10
+ add w26,w26,w22 // d+=h
+ add w22,w22,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w1,w1,w7
+ add w22,w22,w17 // h+=Sigma0(a)
+ add w1,w1,w6
+ ldr w6,[sp,#12]
+ str w9,[sp,#8]
+ ror w16,w26,#6
+ add w21,w21,w19 // h+=K[i]
+ ror w8,w3,#7
+ and w17,w27,w26
+ ror w7,w0,#17
+ bic w19,w20,w26
+ ror w9,w22,#2
+ add w21,w21,w1 // h+=X[i]
+ eor w16,w16,w26,ror#11
+ eor w8,w8,w3,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w22,w23 // a^b, b^c in next round
+ eor w16,w16,w26,ror#25 // Sigma1(e)
+ eor w9,w9,w22,ror#13
+ add w21,w21,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w7,w7,w0,ror#19
+ eor w8,w8,w3,lsr#3 // sigma0(X[i+1])
+ add w21,w21,w16 // h+=Sigma1(e)
+ eor w28,w28,w23 // Maj(a,b,c)
+ eor w17,w9,w22,ror#22 // Sigma0(a)
+ eor w7,w7,w0,lsr#10 // sigma1(X[i+14])
+ add w2,w2,w11
+ add w25,w25,w21 // d+=h
+ add w21,w21,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w2,w2,w8
+ add w21,w21,w17 // h+=Sigma0(a)
+ add w2,w2,w7
+ ldr w7,[sp,#0]
+ str w10,[sp,#12]
+ ror w16,w25,#6
+ add w20,w20,w28 // h+=K[i]
+ ror w9,w4,#7
+ and w17,w26,w25
+ ror w8,w1,#17
+ bic w28,w27,w25
+ ror w10,w21,#2
+ add w20,w20,w2 // h+=X[i]
+ eor w16,w16,w25,ror#11
+ eor w9,w9,w4,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w21,w22 // a^b, b^c in next round
+ eor w16,w16,w25,ror#25 // Sigma1(e)
+ eor w10,w10,w21,ror#13
+ add w20,w20,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w8,w8,w1,ror#19
+ eor w9,w9,w4,lsr#3 // sigma0(X[i+1])
+ add w20,w20,w16 // h+=Sigma1(e)
+ eor w19,w19,w22 // Maj(a,b,c)
+ eor w17,w10,w21,ror#22 // Sigma0(a)
+ eor w8,w8,w1,lsr#10 // sigma1(X[i+14])
+ add w3,w3,w12
+ add w24,w24,w20 // d+=h
+ add w20,w20,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w3,w3,w9
+ add w20,w20,w17 // h+=Sigma0(a)
+ add w3,w3,w8
+ cbnz w19,.Loop_16_xx
+
+ ldp x0,x2,[x29,#96]
+ ldr x1,[x29,#112]
+ sub x30,x30,#260 // rewind
+
+ ldp w3,w4,[x0]
+ ldp w5,w6,[x0,#2*4]
+ add x1,x1,#14*4 // advance input pointer
+ ldp w7,w8,[x0,#4*4]
+ add w20,w20,w3
+ ldp w9,w10,[x0,#6*4]
+ add w21,w21,w4
+ add w22,w22,w5
+ add w23,w23,w6
+ stp w20,w21,[x0]
+ add w24,w24,w7
+ add w25,w25,w8
+ stp w22,w23,[x0,#2*4]
+ add w26,w26,w9
+ add w27,w27,w10
+ cmp x1,x2
+ stp w24,w25,[x0,#4*4]
+ stp w26,w27,[x0,#6*4]
+ b.ne .Loop
+
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#4*4
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#128
+.inst 0xd50323bf // autiasp
+ ret
+.size sha256_block_data_order,.-sha256_block_data_order
+
+.align 6
+.type .LK256,%object
+.LK256:
+.long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+.long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+.long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+.long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+.long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+.long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+.long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+.long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+.long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+.long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+.long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+.long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+.long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+.long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+.long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+.long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+.long 0 //terminator
+.size .LK256,.-.LK256
+.byte 83,72,65,50,53,54,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 2
+.align 2
+#ifndef __KERNEL__
+.type sha256_block_armv8,%function
+.align 6
+sha256_block_armv8:
+.Lv8_entry:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ld1 {v0.4s,v1.4s},[x0]
+ adr x3,.LK256
+
+.Loop_hw:
+ ld1 {v4.16b,v5.16b,v6.16b,v7.16b},[x1],#64
+ sub x2,x2,#1
+ ld1 {v16.4s},[x3],#16
+ rev32 v4.16b,v4.16b
+ rev32 v5.16b,v5.16b
+ rev32 v6.16b,v6.16b
+ rev32 v7.16b,v7.16b
+ orr v18.16b,v0.16b,v0.16b // offload
+ orr v19.16b,v1.16b,v1.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v4.4s
+.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v5.4s
+.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v6.4s
+.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v7.4s
+.inst 0x5e282887 //sha256su0 v7.16b,v4.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v4.4s
+.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v5.4s
+.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v6.4s
+.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v7.4s
+.inst 0x5e282887 //sha256su0 v7.16b,v4.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v4.4s
+.inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+.inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v5.4s
+.inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+.inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v6.4s
+.inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+.inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v7.4s
+.inst 0x5e282887 //sha256su0 v7.16b,v4.16b
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+.inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v4.4s
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v5.4s
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+
+ ld1 {v17.4s},[x3]
+ add v16.4s,v16.4s,v6.4s
+ sub x3,x3,#64*4-16 // rewind
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+.inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+
+ add v17.4s,v17.4s,v7.4s
+ orr v2.16b,v0.16b,v0.16b
+.inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+.inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+
+ add v0.4s,v0.4s,v18.4s
+ add v1.4s,v1.4s,v19.4s
+
+ cbnz x2,.Loop_hw
+
+ st1 {v0.4s,v1.4s},[x0]
+
+ ldr x29,[sp],#16
+ ret
+.size sha256_block_armv8,.-sha256_block_armv8
+#endif
+#ifdef __KERNEL__
+.globl sha256_block_neon
+#endif
+.type sha256_block_neon,%function
+.align 4
+sha256_block_neon:
+.Lneon_entry:
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ sub sp,sp,#16*4
+
+ adr x16,.LK256
+ add x2,x1,x2,lsl#6 // len to point at the end of inp
+
+ ld1 {v0.16b},[x1], #16
+ ld1 {v1.16b},[x1], #16
+ ld1 {v2.16b},[x1], #16
+ ld1 {v3.16b},[x1], #16
+ ld1 {v4.4s},[x16], #16
+ ld1 {v5.4s},[x16], #16
+ ld1 {v6.4s},[x16], #16
+ ld1 {v7.4s},[x16], #16
+ rev32 v0.16b,v0.16b // yes, even on
+ rev32 v1.16b,v1.16b // big-endian
+ rev32 v2.16b,v2.16b
+ rev32 v3.16b,v3.16b
+ mov x17,sp
+ add v4.4s,v4.4s,v0.4s
+ add v5.4s,v5.4s,v1.4s
+ add v6.4s,v6.4s,v2.4s
+ st1 {v4.4s,v5.4s},[x17], #32
+ add v7.4s,v7.4s,v3.4s
+ st1 {v6.4s,v7.4s},[x17]
+ sub x17,x17,#32
+
+ ldp w3,w4,[x0]
+ ldp w5,w6,[x0,#8]
+ ldp w7,w8,[x0,#16]
+ ldp w9,w10,[x0,#24]
+ ldr w12,[sp,#0]
+ mov w13,wzr
+ eor w14,w4,w5
+ mov w15,wzr
+ b .L_00_48
+
+.align 4
+.L_00_48:
+ ext v4.16b,v0.16b,v1.16b,#4
+ add w10,w10,w12
+ add w3,w3,w15
+ and w12,w8,w7
+ bic w15,w9,w7
+ ext v7.16b,v2.16b,v3.16b,#4
+ eor w11,w7,w7,ror#5
+ add w3,w3,w13
+ mov d19,v3.d[1]
+ orr w12,w12,w15
+ eor w11,w11,w7,ror#19
+ ushr v6.4s,v4.4s,#7
+ eor w15,w3,w3,ror#11
+ ushr v5.4s,v4.4s,#3
+ add w10,w10,w12
+ add v0.4s,v0.4s,v7.4s
+ ror w11,w11,#6
+ sli v6.4s,v4.4s,#25
+ eor w13,w3,w4
+ eor w15,w15,w3,ror#20
+ ushr v7.4s,v4.4s,#18
+ add w10,w10,w11
+ ldr w12,[sp,#4]
+ and w14,w14,w13
+ eor v5.16b,v5.16b,v6.16b
+ ror w15,w15,#2
+ add w6,w6,w10
+ sli v7.4s,v4.4s,#14
+ eor w14,w14,w4
+ ushr v16.4s,v19.4s,#17
+ add w9,w9,w12
+ add w10,w10,w15
+ and w12,w7,w6
+ eor v5.16b,v5.16b,v7.16b
+ bic w15,w8,w6
+ eor w11,w6,w6,ror#5
+ sli v16.4s,v19.4s,#15
+ add w10,w10,w14
+ orr w12,w12,w15
+ ushr v17.4s,v19.4s,#10
+ eor w11,w11,w6,ror#19
+ eor w15,w10,w10,ror#11
+ ushr v7.4s,v19.4s,#19
+ add w9,w9,w12
+ ror w11,w11,#6
+ add v0.4s,v0.4s,v5.4s
+ eor w14,w10,w3
+ eor w15,w15,w10,ror#20
+ sli v7.4s,v19.4s,#13
+ add w9,w9,w11
+ ldr w12,[sp,#8]
+ and w13,w13,w14
+ eor v17.16b,v17.16b,v16.16b
+ ror w15,w15,#2
+ add w5,w5,w9
+ eor w13,w13,w3
+ eor v17.16b,v17.16b,v7.16b
+ add w8,w8,w12
+ add w9,w9,w15
+ and w12,w6,w5
+ add v0.4s,v0.4s,v17.4s
+ bic w15,w7,w5
+ eor w11,w5,w5,ror#5
+ add w9,w9,w13
+ ushr v18.4s,v0.4s,#17
+ orr w12,w12,w15
+ ushr v19.4s,v0.4s,#10
+ eor w11,w11,w5,ror#19
+ eor w15,w9,w9,ror#11
+ sli v18.4s,v0.4s,#15
+ add w8,w8,w12
+ ushr v17.4s,v0.4s,#19
+ ror w11,w11,#6
+ eor w13,w9,w10
+ eor v19.16b,v19.16b,v18.16b
+ eor w15,w15,w9,ror#20
+ add w8,w8,w11
+ sli v17.4s,v0.4s,#13
+ ldr w12,[sp,#12]
+ and w14,w14,w13
+ ror w15,w15,#2
+ ld1 {v4.4s},[x16], #16
+ add w4,w4,w8
+ eor v19.16b,v19.16b,v17.16b
+ eor w14,w14,w10
+ eor v17.16b,v17.16b,v17.16b
+ add w7,w7,w12
+ add w8,w8,w15
+ and w12,w5,w4
+ mov v17.d[1],v19.d[0]
+ bic w15,w6,w4
+ eor w11,w4,w4,ror#5
+ add w8,w8,w14
+ add v0.4s,v0.4s,v17.4s
+ orr w12,w12,w15
+ eor w11,w11,w4,ror#19
+ eor w15,w8,w8,ror#11
+ add v4.4s,v4.4s,v0.4s
+ add w7,w7,w12
+ ror w11,w11,#6
+ eor w14,w8,w9
+ eor w15,w15,w8,ror#20
+ add w7,w7,w11
+ ldr w12,[sp,#16]
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w3,w3,w7
+ eor w13,w13,w9
+ st1 {v4.4s},[x17], #16
+ ext v4.16b,v1.16b,v2.16b,#4
+ add w6,w6,w12
+ add w7,w7,w15
+ and w12,w4,w3
+ bic w15,w5,w3
+ ext v7.16b,v3.16b,v0.16b,#4
+ eor w11,w3,w3,ror#5
+ add w7,w7,w13
+ mov d19,v0.d[1]
+ orr w12,w12,w15
+ eor w11,w11,w3,ror#19
+ ushr v6.4s,v4.4s,#7
+ eor w15,w7,w7,ror#11
+ ushr v5.4s,v4.4s,#3
+ add w6,w6,w12
+ add v1.4s,v1.4s,v7.4s
+ ror w11,w11,#6
+ sli v6.4s,v4.4s,#25
+ eor w13,w7,w8
+ eor w15,w15,w7,ror#20
+ ushr v7.4s,v4.4s,#18
+ add w6,w6,w11
+ ldr w12,[sp,#20]
+ and w14,w14,w13
+ eor v5.16b,v5.16b,v6.16b
+ ror w15,w15,#2
+ add w10,w10,w6
+ sli v7.4s,v4.4s,#14
+ eor w14,w14,w8
+ ushr v16.4s,v19.4s,#17
+ add w5,w5,w12
+ add w6,w6,w15
+ and w12,w3,w10
+ eor v5.16b,v5.16b,v7.16b
+ bic w15,w4,w10
+ eor w11,w10,w10,ror#5
+ sli v16.4s,v19.4s,#15
+ add w6,w6,w14
+ orr w12,w12,w15
+ ushr v17.4s,v19.4s,#10
+ eor w11,w11,w10,ror#19
+ eor w15,w6,w6,ror#11
+ ushr v7.4s,v19.4s,#19
+ add w5,w5,w12
+ ror w11,w11,#6
+ add v1.4s,v1.4s,v5.4s
+ eor w14,w6,w7
+ eor w15,w15,w6,ror#20
+ sli v7.4s,v19.4s,#13
+ add w5,w5,w11
+ ldr w12,[sp,#24]
+ and w13,w13,w14
+ eor v17.16b,v17.16b,v16.16b
+ ror w15,w15,#2
+ add w9,w9,w5
+ eor w13,w13,w7
+ eor v17.16b,v17.16b,v7.16b
+ add w4,w4,w12
+ add w5,w5,w15
+ and w12,w10,w9
+ add v1.4s,v1.4s,v17.4s
+ bic w15,w3,w9
+ eor w11,w9,w9,ror#5
+ add w5,w5,w13
+ ushr v18.4s,v1.4s,#17
+ orr w12,w12,w15
+ ushr v19.4s,v1.4s,#10
+ eor w11,w11,w9,ror#19
+ eor w15,w5,w5,ror#11
+ sli v18.4s,v1.4s,#15
+ add w4,w4,w12
+ ushr v17.4s,v1.4s,#19
+ ror w11,w11,#6
+ eor w13,w5,w6
+ eor v19.16b,v19.16b,v18.16b
+ eor w15,w15,w5,ror#20
+ add w4,w4,w11
+ sli v17.4s,v1.4s,#13
+ ldr w12,[sp,#28]
+ and w14,w14,w13
+ ror w15,w15,#2
+ ld1 {v4.4s},[x16], #16
+ add w8,w8,w4
+ eor v19.16b,v19.16b,v17.16b
+ eor w14,w14,w6
+ eor v17.16b,v17.16b,v17.16b
+ add w3,w3,w12
+ add w4,w4,w15
+ and w12,w9,w8
+ mov v17.d[1],v19.d[0]
+ bic w15,w10,w8
+ eor w11,w8,w8,ror#5
+ add w4,w4,w14
+ add v1.4s,v1.4s,v17.4s
+ orr w12,w12,w15
+ eor w11,w11,w8,ror#19
+ eor w15,w4,w4,ror#11
+ add v4.4s,v4.4s,v1.4s
+ add w3,w3,w12
+ ror w11,w11,#6
+ eor w14,w4,w5
+ eor w15,w15,w4,ror#20
+ add w3,w3,w11
+ ldr w12,[sp,#32]
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w7,w7,w3
+ eor w13,w13,w5
+ st1 {v4.4s},[x17], #16
+ ext v4.16b,v2.16b,v3.16b,#4
+ add w10,w10,w12
+ add w3,w3,w15
+ and w12,w8,w7
+ bic w15,w9,w7
+ ext v7.16b,v0.16b,v1.16b,#4
+ eor w11,w7,w7,ror#5
+ add w3,w3,w13
+ mov d19,v1.d[1]
+ orr w12,w12,w15
+ eor w11,w11,w7,ror#19
+ ushr v6.4s,v4.4s,#7
+ eor w15,w3,w3,ror#11
+ ushr v5.4s,v4.4s,#3
+ add w10,w10,w12
+ add v2.4s,v2.4s,v7.4s
+ ror w11,w11,#6
+ sli v6.4s,v4.4s,#25
+ eor w13,w3,w4
+ eor w15,w15,w3,ror#20
+ ushr v7.4s,v4.4s,#18
+ add w10,w10,w11
+ ldr w12,[sp,#36]
+ and w14,w14,w13
+ eor v5.16b,v5.16b,v6.16b
+ ror w15,w15,#2
+ add w6,w6,w10
+ sli v7.4s,v4.4s,#14
+ eor w14,w14,w4
+ ushr v16.4s,v19.4s,#17
+ add w9,w9,w12
+ add w10,w10,w15
+ and w12,w7,w6
+ eor v5.16b,v5.16b,v7.16b
+ bic w15,w8,w6
+ eor w11,w6,w6,ror#5
+ sli v16.4s,v19.4s,#15
+ add w10,w10,w14
+ orr w12,w12,w15
+ ushr v17.4s,v19.4s,#10
+ eor w11,w11,w6,ror#19
+ eor w15,w10,w10,ror#11
+ ushr v7.4s,v19.4s,#19
+ add w9,w9,w12
+ ror w11,w11,#6
+ add v2.4s,v2.4s,v5.4s
+ eor w14,w10,w3
+ eor w15,w15,w10,ror#20
+ sli v7.4s,v19.4s,#13
+ add w9,w9,w11
+ ldr w12,[sp,#40]
+ and w13,w13,w14
+ eor v17.16b,v17.16b,v16.16b
+ ror w15,w15,#2
+ add w5,w5,w9
+ eor w13,w13,w3
+ eor v17.16b,v17.16b,v7.16b
+ add w8,w8,w12
+ add w9,w9,w15
+ and w12,w6,w5
+ add v2.4s,v2.4s,v17.4s
+ bic w15,w7,w5
+ eor w11,w5,w5,ror#5
+ add w9,w9,w13
+ ushr v18.4s,v2.4s,#17
+ orr w12,w12,w15
+ ushr v19.4s,v2.4s,#10
+ eor w11,w11,w5,ror#19
+ eor w15,w9,w9,ror#11
+ sli v18.4s,v2.4s,#15
+ add w8,w8,w12
+ ushr v17.4s,v2.4s,#19
+ ror w11,w11,#6
+ eor w13,w9,w10
+ eor v19.16b,v19.16b,v18.16b
+ eor w15,w15,w9,ror#20
+ add w8,w8,w11
+ sli v17.4s,v2.4s,#13
+ ldr w12,[sp,#44]
+ and w14,w14,w13
+ ror w15,w15,#2
+ ld1 {v4.4s},[x16], #16
+ add w4,w4,w8
+ eor v19.16b,v19.16b,v17.16b
+ eor w14,w14,w10
+ eor v17.16b,v17.16b,v17.16b
+ add w7,w7,w12
+ add w8,w8,w15
+ and w12,w5,w4
+ mov v17.d[1],v19.d[0]
+ bic w15,w6,w4
+ eor w11,w4,w4,ror#5
+ add w8,w8,w14
+ add v2.4s,v2.4s,v17.4s
+ orr w12,w12,w15
+ eor w11,w11,w4,ror#19
+ eor w15,w8,w8,ror#11
+ add v4.4s,v4.4s,v2.4s
+ add w7,w7,w12
+ ror w11,w11,#6
+ eor w14,w8,w9
+ eor w15,w15,w8,ror#20
+ add w7,w7,w11
+ ldr w12,[sp,#48]
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w3,w3,w7
+ eor w13,w13,w9
+ st1 {v4.4s},[x17], #16
+ ext v4.16b,v3.16b,v0.16b,#4
+ add w6,w6,w12
+ add w7,w7,w15
+ and w12,w4,w3
+ bic w15,w5,w3
+ ext v7.16b,v1.16b,v2.16b,#4
+ eor w11,w3,w3,ror#5
+ add w7,w7,w13
+ mov d19,v2.d[1]
+ orr w12,w12,w15
+ eor w11,w11,w3,ror#19
+ ushr v6.4s,v4.4s,#7
+ eor w15,w7,w7,ror#11
+ ushr v5.4s,v4.4s,#3
+ add w6,w6,w12
+ add v3.4s,v3.4s,v7.4s
+ ror w11,w11,#6
+ sli v6.4s,v4.4s,#25
+ eor w13,w7,w8
+ eor w15,w15,w7,ror#20
+ ushr v7.4s,v4.4s,#18
+ add w6,w6,w11
+ ldr w12,[sp,#52]
+ and w14,w14,w13
+ eor v5.16b,v5.16b,v6.16b
+ ror w15,w15,#2
+ add w10,w10,w6
+ sli v7.4s,v4.4s,#14
+ eor w14,w14,w8
+ ushr v16.4s,v19.4s,#17
+ add w5,w5,w12
+ add w6,w6,w15
+ and w12,w3,w10
+ eor v5.16b,v5.16b,v7.16b
+ bic w15,w4,w10
+ eor w11,w10,w10,ror#5
+ sli v16.4s,v19.4s,#15
+ add w6,w6,w14
+ orr w12,w12,w15
+ ushr v17.4s,v19.4s,#10
+ eor w11,w11,w10,ror#19
+ eor w15,w6,w6,ror#11
+ ushr v7.4s,v19.4s,#19
+ add w5,w5,w12
+ ror w11,w11,#6
+ add v3.4s,v3.4s,v5.4s
+ eor w14,w6,w7
+ eor w15,w15,w6,ror#20
+ sli v7.4s,v19.4s,#13
+ add w5,w5,w11
+ ldr w12,[sp,#56]
+ and w13,w13,w14
+ eor v17.16b,v17.16b,v16.16b
+ ror w15,w15,#2
+ add w9,w9,w5
+ eor w13,w13,w7
+ eor v17.16b,v17.16b,v7.16b
+ add w4,w4,w12
+ add w5,w5,w15
+ and w12,w10,w9
+ add v3.4s,v3.4s,v17.4s
+ bic w15,w3,w9
+ eor w11,w9,w9,ror#5
+ add w5,w5,w13
+ ushr v18.4s,v3.4s,#17
+ orr w12,w12,w15
+ ushr v19.4s,v3.4s,#10
+ eor w11,w11,w9,ror#19
+ eor w15,w5,w5,ror#11
+ sli v18.4s,v3.4s,#15
+ add w4,w4,w12
+ ushr v17.4s,v3.4s,#19
+ ror w11,w11,#6
+ eor w13,w5,w6
+ eor v19.16b,v19.16b,v18.16b
+ eor w15,w15,w5,ror#20
+ add w4,w4,w11
+ sli v17.4s,v3.4s,#13
+ ldr w12,[sp,#60]
+ and w14,w14,w13
+ ror w15,w15,#2
+ ld1 {v4.4s},[x16], #16
+ add w8,w8,w4
+ eor v19.16b,v19.16b,v17.16b
+ eor w14,w14,w6
+ eor v17.16b,v17.16b,v17.16b
+ add w3,w3,w12
+ add w4,w4,w15
+ and w12,w9,w8
+ mov v17.d[1],v19.d[0]
+ bic w15,w10,w8
+ eor w11,w8,w8,ror#5
+ add w4,w4,w14
+ add v3.4s,v3.4s,v17.4s
+ orr w12,w12,w15
+ eor w11,w11,w8,ror#19
+ eor w15,w4,w4,ror#11
+ add v4.4s,v4.4s,v3.4s
+ add w3,w3,w12
+ ror w11,w11,#6
+ eor w14,w4,w5
+ eor w15,w15,w4,ror#20
+ add w3,w3,w11
+ ldr w12,[x16]
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w7,w7,w3
+ eor w13,w13,w5
+ st1 {v4.4s},[x17], #16
+ cmp w12,#0 // check for K256 terminator
+ ldr w12,[sp,#0]
+ sub x17,x17,#64
+ bne .L_00_48
+
+ sub x16,x16,#256 // rewind x16
+ cmp x1,x2
+ mov x17, #64
+ csel x17, x17, xzr, eq
+ sub x1,x1,x17 // avoid SEGV
+ mov x17,sp
+ add w10,w10,w12
+ add w3,w3,w15
+ and w12,w8,w7
+ ld1 {v0.16b},[x1],#16
+ bic w15,w9,w7
+ eor w11,w7,w7,ror#5
+ ld1 {v4.4s},[x16],#16
+ add w3,w3,w13
+ orr w12,w12,w15
+ eor w11,w11,w7,ror#19
+ eor w15,w3,w3,ror#11
+ rev32 v0.16b,v0.16b
+ add w10,w10,w12
+ ror w11,w11,#6
+ eor w13,w3,w4
+ eor w15,w15,w3,ror#20
+ add v4.4s,v4.4s,v0.4s
+ add w10,w10,w11
+ ldr w12,[sp,#4]
+ and w14,w14,w13
+ ror w15,w15,#2
+ add w6,w6,w10
+ eor w14,w14,w4
+ add w9,w9,w12
+ add w10,w10,w15
+ and w12,w7,w6
+ bic w15,w8,w6
+ eor w11,w6,w6,ror#5
+ add w10,w10,w14
+ orr w12,w12,w15
+ eor w11,w11,w6,ror#19
+ eor w15,w10,w10,ror#11
+ add w9,w9,w12
+ ror w11,w11,#6
+ eor w14,w10,w3
+ eor w15,w15,w10,ror#20
+ add w9,w9,w11
+ ldr w12,[sp,#8]
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w5,w5,w9
+ eor w13,w13,w3
+ add w8,w8,w12
+ add w9,w9,w15
+ and w12,w6,w5
+ bic w15,w7,w5
+ eor w11,w5,w5,ror#5
+ add w9,w9,w13
+ orr w12,w12,w15
+ eor w11,w11,w5,ror#19
+ eor w15,w9,w9,ror#11
+ add w8,w8,w12
+ ror w11,w11,#6
+ eor w13,w9,w10
+ eor w15,w15,w9,ror#20
+ add w8,w8,w11
+ ldr w12,[sp,#12]
+ and w14,w14,w13
+ ror w15,w15,#2
+ add w4,w4,w8
+ eor w14,w14,w10
+ add w7,w7,w12
+ add w8,w8,w15
+ and w12,w5,w4
+ bic w15,w6,w4
+ eor w11,w4,w4,ror#5
+ add w8,w8,w14
+ orr w12,w12,w15
+ eor w11,w11,w4,ror#19
+ eor w15,w8,w8,ror#11
+ add w7,w7,w12
+ ror w11,w11,#6
+ eor w14,w8,w9
+ eor w15,w15,w8,ror#20
+ add w7,w7,w11
+ ldr w12,[sp,#16]
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w3,w3,w7
+ eor w13,w13,w9
+ st1 {v4.4s},[x17], #16
+ add w6,w6,w12
+ add w7,w7,w15
+ and w12,w4,w3
+ ld1 {v1.16b},[x1],#16
+ bic w15,w5,w3
+ eor w11,w3,w3,ror#5
+ ld1 {v4.4s},[x16],#16
+ add w7,w7,w13
+ orr w12,w12,w15
+ eor w11,w11,w3,ror#19
+ eor w15,w7,w7,ror#11
+ rev32 v1.16b,v1.16b
+ add w6,w6,w12
+ ror w11,w11,#6
+ eor w13,w7,w8
+ eor w15,w15,w7,ror#20
+ add v4.4s,v4.4s,v1.4s
+ add w6,w6,w11
+ ldr w12,[sp,#20]
+ and w14,w14,w13
+ ror w15,w15,#2
+ add w10,w10,w6
+ eor w14,w14,w8
+ add w5,w5,w12
+ add w6,w6,w15
+ and w12,w3,w10
+ bic w15,w4,w10
+ eor w11,w10,w10,ror#5
+ add w6,w6,w14
+ orr w12,w12,w15
+ eor w11,w11,w10,ror#19
+ eor w15,w6,w6,ror#11
+ add w5,w5,w12
+ ror w11,w11,#6
+ eor w14,w6,w7
+ eor w15,w15,w6,ror#20
+ add w5,w5,w11
+ ldr w12,[sp,#24]
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w9,w9,w5
+ eor w13,w13,w7
+ add w4,w4,w12
+ add w5,w5,w15
+ and w12,w10,w9
+ bic w15,w3,w9
+ eor w11,w9,w9,ror#5
+ add w5,w5,w13
+ orr w12,w12,w15
+ eor w11,w11,w9,ror#19
+ eor w15,w5,w5,ror#11
+ add w4,w4,w12
+ ror w11,w11,#6
+ eor w13,w5,w6
+ eor w15,w15,w5,ror#20
+ add w4,w4,w11
+ ldr w12,[sp,#28]
+ and w14,w14,w13
+ ror w15,w15,#2
+ add w8,w8,w4
+ eor w14,w14,w6
+ add w3,w3,w12
+ add w4,w4,w15
+ and w12,w9,w8
+ bic w15,w10,w8
+ eor w11,w8,w8,ror#5
+ add w4,w4,w14
+ orr w12,w12,w15
+ eor w11,w11,w8,ror#19
+ eor w15,w4,w4,ror#11
+ add w3,w3,w12
+ ror w11,w11,#6
+ eor w14,w4,w5
+ eor w15,w15,w4,ror#20
+ add w3,w3,w11
+ ldr w12,[sp,#32]
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w7,w7,w3
+ eor w13,w13,w5
+ st1 {v4.4s},[x17], #16
+ add w10,w10,w12
+ add w3,w3,w15
+ and w12,w8,w7
+ ld1 {v2.16b},[x1],#16
+ bic w15,w9,w7
+ eor w11,w7,w7,ror#5
+ ld1 {v4.4s},[x16],#16
+ add w3,w3,w13
+ orr w12,w12,w15
+ eor w11,w11,w7,ror#19
+ eor w15,w3,w3,ror#11
+ rev32 v2.16b,v2.16b
+ add w10,w10,w12
+ ror w11,w11,#6
+ eor w13,w3,w4
+ eor w15,w15,w3,ror#20
+ add v4.4s,v4.4s,v2.4s
+ add w10,w10,w11
+ ldr w12,[sp,#36]
+ and w14,w14,w13
+ ror w15,w15,#2
+ add w6,w6,w10
+ eor w14,w14,w4
+ add w9,w9,w12
+ add w10,w10,w15
+ and w12,w7,w6
+ bic w15,w8,w6
+ eor w11,w6,w6,ror#5
+ add w10,w10,w14
+ orr w12,w12,w15
+ eor w11,w11,w6,ror#19
+ eor w15,w10,w10,ror#11
+ add w9,w9,w12
+ ror w11,w11,#6
+ eor w14,w10,w3
+ eor w15,w15,w10,ror#20
+ add w9,w9,w11
+ ldr w12,[sp,#40]
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w5,w5,w9
+ eor w13,w13,w3
+ add w8,w8,w12
+ add w9,w9,w15
+ and w12,w6,w5
+ bic w15,w7,w5
+ eor w11,w5,w5,ror#5
+ add w9,w9,w13
+ orr w12,w12,w15
+ eor w11,w11,w5,ror#19
+ eor w15,w9,w9,ror#11
+ add w8,w8,w12
+ ror w11,w11,#6
+ eor w13,w9,w10
+ eor w15,w15,w9,ror#20
+ add w8,w8,w11
+ ldr w12,[sp,#44]
+ and w14,w14,w13
+ ror w15,w15,#2
+ add w4,w4,w8
+ eor w14,w14,w10
+ add w7,w7,w12
+ add w8,w8,w15
+ and w12,w5,w4
+ bic w15,w6,w4
+ eor w11,w4,w4,ror#5
+ add w8,w8,w14
+ orr w12,w12,w15
+ eor w11,w11,w4,ror#19
+ eor w15,w8,w8,ror#11
+ add w7,w7,w12
+ ror w11,w11,#6
+ eor w14,w8,w9
+ eor w15,w15,w8,ror#20
+ add w7,w7,w11
+ ldr w12,[sp,#48]
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w3,w3,w7
+ eor w13,w13,w9
+ st1 {v4.4s},[x17], #16
+ add w6,w6,w12
+ add w7,w7,w15
+ and w12,w4,w3
+ ld1 {v3.16b},[x1],#16
+ bic w15,w5,w3
+ eor w11,w3,w3,ror#5
+ ld1 {v4.4s},[x16],#16
+ add w7,w7,w13
+ orr w12,w12,w15
+ eor w11,w11,w3,ror#19
+ eor w15,w7,w7,ror#11
+ rev32 v3.16b,v3.16b
+ add w6,w6,w12
+ ror w11,w11,#6
+ eor w13,w7,w8
+ eor w15,w15,w7,ror#20
+ add v4.4s,v4.4s,v3.4s
+ add w6,w6,w11
+ ldr w12,[sp,#52]
+ and w14,w14,w13
+ ror w15,w15,#2
+ add w10,w10,w6
+ eor w14,w14,w8
+ add w5,w5,w12
+ add w6,w6,w15
+ and w12,w3,w10
+ bic w15,w4,w10
+ eor w11,w10,w10,ror#5
+ add w6,w6,w14
+ orr w12,w12,w15
+ eor w11,w11,w10,ror#19
+ eor w15,w6,w6,ror#11
+ add w5,w5,w12
+ ror w11,w11,#6
+ eor w14,w6,w7
+ eor w15,w15,w6,ror#20
+ add w5,w5,w11
+ ldr w12,[sp,#56]
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w9,w9,w5
+ eor w13,w13,w7
+ add w4,w4,w12
+ add w5,w5,w15
+ and w12,w10,w9
+ bic w15,w3,w9
+ eor w11,w9,w9,ror#5
+ add w5,w5,w13
+ orr w12,w12,w15
+ eor w11,w11,w9,ror#19
+ eor w15,w5,w5,ror#11
+ add w4,w4,w12
+ ror w11,w11,#6
+ eor w13,w5,w6
+ eor w15,w15,w5,ror#20
+ add w4,w4,w11
+ ldr w12,[sp,#60]
+ and w14,w14,w13
+ ror w15,w15,#2
+ add w8,w8,w4
+ eor w14,w14,w6
+ add w3,w3,w12
+ add w4,w4,w15
+ and w12,w9,w8
+ bic w15,w10,w8
+ eor w11,w8,w8,ror#5
+ add w4,w4,w14
+ orr w12,w12,w15
+ eor w11,w11,w8,ror#19
+ eor w15,w4,w4,ror#11
+ add w3,w3,w12
+ ror w11,w11,#6
+ eor w14,w4,w5
+ eor w15,w15,w4,ror#20
+ add w3,w3,w11
+ and w13,w13,w14
+ ror w15,w15,#2
+ add w7,w7,w3
+ eor w13,w13,w5
+ st1 {v4.4s},[x17], #16
+ add w3,w3,w15 // h+=Sigma0(a) from the past
+ ldp w11,w12,[x0,#0]
+ add w3,w3,w13 // h+=Maj(a,b,c) from the past
+ ldp w13,w14,[x0,#8]
+ add w3,w3,w11 // accumulate
+ add w4,w4,w12
+ ldp w11,w12,[x0,#16]
+ add w5,w5,w13
+ add w6,w6,w14
+ ldp w13,w14,[x0,#24]
+ add w7,w7,w11
+ add w8,w8,w12
+ ldr w12,[sp,#0]
+ stp w3,w4,[x0,#0]
+ add w9,w9,w13
+ mov w13,wzr
+ stp w5,w6,[x0,#8]
+ add w10,w10,w14
+ stp w7,w8,[x0,#16]
+ eor w14,w4,w5
+ stp w9,w10,[x0,#24]
+ mov w15,wzr
+ mov x17,sp
+ b.ne .L_00_48
+
+ ldr x29,[x29]
+ add sp,sp,#16*4+16
+ ret
+.size sha256_block_neon,.-sha256_block_neon
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha512-armv8.S b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha512-armv8.S
new file mode 100644
index 0000000..9c2cdfe
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/AARCH64-GCC/crypto/sha/sha512-armv8.S
@@ -0,0 +1,1555 @@
+// Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You may not use
+// this file except in compliance with the License. You can obtain a copy
+// in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+#ifndef __KERNEL__
+# include "arm_arch.h"
+
+.hidden OPENSSL_armcap_P
+#endif
+
+.text
+
+.globl sha512_block_data_order
+.type sha512_block_data_order,%function
+.align 6
+sha512_block_data_order:
+#ifndef __KERNEL__
+ adrp x16,OPENSSL_armcap_P
+ ldr w16,[x16,#:lo12:OPENSSL_armcap_P]
+ tst w16,#ARMV8_SHA512
+ b.ne .Lv8_entry
+#endif
+.inst 0xd503233f // paciasp
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ sub sp,sp,#4*8
+
+ ldp x20,x21,[x0] // load context
+ ldp x22,x23,[x0,#2*8]
+ ldp x24,x25,[x0,#4*8]
+ add x2,x1,x2,lsl#7 // end of input
+ ldp x26,x27,[x0,#6*8]
+ adr x30,.LK512
+ stp x0,x2,[x29,#96]
+
+.Loop:
+ ldp x3,x4,[x1],#2*8
+ ldr x19,[x30],#8 // *K++
+ eor x28,x21,x22 // magic seed
+ str x1,[x29,#112]
+#ifndef __AARCH64EB__
+ rev x3,x3 // 0
+#endif
+ ror x16,x24,#14
+ add x27,x27,x19 // h+=K[i]
+ eor x6,x24,x24,ror#23
+ and x17,x25,x24
+ bic x19,x26,x24
+ add x27,x27,x3 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x20,x21 // a^b, b^c in next round
+ eor x16,x16,x6,ror#18 // Sigma1(e)
+ ror x6,x20,#28
+ add x27,x27,x17 // h+=Ch(e,f,g)
+ eor x17,x20,x20,ror#5
+ add x27,x27,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x23,x23,x27 // d+=h
+ eor x28,x28,x21 // Maj(a,b,c)
+ eor x17,x6,x17,ror#34 // Sigma0(a)
+ add x27,x27,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x27,x27,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x4,x4 // 1
+#endif
+ ldp x5,x6,[x1],#2*8
+ add x27,x27,x17 // h+=Sigma0(a)
+ ror x16,x23,#14
+ add x26,x26,x28 // h+=K[i]
+ eor x7,x23,x23,ror#23
+ and x17,x24,x23
+ bic x28,x25,x23
+ add x26,x26,x4 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x27,x20 // a^b, b^c in next round
+ eor x16,x16,x7,ror#18 // Sigma1(e)
+ ror x7,x27,#28
+ add x26,x26,x17 // h+=Ch(e,f,g)
+ eor x17,x27,x27,ror#5
+ add x26,x26,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x22,x22,x26 // d+=h
+ eor x19,x19,x20 // Maj(a,b,c)
+ eor x17,x7,x17,ror#34 // Sigma0(a)
+ add x26,x26,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x26,x26,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x5,x5 // 2
+#endif
+ add x26,x26,x17 // h+=Sigma0(a)
+ ror x16,x22,#14
+ add x25,x25,x19 // h+=K[i]
+ eor x8,x22,x22,ror#23
+ and x17,x23,x22
+ bic x19,x24,x22
+ add x25,x25,x5 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x26,x27 // a^b, b^c in next round
+ eor x16,x16,x8,ror#18 // Sigma1(e)
+ ror x8,x26,#28
+ add x25,x25,x17 // h+=Ch(e,f,g)
+ eor x17,x26,x26,ror#5
+ add x25,x25,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x21,x21,x25 // d+=h
+ eor x28,x28,x27 // Maj(a,b,c)
+ eor x17,x8,x17,ror#34 // Sigma0(a)
+ add x25,x25,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x25,x25,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x6,x6 // 3
+#endif
+ ldp x7,x8,[x1],#2*8
+ add x25,x25,x17 // h+=Sigma0(a)
+ ror x16,x21,#14
+ add x24,x24,x28 // h+=K[i]
+ eor x9,x21,x21,ror#23
+ and x17,x22,x21
+ bic x28,x23,x21
+ add x24,x24,x6 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x25,x26 // a^b, b^c in next round
+ eor x16,x16,x9,ror#18 // Sigma1(e)
+ ror x9,x25,#28
+ add x24,x24,x17 // h+=Ch(e,f,g)
+ eor x17,x25,x25,ror#5
+ add x24,x24,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x20,x20,x24 // d+=h
+ eor x19,x19,x26 // Maj(a,b,c)
+ eor x17,x9,x17,ror#34 // Sigma0(a)
+ add x24,x24,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x24,x24,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x7,x7 // 4
+#endif
+ add x24,x24,x17 // h+=Sigma0(a)
+ ror x16,x20,#14
+ add x23,x23,x19 // h+=K[i]
+ eor x10,x20,x20,ror#23
+ and x17,x21,x20
+ bic x19,x22,x20
+ add x23,x23,x7 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x24,x25 // a^b, b^c in next round
+ eor x16,x16,x10,ror#18 // Sigma1(e)
+ ror x10,x24,#28
+ add x23,x23,x17 // h+=Ch(e,f,g)
+ eor x17,x24,x24,ror#5
+ add x23,x23,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x27,x27,x23 // d+=h
+ eor x28,x28,x25 // Maj(a,b,c)
+ eor x17,x10,x17,ror#34 // Sigma0(a)
+ add x23,x23,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x23,x23,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x8,x8 // 5
+#endif
+ ldp x9,x10,[x1],#2*8
+ add x23,x23,x17 // h+=Sigma0(a)
+ ror x16,x27,#14
+ add x22,x22,x28 // h+=K[i]
+ eor x11,x27,x27,ror#23
+ and x17,x20,x27
+ bic x28,x21,x27
+ add x22,x22,x8 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x23,x24 // a^b, b^c in next round
+ eor x16,x16,x11,ror#18 // Sigma1(e)
+ ror x11,x23,#28
+ add x22,x22,x17 // h+=Ch(e,f,g)
+ eor x17,x23,x23,ror#5
+ add x22,x22,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x26,x26,x22 // d+=h
+ eor x19,x19,x24 // Maj(a,b,c)
+ eor x17,x11,x17,ror#34 // Sigma0(a)
+ add x22,x22,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x22,x22,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x9,x9 // 6
+#endif
+ add x22,x22,x17 // h+=Sigma0(a)
+ ror x16,x26,#14
+ add x21,x21,x19 // h+=K[i]
+ eor x12,x26,x26,ror#23
+ and x17,x27,x26
+ bic x19,x20,x26
+ add x21,x21,x9 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x22,x23 // a^b, b^c in next round
+ eor x16,x16,x12,ror#18 // Sigma1(e)
+ ror x12,x22,#28
+ add x21,x21,x17 // h+=Ch(e,f,g)
+ eor x17,x22,x22,ror#5
+ add x21,x21,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x25,x25,x21 // d+=h
+ eor x28,x28,x23 // Maj(a,b,c)
+ eor x17,x12,x17,ror#34 // Sigma0(a)
+ add x21,x21,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x21,x21,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x10,x10 // 7
+#endif
+ ldp x11,x12,[x1],#2*8
+ add x21,x21,x17 // h+=Sigma0(a)
+ ror x16,x25,#14
+ add x20,x20,x28 // h+=K[i]
+ eor x13,x25,x25,ror#23
+ and x17,x26,x25
+ bic x28,x27,x25
+ add x20,x20,x10 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x21,x22 // a^b, b^c in next round
+ eor x16,x16,x13,ror#18 // Sigma1(e)
+ ror x13,x21,#28
+ add x20,x20,x17 // h+=Ch(e,f,g)
+ eor x17,x21,x21,ror#5
+ add x20,x20,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x24,x24,x20 // d+=h
+ eor x19,x19,x22 // Maj(a,b,c)
+ eor x17,x13,x17,ror#34 // Sigma0(a)
+ add x20,x20,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x20,x20,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x11,x11 // 8
+#endif
+ add x20,x20,x17 // h+=Sigma0(a)
+ ror x16,x24,#14
+ add x27,x27,x19 // h+=K[i]
+ eor x14,x24,x24,ror#23
+ and x17,x25,x24
+ bic x19,x26,x24
+ add x27,x27,x11 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x20,x21 // a^b, b^c in next round
+ eor x16,x16,x14,ror#18 // Sigma1(e)
+ ror x14,x20,#28
+ add x27,x27,x17 // h+=Ch(e,f,g)
+ eor x17,x20,x20,ror#5
+ add x27,x27,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x23,x23,x27 // d+=h
+ eor x28,x28,x21 // Maj(a,b,c)
+ eor x17,x14,x17,ror#34 // Sigma0(a)
+ add x27,x27,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x27,x27,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x12,x12 // 9
+#endif
+ ldp x13,x14,[x1],#2*8
+ add x27,x27,x17 // h+=Sigma0(a)
+ ror x16,x23,#14
+ add x26,x26,x28 // h+=K[i]
+ eor x15,x23,x23,ror#23
+ and x17,x24,x23
+ bic x28,x25,x23
+ add x26,x26,x12 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x27,x20 // a^b, b^c in next round
+ eor x16,x16,x15,ror#18 // Sigma1(e)
+ ror x15,x27,#28
+ add x26,x26,x17 // h+=Ch(e,f,g)
+ eor x17,x27,x27,ror#5
+ add x26,x26,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x22,x22,x26 // d+=h
+ eor x19,x19,x20 // Maj(a,b,c)
+ eor x17,x15,x17,ror#34 // Sigma0(a)
+ add x26,x26,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x26,x26,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x13,x13 // 10
+#endif
+ add x26,x26,x17 // h+=Sigma0(a)
+ ror x16,x22,#14
+ add x25,x25,x19 // h+=K[i]
+ eor x0,x22,x22,ror#23
+ and x17,x23,x22
+ bic x19,x24,x22
+ add x25,x25,x13 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x26,x27 // a^b, b^c in next round
+ eor x16,x16,x0,ror#18 // Sigma1(e)
+ ror x0,x26,#28
+ add x25,x25,x17 // h+=Ch(e,f,g)
+ eor x17,x26,x26,ror#5
+ add x25,x25,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x21,x21,x25 // d+=h
+ eor x28,x28,x27 // Maj(a,b,c)
+ eor x17,x0,x17,ror#34 // Sigma0(a)
+ add x25,x25,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x25,x25,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x14,x14 // 11
+#endif
+ ldp x15,x0,[x1],#2*8
+ add x25,x25,x17 // h+=Sigma0(a)
+ str x6,[sp,#24]
+ ror x16,x21,#14
+ add x24,x24,x28 // h+=K[i]
+ eor x6,x21,x21,ror#23
+ and x17,x22,x21
+ bic x28,x23,x21
+ add x24,x24,x14 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x25,x26 // a^b, b^c in next round
+ eor x16,x16,x6,ror#18 // Sigma1(e)
+ ror x6,x25,#28
+ add x24,x24,x17 // h+=Ch(e,f,g)
+ eor x17,x25,x25,ror#5
+ add x24,x24,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x20,x20,x24 // d+=h
+ eor x19,x19,x26 // Maj(a,b,c)
+ eor x17,x6,x17,ror#34 // Sigma0(a)
+ add x24,x24,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x24,x24,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x15,x15 // 12
+#endif
+ add x24,x24,x17 // h+=Sigma0(a)
+ str x7,[sp,#0]
+ ror x16,x20,#14
+ add x23,x23,x19 // h+=K[i]
+ eor x7,x20,x20,ror#23
+ and x17,x21,x20
+ bic x19,x22,x20
+ add x23,x23,x15 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x24,x25 // a^b, b^c in next round
+ eor x16,x16,x7,ror#18 // Sigma1(e)
+ ror x7,x24,#28
+ add x23,x23,x17 // h+=Ch(e,f,g)
+ eor x17,x24,x24,ror#5
+ add x23,x23,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x27,x27,x23 // d+=h
+ eor x28,x28,x25 // Maj(a,b,c)
+ eor x17,x7,x17,ror#34 // Sigma0(a)
+ add x23,x23,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x23,x23,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x0,x0 // 13
+#endif
+ ldp x1,x2,[x1]
+ add x23,x23,x17 // h+=Sigma0(a)
+ str x8,[sp,#8]
+ ror x16,x27,#14
+ add x22,x22,x28 // h+=K[i]
+ eor x8,x27,x27,ror#23
+ and x17,x20,x27
+ bic x28,x21,x27
+ add x22,x22,x0 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x23,x24 // a^b, b^c in next round
+ eor x16,x16,x8,ror#18 // Sigma1(e)
+ ror x8,x23,#28
+ add x22,x22,x17 // h+=Ch(e,f,g)
+ eor x17,x23,x23,ror#5
+ add x22,x22,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x26,x26,x22 // d+=h
+ eor x19,x19,x24 // Maj(a,b,c)
+ eor x17,x8,x17,ror#34 // Sigma0(a)
+ add x22,x22,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x22,x22,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x1,x1 // 14
+#endif
+ ldr x6,[sp,#24]
+ add x22,x22,x17 // h+=Sigma0(a)
+ str x9,[sp,#16]
+ ror x16,x26,#14
+ add x21,x21,x19 // h+=K[i]
+ eor x9,x26,x26,ror#23
+ and x17,x27,x26
+ bic x19,x20,x26
+ add x21,x21,x1 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x22,x23 // a^b, b^c in next round
+ eor x16,x16,x9,ror#18 // Sigma1(e)
+ ror x9,x22,#28
+ add x21,x21,x17 // h+=Ch(e,f,g)
+ eor x17,x22,x22,ror#5
+ add x21,x21,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x25,x25,x21 // d+=h
+ eor x28,x28,x23 // Maj(a,b,c)
+ eor x17,x9,x17,ror#34 // Sigma0(a)
+ add x21,x21,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x21,x21,x17 // h+=Sigma0(a)
+#ifndef __AARCH64EB__
+ rev x2,x2 // 15
+#endif
+ ldr x7,[sp,#0]
+ add x21,x21,x17 // h+=Sigma0(a)
+ str x10,[sp,#24]
+ ror x16,x25,#14
+ add x20,x20,x28 // h+=K[i]
+ ror x9,x4,#1
+ and x17,x26,x25
+ ror x8,x1,#19
+ bic x28,x27,x25
+ ror x10,x21,#28
+ add x20,x20,x2 // h+=X[i]
+ eor x16,x16,x25,ror#18
+ eor x9,x9,x4,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x21,x22 // a^b, b^c in next round
+ eor x16,x16,x25,ror#41 // Sigma1(e)
+ eor x10,x10,x21,ror#34
+ add x20,x20,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x8,x8,x1,ror#61
+ eor x9,x9,x4,lsr#7 // sigma0(X[i+1])
+ add x20,x20,x16 // h+=Sigma1(e)
+ eor x19,x19,x22 // Maj(a,b,c)
+ eor x17,x10,x21,ror#39 // Sigma0(a)
+ eor x8,x8,x1,lsr#6 // sigma1(X[i+14])
+ add x3,x3,x12
+ add x24,x24,x20 // d+=h
+ add x20,x20,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x3,x3,x9
+ add x20,x20,x17 // h+=Sigma0(a)
+ add x3,x3,x8
+.Loop_16_xx:
+ ldr x8,[sp,#8]
+ str x11,[sp,#0]
+ ror x16,x24,#14
+ add x27,x27,x19 // h+=K[i]
+ ror x10,x5,#1
+ and x17,x25,x24
+ ror x9,x2,#19
+ bic x19,x26,x24
+ ror x11,x20,#28
+ add x27,x27,x3 // h+=X[i]
+ eor x16,x16,x24,ror#18
+ eor x10,x10,x5,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x20,x21 // a^b, b^c in next round
+ eor x16,x16,x24,ror#41 // Sigma1(e)
+ eor x11,x11,x20,ror#34
+ add x27,x27,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x9,x9,x2,ror#61
+ eor x10,x10,x5,lsr#7 // sigma0(X[i+1])
+ add x27,x27,x16 // h+=Sigma1(e)
+ eor x28,x28,x21 // Maj(a,b,c)
+ eor x17,x11,x20,ror#39 // Sigma0(a)
+ eor x9,x9,x2,lsr#6 // sigma1(X[i+14])
+ add x4,x4,x13
+ add x23,x23,x27 // d+=h
+ add x27,x27,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x4,x4,x10
+ add x27,x27,x17 // h+=Sigma0(a)
+ add x4,x4,x9
+ ldr x9,[sp,#16]
+ str x12,[sp,#8]
+ ror x16,x23,#14
+ add x26,x26,x28 // h+=K[i]
+ ror x11,x6,#1
+ and x17,x24,x23
+ ror x10,x3,#19
+ bic x28,x25,x23
+ ror x12,x27,#28
+ add x26,x26,x4 // h+=X[i]
+ eor x16,x16,x23,ror#18
+ eor x11,x11,x6,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x27,x20 // a^b, b^c in next round
+ eor x16,x16,x23,ror#41 // Sigma1(e)
+ eor x12,x12,x27,ror#34
+ add x26,x26,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x10,x10,x3,ror#61
+ eor x11,x11,x6,lsr#7 // sigma0(X[i+1])
+ add x26,x26,x16 // h+=Sigma1(e)
+ eor x19,x19,x20 // Maj(a,b,c)
+ eor x17,x12,x27,ror#39 // Sigma0(a)
+ eor x10,x10,x3,lsr#6 // sigma1(X[i+14])
+ add x5,x5,x14
+ add x22,x22,x26 // d+=h
+ add x26,x26,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x5,x5,x11
+ add x26,x26,x17 // h+=Sigma0(a)
+ add x5,x5,x10
+ ldr x10,[sp,#24]
+ str x13,[sp,#16]
+ ror x16,x22,#14
+ add x25,x25,x19 // h+=K[i]
+ ror x12,x7,#1
+ and x17,x23,x22
+ ror x11,x4,#19
+ bic x19,x24,x22
+ ror x13,x26,#28
+ add x25,x25,x5 // h+=X[i]
+ eor x16,x16,x22,ror#18
+ eor x12,x12,x7,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x26,x27 // a^b, b^c in next round
+ eor x16,x16,x22,ror#41 // Sigma1(e)
+ eor x13,x13,x26,ror#34
+ add x25,x25,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x11,x11,x4,ror#61
+ eor x12,x12,x7,lsr#7 // sigma0(X[i+1])
+ add x25,x25,x16 // h+=Sigma1(e)
+ eor x28,x28,x27 // Maj(a,b,c)
+ eor x17,x13,x26,ror#39 // Sigma0(a)
+ eor x11,x11,x4,lsr#6 // sigma1(X[i+14])
+ add x6,x6,x15
+ add x21,x21,x25 // d+=h
+ add x25,x25,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x6,x6,x12
+ add x25,x25,x17 // h+=Sigma0(a)
+ add x6,x6,x11
+ ldr x11,[sp,#0]
+ str x14,[sp,#24]
+ ror x16,x21,#14
+ add x24,x24,x28 // h+=K[i]
+ ror x13,x8,#1
+ and x17,x22,x21
+ ror x12,x5,#19
+ bic x28,x23,x21
+ ror x14,x25,#28
+ add x24,x24,x6 // h+=X[i]
+ eor x16,x16,x21,ror#18
+ eor x13,x13,x8,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x25,x26 // a^b, b^c in next round
+ eor x16,x16,x21,ror#41 // Sigma1(e)
+ eor x14,x14,x25,ror#34
+ add x24,x24,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x12,x12,x5,ror#61
+ eor x13,x13,x8,lsr#7 // sigma0(X[i+1])
+ add x24,x24,x16 // h+=Sigma1(e)
+ eor x19,x19,x26 // Maj(a,b,c)
+ eor x17,x14,x25,ror#39 // Sigma0(a)
+ eor x12,x12,x5,lsr#6 // sigma1(X[i+14])
+ add x7,x7,x0
+ add x20,x20,x24 // d+=h
+ add x24,x24,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x7,x7,x13
+ add x24,x24,x17 // h+=Sigma0(a)
+ add x7,x7,x12
+ ldr x12,[sp,#8]
+ str x15,[sp,#0]
+ ror x16,x20,#14
+ add x23,x23,x19 // h+=K[i]
+ ror x14,x9,#1
+ and x17,x21,x20
+ ror x13,x6,#19
+ bic x19,x22,x20
+ ror x15,x24,#28
+ add x23,x23,x7 // h+=X[i]
+ eor x16,x16,x20,ror#18
+ eor x14,x14,x9,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x24,x25 // a^b, b^c in next round
+ eor x16,x16,x20,ror#41 // Sigma1(e)
+ eor x15,x15,x24,ror#34
+ add x23,x23,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x13,x13,x6,ror#61
+ eor x14,x14,x9,lsr#7 // sigma0(X[i+1])
+ add x23,x23,x16 // h+=Sigma1(e)
+ eor x28,x28,x25 // Maj(a,b,c)
+ eor x17,x15,x24,ror#39 // Sigma0(a)
+ eor x13,x13,x6,lsr#6 // sigma1(X[i+14])
+ add x8,x8,x1
+ add x27,x27,x23 // d+=h
+ add x23,x23,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x8,x8,x14
+ add x23,x23,x17 // h+=Sigma0(a)
+ add x8,x8,x13
+ ldr x13,[sp,#16]
+ str x0,[sp,#8]
+ ror x16,x27,#14
+ add x22,x22,x28 // h+=K[i]
+ ror x15,x10,#1
+ and x17,x20,x27
+ ror x14,x7,#19
+ bic x28,x21,x27
+ ror x0,x23,#28
+ add x22,x22,x8 // h+=X[i]
+ eor x16,x16,x27,ror#18
+ eor x15,x15,x10,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x23,x24 // a^b, b^c in next round
+ eor x16,x16,x27,ror#41 // Sigma1(e)
+ eor x0,x0,x23,ror#34
+ add x22,x22,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x14,x14,x7,ror#61
+ eor x15,x15,x10,lsr#7 // sigma0(X[i+1])
+ add x22,x22,x16 // h+=Sigma1(e)
+ eor x19,x19,x24 // Maj(a,b,c)
+ eor x17,x0,x23,ror#39 // Sigma0(a)
+ eor x14,x14,x7,lsr#6 // sigma1(X[i+14])
+ add x9,x9,x2
+ add x26,x26,x22 // d+=h
+ add x22,x22,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x9,x9,x15
+ add x22,x22,x17 // h+=Sigma0(a)
+ add x9,x9,x14
+ ldr x14,[sp,#24]
+ str x1,[sp,#16]
+ ror x16,x26,#14
+ add x21,x21,x19 // h+=K[i]
+ ror x0,x11,#1
+ and x17,x27,x26
+ ror x15,x8,#19
+ bic x19,x20,x26
+ ror x1,x22,#28
+ add x21,x21,x9 // h+=X[i]
+ eor x16,x16,x26,ror#18
+ eor x0,x0,x11,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x22,x23 // a^b, b^c in next round
+ eor x16,x16,x26,ror#41 // Sigma1(e)
+ eor x1,x1,x22,ror#34
+ add x21,x21,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x15,x15,x8,ror#61
+ eor x0,x0,x11,lsr#7 // sigma0(X[i+1])
+ add x21,x21,x16 // h+=Sigma1(e)
+ eor x28,x28,x23 // Maj(a,b,c)
+ eor x17,x1,x22,ror#39 // Sigma0(a)
+ eor x15,x15,x8,lsr#6 // sigma1(X[i+14])
+ add x10,x10,x3
+ add x25,x25,x21 // d+=h
+ add x21,x21,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x10,x10,x0
+ add x21,x21,x17 // h+=Sigma0(a)
+ add x10,x10,x15
+ ldr x15,[sp,#0]
+ str x2,[sp,#24]
+ ror x16,x25,#14
+ add x20,x20,x28 // h+=K[i]
+ ror x1,x12,#1
+ and x17,x26,x25
+ ror x0,x9,#19
+ bic x28,x27,x25
+ ror x2,x21,#28
+ add x20,x20,x10 // h+=X[i]
+ eor x16,x16,x25,ror#18
+ eor x1,x1,x12,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x21,x22 // a^b, b^c in next round
+ eor x16,x16,x25,ror#41 // Sigma1(e)
+ eor x2,x2,x21,ror#34
+ add x20,x20,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x0,x0,x9,ror#61
+ eor x1,x1,x12,lsr#7 // sigma0(X[i+1])
+ add x20,x20,x16 // h+=Sigma1(e)
+ eor x19,x19,x22 // Maj(a,b,c)
+ eor x17,x2,x21,ror#39 // Sigma0(a)
+ eor x0,x0,x9,lsr#6 // sigma1(X[i+14])
+ add x11,x11,x4
+ add x24,x24,x20 // d+=h
+ add x20,x20,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x11,x11,x1
+ add x20,x20,x17 // h+=Sigma0(a)
+ add x11,x11,x0
+ ldr x0,[sp,#8]
+ str x3,[sp,#0]
+ ror x16,x24,#14
+ add x27,x27,x19 // h+=K[i]
+ ror x2,x13,#1
+ and x17,x25,x24
+ ror x1,x10,#19
+ bic x19,x26,x24
+ ror x3,x20,#28
+ add x27,x27,x11 // h+=X[i]
+ eor x16,x16,x24,ror#18
+ eor x2,x2,x13,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x20,x21 // a^b, b^c in next round
+ eor x16,x16,x24,ror#41 // Sigma1(e)
+ eor x3,x3,x20,ror#34
+ add x27,x27,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x1,x1,x10,ror#61
+ eor x2,x2,x13,lsr#7 // sigma0(X[i+1])
+ add x27,x27,x16 // h+=Sigma1(e)
+ eor x28,x28,x21 // Maj(a,b,c)
+ eor x17,x3,x20,ror#39 // Sigma0(a)
+ eor x1,x1,x10,lsr#6 // sigma1(X[i+14])
+ add x12,x12,x5
+ add x23,x23,x27 // d+=h
+ add x27,x27,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x12,x12,x2
+ add x27,x27,x17 // h+=Sigma0(a)
+ add x12,x12,x1
+ ldr x1,[sp,#16]
+ str x4,[sp,#8]
+ ror x16,x23,#14
+ add x26,x26,x28 // h+=K[i]
+ ror x3,x14,#1
+ and x17,x24,x23
+ ror x2,x11,#19
+ bic x28,x25,x23
+ ror x4,x27,#28
+ add x26,x26,x12 // h+=X[i]
+ eor x16,x16,x23,ror#18
+ eor x3,x3,x14,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x27,x20 // a^b, b^c in next round
+ eor x16,x16,x23,ror#41 // Sigma1(e)
+ eor x4,x4,x27,ror#34
+ add x26,x26,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x2,x2,x11,ror#61
+ eor x3,x3,x14,lsr#7 // sigma0(X[i+1])
+ add x26,x26,x16 // h+=Sigma1(e)
+ eor x19,x19,x20 // Maj(a,b,c)
+ eor x17,x4,x27,ror#39 // Sigma0(a)
+ eor x2,x2,x11,lsr#6 // sigma1(X[i+14])
+ add x13,x13,x6
+ add x22,x22,x26 // d+=h
+ add x26,x26,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x13,x13,x3
+ add x26,x26,x17 // h+=Sigma0(a)
+ add x13,x13,x2
+ ldr x2,[sp,#24]
+ str x5,[sp,#16]
+ ror x16,x22,#14
+ add x25,x25,x19 // h+=K[i]
+ ror x4,x15,#1
+ and x17,x23,x22
+ ror x3,x12,#19
+ bic x19,x24,x22
+ ror x5,x26,#28
+ add x25,x25,x13 // h+=X[i]
+ eor x16,x16,x22,ror#18
+ eor x4,x4,x15,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x26,x27 // a^b, b^c in next round
+ eor x16,x16,x22,ror#41 // Sigma1(e)
+ eor x5,x5,x26,ror#34
+ add x25,x25,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x3,x3,x12,ror#61
+ eor x4,x4,x15,lsr#7 // sigma0(X[i+1])
+ add x25,x25,x16 // h+=Sigma1(e)
+ eor x28,x28,x27 // Maj(a,b,c)
+ eor x17,x5,x26,ror#39 // Sigma0(a)
+ eor x3,x3,x12,lsr#6 // sigma1(X[i+14])
+ add x14,x14,x7
+ add x21,x21,x25 // d+=h
+ add x25,x25,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x14,x14,x4
+ add x25,x25,x17 // h+=Sigma0(a)
+ add x14,x14,x3
+ ldr x3,[sp,#0]
+ str x6,[sp,#24]
+ ror x16,x21,#14
+ add x24,x24,x28 // h+=K[i]
+ ror x5,x0,#1
+ and x17,x22,x21
+ ror x4,x13,#19
+ bic x28,x23,x21
+ ror x6,x25,#28
+ add x24,x24,x14 // h+=X[i]
+ eor x16,x16,x21,ror#18
+ eor x5,x5,x0,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x25,x26 // a^b, b^c in next round
+ eor x16,x16,x21,ror#41 // Sigma1(e)
+ eor x6,x6,x25,ror#34
+ add x24,x24,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x4,x4,x13,ror#61
+ eor x5,x5,x0,lsr#7 // sigma0(X[i+1])
+ add x24,x24,x16 // h+=Sigma1(e)
+ eor x19,x19,x26 // Maj(a,b,c)
+ eor x17,x6,x25,ror#39 // Sigma0(a)
+ eor x4,x4,x13,lsr#6 // sigma1(X[i+14])
+ add x15,x15,x8
+ add x20,x20,x24 // d+=h
+ add x24,x24,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x15,x15,x5
+ add x24,x24,x17 // h+=Sigma0(a)
+ add x15,x15,x4
+ ldr x4,[sp,#8]
+ str x7,[sp,#0]
+ ror x16,x20,#14
+ add x23,x23,x19 // h+=K[i]
+ ror x6,x1,#1
+ and x17,x21,x20
+ ror x5,x14,#19
+ bic x19,x22,x20
+ ror x7,x24,#28
+ add x23,x23,x15 // h+=X[i]
+ eor x16,x16,x20,ror#18
+ eor x6,x6,x1,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x24,x25 // a^b, b^c in next round
+ eor x16,x16,x20,ror#41 // Sigma1(e)
+ eor x7,x7,x24,ror#34
+ add x23,x23,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x5,x5,x14,ror#61
+ eor x6,x6,x1,lsr#7 // sigma0(X[i+1])
+ add x23,x23,x16 // h+=Sigma1(e)
+ eor x28,x28,x25 // Maj(a,b,c)
+ eor x17,x7,x24,ror#39 // Sigma0(a)
+ eor x5,x5,x14,lsr#6 // sigma1(X[i+14])
+ add x0,x0,x9
+ add x27,x27,x23 // d+=h
+ add x23,x23,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x0,x0,x6
+ add x23,x23,x17 // h+=Sigma0(a)
+ add x0,x0,x5
+ ldr x5,[sp,#16]
+ str x8,[sp,#8]
+ ror x16,x27,#14
+ add x22,x22,x28 // h+=K[i]
+ ror x7,x2,#1
+ and x17,x20,x27
+ ror x6,x15,#19
+ bic x28,x21,x27
+ ror x8,x23,#28
+ add x22,x22,x0 // h+=X[i]
+ eor x16,x16,x27,ror#18
+ eor x7,x7,x2,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x23,x24 // a^b, b^c in next round
+ eor x16,x16,x27,ror#41 // Sigma1(e)
+ eor x8,x8,x23,ror#34
+ add x22,x22,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x6,x6,x15,ror#61
+ eor x7,x7,x2,lsr#7 // sigma0(X[i+1])
+ add x22,x22,x16 // h+=Sigma1(e)
+ eor x19,x19,x24 // Maj(a,b,c)
+ eor x17,x8,x23,ror#39 // Sigma0(a)
+ eor x6,x6,x15,lsr#6 // sigma1(X[i+14])
+ add x1,x1,x10
+ add x26,x26,x22 // d+=h
+ add x22,x22,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x1,x1,x7
+ add x22,x22,x17 // h+=Sigma0(a)
+ add x1,x1,x6
+ ldr x6,[sp,#24]
+ str x9,[sp,#16]
+ ror x16,x26,#14
+ add x21,x21,x19 // h+=K[i]
+ ror x8,x3,#1
+ and x17,x27,x26
+ ror x7,x0,#19
+ bic x19,x20,x26
+ ror x9,x22,#28
+ add x21,x21,x1 // h+=X[i]
+ eor x16,x16,x26,ror#18
+ eor x8,x8,x3,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x22,x23 // a^b, b^c in next round
+ eor x16,x16,x26,ror#41 // Sigma1(e)
+ eor x9,x9,x22,ror#34
+ add x21,x21,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x7,x7,x0,ror#61
+ eor x8,x8,x3,lsr#7 // sigma0(X[i+1])
+ add x21,x21,x16 // h+=Sigma1(e)
+ eor x28,x28,x23 // Maj(a,b,c)
+ eor x17,x9,x22,ror#39 // Sigma0(a)
+ eor x7,x7,x0,lsr#6 // sigma1(X[i+14])
+ add x2,x2,x11
+ add x25,x25,x21 // d+=h
+ add x21,x21,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x2,x2,x8
+ add x21,x21,x17 // h+=Sigma0(a)
+ add x2,x2,x7
+ ldr x7,[sp,#0]
+ str x10,[sp,#24]
+ ror x16,x25,#14
+ add x20,x20,x28 // h+=K[i]
+ ror x9,x4,#1
+ and x17,x26,x25
+ ror x8,x1,#19
+ bic x28,x27,x25
+ ror x10,x21,#28
+ add x20,x20,x2 // h+=X[i]
+ eor x16,x16,x25,ror#18
+ eor x9,x9,x4,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x21,x22 // a^b, b^c in next round
+ eor x16,x16,x25,ror#41 // Sigma1(e)
+ eor x10,x10,x21,ror#34
+ add x20,x20,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x8,x8,x1,ror#61
+ eor x9,x9,x4,lsr#7 // sigma0(X[i+1])
+ add x20,x20,x16 // h+=Sigma1(e)
+ eor x19,x19,x22 // Maj(a,b,c)
+ eor x17,x10,x21,ror#39 // Sigma0(a)
+ eor x8,x8,x1,lsr#6 // sigma1(X[i+14])
+ add x3,x3,x12
+ add x24,x24,x20 // d+=h
+ add x20,x20,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x3,x3,x9
+ add x20,x20,x17 // h+=Sigma0(a)
+ add x3,x3,x8
+ cbnz x19,.Loop_16_xx
+
+ ldp x0,x2,[x29,#96]
+ ldr x1,[x29,#112]
+ sub x30,x30,#648 // rewind
+
+ ldp x3,x4,[x0]
+ ldp x5,x6,[x0,#2*8]
+ add x1,x1,#14*8 // advance input pointer
+ ldp x7,x8,[x0,#4*8]
+ add x20,x20,x3
+ ldp x9,x10,[x0,#6*8]
+ add x21,x21,x4
+ add x22,x22,x5
+ add x23,x23,x6
+ stp x20,x21,[x0]
+ add x24,x24,x7
+ add x25,x25,x8
+ stp x22,x23,[x0,#2*8]
+ add x26,x26,x9
+ add x27,x27,x10
+ cmp x1,x2
+ stp x24,x25,[x0,#4*8]
+ stp x26,x27,[x0,#6*8]
+ b.ne .Loop
+
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#4*8
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#128
+.inst 0xd50323bf // autiasp
+ ret
+.size sha512_block_data_order,.-sha512_block_data_order
+
+.align 6
+.type .LK512,%object
+.LK512:
+.quad 0x428a2f98d728ae22,0x7137449123ef65cd
+.quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+.quad 0x3956c25bf348b538,0x59f111f1b605d019
+.quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118
+.quad 0xd807aa98a3030242,0x12835b0145706fbe
+.quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+.quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1
+.quad 0x9bdc06a725c71235,0xc19bf174cf692694
+.quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3
+.quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+.quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483
+.quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+.quad 0x983e5152ee66dfab,0xa831c66d2db43210
+.quad 0xb00327c898fb213f,0xbf597fc7beef0ee4
+.quad 0xc6e00bf33da88fc2,0xd5a79147930aa725
+.quad 0x06ca6351e003826f,0x142929670a0e6e70
+.quad 0x27b70a8546d22ffc,0x2e1b21385c26c926
+.quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+.quad 0x650a73548baf63de,0x766a0abb3c77b2a8
+.quad 0x81c2c92e47edaee6,0x92722c851482353b
+.quad 0xa2bfe8a14cf10364,0xa81a664bbc423001
+.quad 0xc24b8b70d0f89791,0xc76c51a30654be30
+.quad 0xd192e819d6ef5218,0xd69906245565a910
+.quad 0xf40e35855771202a,0x106aa07032bbd1b8
+.quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53
+.quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+.quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+.quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+.quad 0x748f82ee5defb2fc,0x78a5636f43172f60
+.quad 0x84c87814a1f0ab72,0x8cc702081a6439ec
+.quad 0x90befffa23631e28,0xa4506cebde82bde9
+.quad 0xbef9a3f7b2c67915,0xc67178f2e372532b
+.quad 0xca273eceea26619c,0xd186b8c721c0c207
+.quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+.quad 0x06f067aa72176fba,0x0a637dc5a2c898a6
+.quad 0x113f9804bef90dae,0x1b710b35131c471b
+.quad 0x28db77f523047d84,0x32caab7b40c72493
+.quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+.quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+.quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817
+.quad 0 // terminator
+.size .LK512,.-.LK512
+.byte 83,72,65,53,49,50,32,98,108,111,99,107,32,116,114,97,110,115,102,111,114,109,32,102,111,114,32,65,82,77,118,56,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
+.align 2
+.align 2
+#ifndef __KERNEL__
+.type sha512_block_armv8,%function
+.align 6
+sha512_block_armv8:
+.Lv8_entry:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ld1 {v16.16b,v17.16b,v18.16b,v19.16b},[x1],#64 // load input
+ ld1 {v20.16b,v21.16b,v22.16b,v23.16b},[x1],#64
+
+ ld1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // load context
+ adr x3,.LK512
+
+ rev64 v16.16b,v16.16b
+ rev64 v17.16b,v17.16b
+ rev64 v18.16b,v18.16b
+ rev64 v19.16b,v19.16b
+ rev64 v20.16b,v20.16b
+ rev64 v21.16b,v21.16b
+ rev64 v22.16b,v22.16b
+ rev64 v23.16b,v23.16b
+ b .Loop_hw
+
+.align 4
+.Loop_hw:
+ ld1 {v24.2d},[x3],#16
+ subs x2,x2,#1
+ sub x4,x1,#128
+ orr v26.16b,v0.16b,v0.16b // offload
+ orr v27.16b,v1.16b,v1.16b
+ orr v28.16b,v2.16b,v2.16b
+ orr v29.16b,v3.16b,v3.16b
+ csel x1,x1,x4,ne // conditional rewind
+ add v24.2d,v24.2d,v16.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v2.16b,v3.16b,#8
+ ext v6.16b,v1.16b,v2.16b,#8
+ add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec08230 //sha512su0 v16.16b,v17.16b
+ ext v7.16b,v20.16b,v21.16b,#8
+.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b
+.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b
+ add v4.2d,v1.2d,v3.2d // "D + T1"
+.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b
+ add v25.2d,v25.2d,v17.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v4.16b,v2.16b,#8
+ ext v6.16b,v0.16b,v4.16b,#8
+ add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08251 //sha512su0 v17.16b,v18.16b
+ ext v7.16b,v21.16b,v22.16b,#8
+.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b
+.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b
+ add v1.2d,v0.2d,v2.2d // "D + T1"
+.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b
+ add v24.2d,v24.2d,v18.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v1.16b,v4.16b,#8
+ ext v6.16b,v3.16b,v1.16b,#8
+ add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec08272 //sha512su0 v18.16b,v19.16b
+ ext v7.16b,v22.16b,v23.16b,#8
+.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b
+.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b
+ add v0.2d,v3.2d,v4.2d // "D + T1"
+.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b
+ add v25.2d,v25.2d,v19.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v0.16b,v1.16b,#8
+ ext v6.16b,v2.16b,v0.16b,#8
+ add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08293 //sha512su0 v19.16b,v20.16b
+ ext v7.16b,v23.16b,v16.16b,#8
+.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b
+.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b
+ add v3.2d,v2.2d,v1.2d // "D + T1"
+.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b
+ add v24.2d,v24.2d,v20.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v3.16b,v0.16b,#8
+ ext v6.16b,v4.16b,v3.16b,#8
+ add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b
+ ext v7.16b,v16.16b,v17.16b,#8
+.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b
+.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b
+ add v2.2d,v4.2d,v0.2d // "D + T1"
+.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b
+ add v25.2d,v25.2d,v21.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v2.16b,v3.16b,#8
+ ext v6.16b,v1.16b,v2.16b,#8
+ add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b
+ ext v7.16b,v17.16b,v18.16b,#8
+.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b
+.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b
+ add v4.2d,v1.2d,v3.2d // "D + T1"
+.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b
+ add v24.2d,v24.2d,v22.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v4.16b,v2.16b,#8
+ ext v6.16b,v0.16b,v4.16b,#8
+ add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b
+ ext v7.16b,v18.16b,v19.16b,#8
+.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b
+.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b
+ add v1.2d,v0.2d,v2.2d // "D + T1"
+.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b
+ add v25.2d,v25.2d,v23.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v1.16b,v4.16b,#8
+ ext v6.16b,v3.16b,v1.16b,#8
+ add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08217 //sha512su0 v23.16b,v16.16b
+ ext v7.16b,v19.16b,v20.16b,#8
+.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b
+.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b
+ add v0.2d,v3.2d,v4.2d // "D + T1"
+.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b
+ add v24.2d,v24.2d,v16.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v0.16b,v1.16b,#8
+ ext v6.16b,v2.16b,v0.16b,#8
+ add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec08230 //sha512su0 v16.16b,v17.16b
+ ext v7.16b,v20.16b,v21.16b,#8
+.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b
+.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b
+ add v3.2d,v2.2d,v1.2d // "D + T1"
+.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b
+ add v25.2d,v25.2d,v17.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v3.16b,v0.16b,#8
+ ext v6.16b,v4.16b,v3.16b,#8
+ add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08251 //sha512su0 v17.16b,v18.16b
+ ext v7.16b,v21.16b,v22.16b,#8
+.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b
+.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b
+ add v2.2d,v4.2d,v0.2d // "D + T1"
+.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b
+ add v24.2d,v24.2d,v18.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v2.16b,v3.16b,#8
+ ext v6.16b,v1.16b,v2.16b,#8
+ add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec08272 //sha512su0 v18.16b,v19.16b
+ ext v7.16b,v22.16b,v23.16b,#8
+.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b
+.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b
+ add v4.2d,v1.2d,v3.2d // "D + T1"
+.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b
+ add v25.2d,v25.2d,v19.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v4.16b,v2.16b,#8
+ ext v6.16b,v0.16b,v4.16b,#8
+ add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08293 //sha512su0 v19.16b,v20.16b
+ ext v7.16b,v23.16b,v16.16b,#8
+.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b
+.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b
+ add v1.2d,v0.2d,v2.2d // "D + T1"
+.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b
+ add v24.2d,v24.2d,v20.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v1.16b,v4.16b,#8
+ ext v6.16b,v3.16b,v1.16b,#8
+ add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b
+ ext v7.16b,v16.16b,v17.16b,#8
+.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b
+.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b
+ add v0.2d,v3.2d,v4.2d // "D + T1"
+.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b
+ add v25.2d,v25.2d,v21.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v0.16b,v1.16b,#8
+ ext v6.16b,v2.16b,v0.16b,#8
+ add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b
+ ext v7.16b,v17.16b,v18.16b,#8
+.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b
+.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b
+ add v3.2d,v2.2d,v1.2d // "D + T1"
+.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b
+ add v24.2d,v24.2d,v22.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v3.16b,v0.16b,#8
+ ext v6.16b,v4.16b,v3.16b,#8
+ add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b
+ ext v7.16b,v18.16b,v19.16b,#8
+.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b
+.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b
+ add v2.2d,v4.2d,v0.2d // "D + T1"
+.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b
+ add v25.2d,v25.2d,v23.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v2.16b,v3.16b,#8
+ ext v6.16b,v1.16b,v2.16b,#8
+ add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08217 //sha512su0 v23.16b,v16.16b
+ ext v7.16b,v19.16b,v20.16b,#8
+.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b
+.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b
+ add v4.2d,v1.2d,v3.2d // "D + T1"
+.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b
+ add v24.2d,v24.2d,v16.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v4.16b,v2.16b,#8
+ ext v6.16b,v0.16b,v4.16b,#8
+ add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec08230 //sha512su0 v16.16b,v17.16b
+ ext v7.16b,v20.16b,v21.16b,#8
+.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b
+.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b
+ add v1.2d,v0.2d,v2.2d // "D + T1"
+.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b
+ add v25.2d,v25.2d,v17.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v1.16b,v4.16b,#8
+ ext v6.16b,v3.16b,v1.16b,#8
+ add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08251 //sha512su0 v17.16b,v18.16b
+ ext v7.16b,v21.16b,v22.16b,#8
+.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b
+.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b
+ add v0.2d,v3.2d,v4.2d // "D + T1"
+.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b
+ add v24.2d,v24.2d,v18.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v0.16b,v1.16b,#8
+ ext v6.16b,v2.16b,v0.16b,#8
+ add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec08272 //sha512su0 v18.16b,v19.16b
+ ext v7.16b,v22.16b,v23.16b,#8
+.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b
+.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b
+ add v3.2d,v2.2d,v1.2d // "D + T1"
+.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b
+ add v25.2d,v25.2d,v19.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v3.16b,v0.16b,#8
+ ext v6.16b,v4.16b,v3.16b,#8
+ add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08293 //sha512su0 v19.16b,v20.16b
+ ext v7.16b,v23.16b,v16.16b,#8
+.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b
+.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b
+ add v2.2d,v4.2d,v0.2d // "D + T1"
+.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b
+ add v24.2d,v24.2d,v20.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v2.16b,v3.16b,#8
+ ext v6.16b,v1.16b,v2.16b,#8
+ add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b
+ ext v7.16b,v16.16b,v17.16b,#8
+.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b
+.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b
+ add v4.2d,v1.2d,v3.2d // "D + T1"
+.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b
+ add v25.2d,v25.2d,v21.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v4.16b,v2.16b,#8
+ ext v6.16b,v0.16b,v4.16b,#8
+ add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b
+ ext v7.16b,v17.16b,v18.16b,#8
+.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b
+.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b
+ add v1.2d,v0.2d,v2.2d // "D + T1"
+.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b
+ add v24.2d,v24.2d,v22.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v1.16b,v4.16b,#8
+ ext v6.16b,v3.16b,v1.16b,#8
+ add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b
+ ext v7.16b,v18.16b,v19.16b,#8
+.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b
+.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b
+ add v0.2d,v3.2d,v4.2d // "D + T1"
+.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b
+ add v25.2d,v25.2d,v23.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v0.16b,v1.16b,#8
+ ext v6.16b,v2.16b,v0.16b,#8
+ add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08217 //sha512su0 v23.16b,v16.16b
+ ext v7.16b,v19.16b,v20.16b,#8
+.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b
+.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b
+ add v3.2d,v2.2d,v1.2d // "D + T1"
+.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b
+ add v24.2d,v24.2d,v16.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v3.16b,v0.16b,#8
+ ext v6.16b,v4.16b,v3.16b,#8
+ add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec08230 //sha512su0 v16.16b,v17.16b
+ ext v7.16b,v20.16b,v21.16b,#8
+.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b
+.inst 0xce678af0 //sha512su1 v16.16b,v23.16b,v7.16b
+ add v2.2d,v4.2d,v0.2d // "D + T1"
+.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b
+ add v25.2d,v25.2d,v17.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v2.16b,v3.16b,#8
+ ext v6.16b,v1.16b,v2.16b,#8
+ add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08251 //sha512su0 v17.16b,v18.16b
+ ext v7.16b,v21.16b,v22.16b,#8
+.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b
+.inst 0xce678a11 //sha512su1 v17.16b,v16.16b,v7.16b
+ add v4.2d,v1.2d,v3.2d // "D + T1"
+.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b
+ add v24.2d,v24.2d,v18.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v4.16b,v2.16b,#8
+ ext v6.16b,v0.16b,v4.16b,#8
+ add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec08272 //sha512su0 v18.16b,v19.16b
+ ext v7.16b,v22.16b,v23.16b,#8
+.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b
+.inst 0xce678a32 //sha512su1 v18.16b,v17.16b,v7.16b
+ add v1.2d,v0.2d,v2.2d // "D + T1"
+.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b
+ add v25.2d,v25.2d,v19.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v1.16b,v4.16b,#8
+ ext v6.16b,v3.16b,v1.16b,#8
+ add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08293 //sha512su0 v19.16b,v20.16b
+ ext v7.16b,v23.16b,v16.16b,#8
+.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b
+.inst 0xce678a53 //sha512su1 v19.16b,v18.16b,v7.16b
+ add v0.2d,v3.2d,v4.2d // "D + T1"
+.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b
+ add v24.2d,v24.2d,v20.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v0.16b,v1.16b,#8
+ ext v6.16b,v2.16b,v0.16b,#8
+ add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec082b4 //sha512su0 v20.16b,v21.16b
+ ext v7.16b,v16.16b,v17.16b,#8
+.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b
+.inst 0xce678a74 //sha512su1 v20.16b,v19.16b,v7.16b
+ add v3.2d,v2.2d,v1.2d // "D + T1"
+.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b
+ add v25.2d,v25.2d,v21.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v3.16b,v0.16b,#8
+ ext v6.16b,v4.16b,v3.16b,#8
+ add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec082d5 //sha512su0 v21.16b,v22.16b
+ ext v7.16b,v17.16b,v18.16b,#8
+.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b
+.inst 0xce678a95 //sha512su1 v21.16b,v20.16b,v7.16b
+ add v2.2d,v4.2d,v0.2d // "D + T1"
+.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b
+ add v24.2d,v24.2d,v22.2d
+ ld1 {v25.2d},[x3],#16
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v2.16b,v3.16b,#8
+ ext v6.16b,v1.16b,v2.16b,#8
+ add v3.2d,v3.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xcec082f6 //sha512su0 v22.16b,v23.16b
+ ext v7.16b,v18.16b,v19.16b,#8
+.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b
+.inst 0xce678ab6 //sha512su1 v22.16b,v21.16b,v7.16b
+ add v4.2d,v1.2d,v3.2d // "D + T1"
+.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b
+ add v25.2d,v25.2d,v23.2d
+ ld1 {v24.2d},[x3],#16
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v4.16b,v2.16b,#8
+ ext v6.16b,v0.16b,v4.16b,#8
+ add v2.2d,v2.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xcec08217 //sha512su0 v23.16b,v16.16b
+ ext v7.16b,v19.16b,v20.16b,#8
+.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b
+.inst 0xce678ad7 //sha512su1 v23.16b,v22.16b,v7.16b
+ add v1.2d,v0.2d,v2.2d // "D + T1"
+.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b
+ ld1 {v25.2d},[x3],#16
+ add v24.2d,v24.2d,v16.2d
+ ld1 {v16.16b},[x1],#16 // load next input
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v1.16b,v4.16b,#8
+ ext v6.16b,v3.16b,v1.16b,#8
+ add v4.2d,v4.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b
+ rev64 v16.16b,v16.16b
+ add v0.2d,v3.2d,v4.2d // "D + T1"
+.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b
+ ld1 {v24.2d},[x3],#16
+ add v25.2d,v25.2d,v17.2d
+ ld1 {v17.16b},[x1],#16 // load next input
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v0.16b,v1.16b,#8
+ ext v6.16b,v2.16b,v0.16b,#8
+ add v1.2d,v1.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b
+ rev64 v17.16b,v17.16b
+ add v3.2d,v2.2d,v1.2d // "D + T1"
+.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b
+ ld1 {v25.2d},[x3],#16
+ add v24.2d,v24.2d,v18.2d
+ ld1 {v18.16b},[x1],#16 // load next input
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v3.16b,v0.16b,#8
+ ext v6.16b,v4.16b,v3.16b,#8
+ add v0.2d,v0.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b
+ rev64 v18.16b,v18.16b
+ add v2.2d,v4.2d,v0.2d // "D + T1"
+.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b
+ ld1 {v24.2d},[x3],#16
+ add v25.2d,v25.2d,v19.2d
+ ld1 {v19.16b},[x1],#16 // load next input
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v2.16b,v3.16b,#8
+ ext v6.16b,v1.16b,v2.16b,#8
+ add v3.2d,v3.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xce6680a3 //sha512h v3.16b,v5.16b,v6.16b
+ rev64 v19.16b,v19.16b
+ add v4.2d,v1.2d,v3.2d // "D + T1"
+.inst 0xce608423 //sha512h2 v3.16b,v1.16b,v0.16b
+ ld1 {v25.2d},[x3],#16
+ add v24.2d,v24.2d,v20.2d
+ ld1 {v20.16b},[x1],#16 // load next input
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v4.16b,v2.16b,#8
+ ext v6.16b,v0.16b,v4.16b,#8
+ add v2.2d,v2.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xce6680a2 //sha512h v2.16b,v5.16b,v6.16b
+ rev64 v20.16b,v20.16b
+ add v1.2d,v0.2d,v2.2d // "D + T1"
+.inst 0xce638402 //sha512h2 v2.16b,v0.16b,v3.16b
+ ld1 {v24.2d},[x3],#16
+ add v25.2d,v25.2d,v21.2d
+ ld1 {v21.16b},[x1],#16 // load next input
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v1.16b,v4.16b,#8
+ ext v6.16b,v3.16b,v1.16b,#8
+ add v4.2d,v4.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xce6680a4 //sha512h v4.16b,v5.16b,v6.16b
+ rev64 v21.16b,v21.16b
+ add v0.2d,v3.2d,v4.2d // "D + T1"
+.inst 0xce628464 //sha512h2 v4.16b,v3.16b,v2.16b
+ ld1 {v25.2d},[x3],#16
+ add v24.2d,v24.2d,v22.2d
+ ld1 {v22.16b},[x1],#16 // load next input
+ ext v24.16b,v24.16b,v24.16b,#8
+ ext v5.16b,v0.16b,v1.16b,#8
+ ext v6.16b,v2.16b,v0.16b,#8
+ add v1.2d,v1.2d,v24.2d // "T1 + H + K512[i]"
+.inst 0xce6680a1 //sha512h v1.16b,v5.16b,v6.16b
+ rev64 v22.16b,v22.16b
+ add v3.2d,v2.2d,v1.2d // "D + T1"
+.inst 0xce648441 //sha512h2 v1.16b,v2.16b,v4.16b
+ sub x3,x3,#80*8 // rewind
+ add v25.2d,v25.2d,v23.2d
+ ld1 {v23.16b},[x1],#16 // load next input
+ ext v25.16b,v25.16b,v25.16b,#8
+ ext v5.16b,v3.16b,v0.16b,#8
+ ext v6.16b,v4.16b,v3.16b,#8
+ add v0.2d,v0.2d,v25.2d // "T1 + H + K512[i]"
+.inst 0xce6680a0 //sha512h v0.16b,v5.16b,v6.16b
+ rev64 v23.16b,v23.16b
+ add v2.2d,v4.2d,v0.2d // "D + T1"
+.inst 0xce618480 //sha512h2 v0.16b,v4.16b,v1.16b
+ add v0.2d,v0.2d,v26.2d // accumulate
+ add v1.2d,v1.2d,v27.2d
+ add v2.2d,v2.2d,v28.2d
+ add v3.2d,v3.2d,v29.2d
+
+ cbnz x2,.Loop_hw
+
+ st1 {v0.2d,v1.2d,v2.2d,v3.2d},[x0] // store context
+
+ ldr x29,[sp],#16
+ ret
+.size sha512_block_armv8,.-sha512_block_armv8
+#endif
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/bio.h b/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/bio.h
index 43a6608..9021fd2 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/bio.h
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/bio.h
@@ -867,7 +867,7 @@ int BIO_meth_set_puts(BIO_METHOD *biom,
int (*puts) (BIO *, const char *));
int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int);
int BIO_meth_set_gets(BIO_METHOD *biom,
- int (*gets) (BIO *, char *, int));
+ int (*ossl_gets) (BIO *, char *, int));
long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *);
int BIO_meth_set_ctrl(BIO_METHOD *biom,
long (*ctrl) (BIO *, int, long, void *));
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/opensslv.h b/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/opensslv.h
index 9340a01..efbc858 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/opensslv.h
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
*/
# define OPENSSL_VERSION_MAJOR 3
# define OPENSSL_VERSION_MINOR 0
-# define OPENSSL_VERSION_PATCH 9
+# define OPENSSL_VERSION_PATCH 15
/*
* Additional version information
@@ -74,21 +74,21 @@ extern "C" {
* longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
* OPENSSL_VERSION_BUILD_METADATA_STR appended.
*/
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9"
+# define OPENSSL_VERSION_STR "3.0.15"
+# define OPENSSL_FULL_VERSION_STR "3.0.15"
/*
* SECTION 3: ADDITIONAL METADATA
*
* These strings are defined separately to allow them to be parsable.
*/
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "3 Sep 2024"
/*
* SECTION 4: BACKWARD COMPATIBILITY
*/
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.15 3 Sep 2024"
/* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
# ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/pkcs7.h b/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/pkcs7.h
index 7b07d9c..497fcf3 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/pkcs7.h
+++ b/CryptoPkg/Library/OpensslLib/OpensslGen/include/openssl/pkcs7.h
@@ -2,7 +2,7 @@
* WARNING: do not edit!
* Generated by Makefile from include/openssl/pkcs7.h.in
*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -56,8 +56,8 @@ typedef struct pkcs7_signer_info_st {
PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
X509_ALGOR *digest_alg;
STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */
- X509_ALGOR *digest_enc_alg;
- ASN1_OCTET_STRING *enc_digest;
+ X509_ALGOR *digest_enc_alg; /* confusing name, actually used for signing */
+ ASN1_OCTET_STRING *enc_digest; /* confusing name, actually signature */
STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */
/* The private key to sign with */
EVP_PKEY *pkey;
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
index d499eb7..ebdeae1 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
@@ -29,7 +29,6 @@
[Sources]
OpensslLibConstructor.c
- $(OPENSSL_PATH)/e_os.h
$(OPENSSL_PATH)/ms/uplink.h
# Autogenerated files list starts here
$(OPENSSL_PATH)/crypto/aes/aes_cbc.c
@@ -739,8 +738,8 @@
# 1: ignore "#1-D: last line of file ends without a newline"
# 3017: <entity> may be used before being set (NOTE: This was fixed in OpenSSL 1.1 HEAD with
# commit d9b8b89bec4480de3a10bdaf9425db371c19145b, and can be dropped then.)
- XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized
- XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized
+ XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized -DOPENSSL_NO_APPLE_CRYPTO_RANDOM
+ XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized -DOPENSSL_NO_APPLE_CRYPTO_RANDOM
#
# AARCH64 uses strict alignment and avoids SIMD registers for code that may execute
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf
index a37347f..7ef206e 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf
@@ -1,10 +1,11 @@
## @file
# This module provides OpenSSL Library implementation with TLS features
# along with performance optimized implementations of SHA1, SHA256, SHA512,
-# AESNI, VPAED, and GHASH for IA32 and X64.
+# AESNI, VPAED, and GHASH for IA32 and X64 and AARCH64.
#
# Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>
# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+# Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -24,14 +25,14 @@
DEFINE OPENSSL_FLAGS = -DL_ENDIAN -DOPENSSL_SMALL_FOOTPRINT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DEDK2_OPENSSL_NOEC=1
DEFINE OPENSSL_FLAGS_IA32 = -DAES_ASM -DGHASH_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM
DEFINE OPENSSL_FLAGS_X64 = -DAES_ASM -DBSAES_ASM -DGHASH_ASM -DKECCAK1600_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM
+ DEFINE OPENSSL_FLAGS_AARCH64 = -DKECCAK1600_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM
#
-# VALID_ARCHITECTURES = IA32 X64
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
#
[Sources]
OpensslLibConstructor.c
- $(OPENSSL_PATH)/e_os.h
$(OPENSSL_PATH)/ms/uplink.h
$(OPENSSL_PATH)/crypto/bn/bn_asm.c
# Autogenerated files list starts here
@@ -1326,6 +1327,630 @@
$(OPENSSL_GEN_PATH)/X64-GCC/crypto/sha/sha512-x86_64.s | GCC
# Autogenerated files list ends here
+[Sources.AARCH64]
+ OpensslStub/AArch64Cap.c
+# Autogenerated files list starts here
+ $(OPENSSL_PATH)/crypto/aes/aes_cbc.c
+ $(OPENSSL_PATH)/crypto/aes/aes_cfb.c
+ $(OPENSSL_PATH)/crypto/aes/aes_core.c
+ $(OPENSSL_PATH)/crypto/aes/aes_ecb.c
+ $(OPENSSL_PATH)/crypto/aes/aes_ige.c
+ $(OPENSSL_PATH)/crypto/aes/aes_misc.c
+ $(OPENSSL_PATH)/crypto/aes/aes_ofb.c
+ $(OPENSSL_PATH)/crypto/aes/aes_wrap.c
+ $(OPENSSL_PATH)/crypto/asn1/a_bitstr.c
+ $(OPENSSL_PATH)/crypto/asn1/a_d2i_fp.c
+ $(OPENSSL_PATH)/crypto/asn1/a_digest.c
+ $(OPENSSL_PATH)/crypto/asn1/a_dup.c
+ $(OPENSSL_PATH)/crypto/asn1/a_gentm.c
+ $(OPENSSL_PATH)/crypto/asn1/a_i2d_fp.c
+ $(OPENSSL_PATH)/crypto/asn1/a_int.c
+ $(OPENSSL_PATH)/crypto/asn1/a_mbstr.c
+ $(OPENSSL_PATH)/crypto/asn1/a_object.c
+ $(OPENSSL_PATH)/crypto/asn1/a_octet.c
+ $(OPENSSL_PATH)/crypto/asn1/a_print.c
+ $(OPENSSL_PATH)/crypto/asn1/a_sign.c
+ $(OPENSSL_PATH)/crypto/asn1/a_strex.c
+ $(OPENSSL_PATH)/crypto/asn1/a_strnid.c
+ $(OPENSSL_PATH)/crypto/asn1/a_time.c
+ $(OPENSSL_PATH)/crypto/asn1/a_type.c
+ $(OPENSSL_PATH)/crypto/asn1/a_utctm.c
+ $(OPENSSL_PATH)/crypto/asn1/a_utf8.c
+ $(OPENSSL_PATH)/crypto/asn1/a_verify.c
+ $(OPENSSL_PATH)/crypto/asn1/ameth_lib.c
+ $(OPENSSL_PATH)/crypto/asn1/asn1_err.c
+ $(OPENSSL_PATH)/crypto/asn1/asn1_gen.c
+ $(OPENSSL_PATH)/crypto/asn1/asn1_item_list.c
+ $(OPENSSL_PATH)/crypto/asn1/asn1_lib.c
+ $(OPENSSL_PATH)/crypto/asn1/asn1_parse.c
+ $(OPENSSL_PATH)/crypto/asn1/asn_mime.c
+ $(OPENSSL_PATH)/crypto/asn1/asn_moid.c
+ $(OPENSSL_PATH)/crypto/asn1/asn_mstbl.c
+ $(OPENSSL_PATH)/crypto/asn1/asn_pack.c
+ $(OPENSSL_PATH)/crypto/asn1/bio_asn1.c
+ $(OPENSSL_PATH)/crypto/asn1/bio_ndef.c
+ $(OPENSSL_PATH)/crypto/asn1/d2i_param.c
+ $(OPENSSL_PATH)/crypto/asn1/d2i_pr.c
+ $(OPENSSL_PATH)/crypto/asn1/d2i_pu.c
+ $(OPENSSL_PATH)/crypto/asn1/evp_asn1.c
+ $(OPENSSL_PATH)/crypto/asn1/f_int.c
+ $(OPENSSL_PATH)/crypto/asn1/f_string.c
+ $(OPENSSL_PATH)/crypto/asn1/i2d_evp.c
+ $(OPENSSL_PATH)/crypto/asn1/nsseq.c
+ $(OPENSSL_PATH)/crypto/asn1/p5_pbe.c
+ $(OPENSSL_PATH)/crypto/asn1/p5_pbev2.c
+ $(OPENSSL_PATH)/crypto/asn1/p5_scrypt.c
+ $(OPENSSL_PATH)/crypto/asn1/p8_pkey.c
+ $(OPENSSL_PATH)/crypto/asn1/t_bitst.c
+ $(OPENSSL_PATH)/crypto/asn1/t_pkey.c
+ $(OPENSSL_PATH)/crypto/asn1/t_spki.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_dec.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_enc.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_fre.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_new.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_prn.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_scn.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_typ.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_utl.c
+ $(OPENSSL_PATH)/crypto/asn1/x_algor.c
+ $(OPENSSL_PATH)/crypto/asn1/x_bignum.c
+ $(OPENSSL_PATH)/crypto/asn1/x_info.c
+ $(OPENSSL_PATH)/crypto/asn1/x_int64.c
+ $(OPENSSL_PATH)/crypto/asn1/x_long.c
+ $(OPENSSL_PATH)/crypto/asn1/x_pkey.c
+ $(OPENSSL_PATH)/crypto/asn1/x_sig.c
+ $(OPENSSL_PATH)/crypto/asn1/x_spki.c
+ $(OPENSSL_PATH)/crypto/asn1/x_val.c
+ $(OPENSSL_PATH)/crypto/async/arch/async_null.c
+ $(OPENSSL_PATH)/crypto/async/arch/async_posix.c
+ $(OPENSSL_PATH)/crypto/async/arch/async_win.c
+ $(OPENSSL_PATH)/crypto/async/async.c
+ $(OPENSSL_PATH)/crypto/async/async_err.c
+ $(OPENSSL_PATH)/crypto/async/async_wait.c
+ $(OPENSSL_PATH)/crypto/bio/bf_buff.c
+ $(OPENSSL_PATH)/crypto/bio/bf_lbuf.c
+ $(OPENSSL_PATH)/crypto/bio/bf_nbio.c
+ $(OPENSSL_PATH)/crypto/bio/bf_null.c
+ $(OPENSSL_PATH)/crypto/bio/bf_prefix.c
+ $(OPENSSL_PATH)/crypto/bio/bf_readbuff.c
+ $(OPENSSL_PATH)/crypto/bio/bio_addr.c
+ $(OPENSSL_PATH)/crypto/bio/bio_cb.c
+ $(OPENSSL_PATH)/crypto/bio/bio_dump.c
+ $(OPENSSL_PATH)/crypto/bio/bio_err.c
+ $(OPENSSL_PATH)/crypto/bio/bio_lib.c
+ $(OPENSSL_PATH)/crypto/bio/bio_meth.c
+ $(OPENSSL_PATH)/crypto/bio/bio_print.c
+ $(OPENSSL_PATH)/crypto/bio/bio_sock.c
+ $(OPENSSL_PATH)/crypto/bio/bio_sock2.c
+ $(OPENSSL_PATH)/crypto/bio/bss_acpt.c
+ $(OPENSSL_PATH)/crypto/bio/bss_bio.c
+ $(OPENSSL_PATH)/crypto/bio/bss_conn.c
+ $(OPENSSL_PATH)/crypto/bio/bss_core.c
+ $(OPENSSL_PATH)/crypto/bio/bss_dgram.c
+ $(OPENSSL_PATH)/crypto/bio/bss_fd.c
+ $(OPENSSL_PATH)/crypto/bio/bss_file.c
+ $(OPENSSL_PATH)/crypto/bio/bss_log.c
+ $(OPENSSL_PATH)/crypto/bio/bss_mem.c
+ $(OPENSSL_PATH)/crypto/bio/bss_null.c
+ $(OPENSSL_PATH)/crypto/bio/bss_sock.c
+ $(OPENSSL_PATH)/crypto/bio/ossl_core_bio.c
+ $(OPENSSL_PATH)/crypto/bn/bn_add.c
+ $(OPENSSL_PATH)/crypto/bn/bn_asm.c
+ $(OPENSSL_PATH)/crypto/bn/bn_blind.c
+ $(OPENSSL_PATH)/crypto/bn/bn_const.c
+ $(OPENSSL_PATH)/crypto/bn/bn_conv.c
+ $(OPENSSL_PATH)/crypto/bn/bn_ctx.c
+ $(OPENSSL_PATH)/crypto/bn/bn_dh.c
+ $(OPENSSL_PATH)/crypto/bn/bn_div.c
+ $(OPENSSL_PATH)/crypto/bn/bn_err.c
+ $(OPENSSL_PATH)/crypto/bn/bn_exp.c
+ $(OPENSSL_PATH)/crypto/bn/bn_exp2.c
+ $(OPENSSL_PATH)/crypto/bn/bn_gcd.c
+ $(OPENSSL_PATH)/crypto/bn/bn_gf2m.c
+ $(OPENSSL_PATH)/crypto/bn/bn_intern.c
+ $(OPENSSL_PATH)/crypto/bn/bn_kron.c
+ $(OPENSSL_PATH)/crypto/bn/bn_lib.c
+ $(OPENSSL_PATH)/crypto/bn/bn_mod.c
+ $(OPENSSL_PATH)/crypto/bn/bn_mont.c
+ $(OPENSSL_PATH)/crypto/bn/bn_mpi.c
+ $(OPENSSL_PATH)/crypto/bn/bn_mul.c
+ $(OPENSSL_PATH)/crypto/bn/bn_nist.c
+ $(OPENSSL_PATH)/crypto/bn/bn_prime.c
+ $(OPENSSL_PATH)/crypto/bn/bn_print.c
+ $(OPENSSL_PATH)/crypto/bn/bn_rand.c
+ $(OPENSSL_PATH)/crypto/bn/bn_recp.c
+ $(OPENSSL_PATH)/crypto/bn/bn_rsa_fips186_4.c
+ $(OPENSSL_PATH)/crypto/bn/bn_shift.c
+ $(OPENSSL_PATH)/crypto/bn/bn_sqr.c
+ $(OPENSSL_PATH)/crypto/bn/bn_sqrt.c
+ $(OPENSSL_PATH)/crypto/bn/bn_srp.c
+ $(OPENSSL_PATH)/crypto/bn/bn_word.c
+ $(OPENSSL_PATH)/crypto/bn/bn_x931p.c
+ $(OPENSSL_PATH)/crypto/buffer/buf_err.c
+ $(OPENSSL_PATH)/crypto/buffer/buffer.c
+ $(OPENSSL_PATH)/crypto/comp/c_zlib.c
+ $(OPENSSL_PATH)/crypto/comp/comp_err.c
+ $(OPENSSL_PATH)/crypto/comp/comp_lib.c
+ $(OPENSSL_PATH)/crypto/conf/conf_api.c
+ $(OPENSSL_PATH)/crypto/conf/conf_def.c
+ $(OPENSSL_PATH)/crypto/conf/conf_err.c
+ $(OPENSSL_PATH)/crypto/conf/conf_lib.c
+ $(OPENSSL_PATH)/crypto/conf/conf_mall.c
+ $(OPENSSL_PATH)/crypto/conf/conf_mod.c
+ $(OPENSSL_PATH)/crypto/conf/conf_sap.c
+ $(OPENSSL_PATH)/crypto/conf/conf_ssl.c
+ $(OPENSSL_PATH)/crypto/dh/dh_ameth.c
+ $(OPENSSL_PATH)/crypto/dh/dh_asn1.c
+ $(OPENSSL_PATH)/crypto/dh/dh_backend.c
+ $(OPENSSL_PATH)/crypto/dh/dh_check.c
+ $(OPENSSL_PATH)/crypto/dh/dh_err.c
+ $(OPENSSL_PATH)/crypto/dh/dh_gen.c
+ $(OPENSSL_PATH)/crypto/dh/dh_group_params.c
+ $(OPENSSL_PATH)/crypto/dh/dh_kdf.c
+ $(OPENSSL_PATH)/crypto/dh/dh_key.c
+ $(OPENSSL_PATH)/crypto/dh/dh_lib.c
+ $(OPENSSL_PATH)/crypto/dh/dh_meth.c
+ $(OPENSSL_PATH)/crypto/dh/dh_pmeth.c
+ $(OPENSSL_PATH)/crypto/dh/dh_prn.c
+ $(OPENSSL_PATH)/crypto/dh/dh_rfc5114.c
+ $(OPENSSL_PATH)/crypto/dso/dso_dl.c
+ $(OPENSSL_PATH)/crypto/dso/dso_dlfcn.c
+ $(OPENSSL_PATH)/crypto/dso/dso_err.c
+ $(OPENSSL_PATH)/crypto/dso/dso_lib.c
+ $(OPENSSL_PATH)/crypto/dso/dso_openssl.c
+ $(OPENSSL_PATH)/crypto/dso/dso_vms.c
+ $(OPENSSL_PATH)/crypto/dso/dso_win32.c
+ $(OPENSSL_PATH)/crypto/encode_decode/decoder_err.c
+ $(OPENSSL_PATH)/crypto/encode_decode/decoder_lib.c
+ $(OPENSSL_PATH)/crypto/encode_decode/decoder_meth.c
+ $(OPENSSL_PATH)/crypto/encode_decode/decoder_pkey.c
+ $(OPENSSL_PATH)/crypto/err/err.c
+ $(OPENSSL_PATH)/crypto/err/err_all.c
+ $(OPENSSL_PATH)/crypto/err/err_all_legacy.c
+ $(OPENSSL_PATH)/crypto/err/err_blocks.c
+ $(OPENSSL_PATH)/crypto/err/err_prn.c
+ $(OPENSSL_PATH)/crypto/ess/ess_asn1.c
+ $(OPENSSL_PATH)/crypto/ess/ess_err.c
+ $(OPENSSL_PATH)/crypto/ess/ess_lib.c
+ $(OPENSSL_PATH)/crypto/evp/asymcipher.c
+ $(OPENSSL_PATH)/crypto/evp/bio_b64.c
+ $(OPENSSL_PATH)/crypto/evp/bio_enc.c
+ $(OPENSSL_PATH)/crypto/evp/bio_md.c
+ $(OPENSSL_PATH)/crypto/evp/bio_ok.c
+ $(OPENSSL_PATH)/crypto/evp/c_allc.c
+ $(OPENSSL_PATH)/crypto/evp/c_alld.c
+ $(OPENSSL_PATH)/crypto/evp/cmeth_lib.c
+ $(OPENSSL_PATH)/crypto/evp/ctrl_params_translate.c
+ $(OPENSSL_PATH)/crypto/evp/dh_ctrl.c
+ $(OPENSSL_PATH)/crypto/evp/dh_support.c
+ $(OPENSSL_PATH)/crypto/evp/digest.c
+ $(OPENSSL_PATH)/crypto/evp/dsa_ctrl.c
+ $(OPENSSL_PATH)/crypto/evp/e_aes.c
+ $(OPENSSL_PATH)/crypto/evp/e_aes_cbc_hmac_sha1.c
+ $(OPENSSL_PATH)/crypto/evp/e_aes_cbc_hmac_sha256.c
+ $(OPENSSL_PATH)/crypto/evp/e_aria.c
+ $(OPENSSL_PATH)/crypto/evp/e_bf.c
+ $(OPENSSL_PATH)/crypto/evp/e_cast.c
+ $(OPENSSL_PATH)/crypto/evp/e_chacha20_poly1305.c
+ $(OPENSSL_PATH)/crypto/evp/e_des.c
+ $(OPENSSL_PATH)/crypto/evp/e_des3.c
+ $(OPENSSL_PATH)/crypto/evp/e_idea.c
+ $(OPENSSL_PATH)/crypto/evp/e_null.c
+ $(OPENSSL_PATH)/crypto/evp/e_rc2.c
+ $(OPENSSL_PATH)/crypto/evp/e_rc4.c
+ $(OPENSSL_PATH)/crypto/evp/e_rc4_hmac_md5.c
+ $(OPENSSL_PATH)/crypto/evp/e_rc5.c
+ $(OPENSSL_PATH)/crypto/evp/e_sm4.c
+ $(OPENSSL_PATH)/crypto/evp/e_xcbc_d.c
+ $(OPENSSL_PATH)/crypto/evp/ec_ctrl.c
+ $(OPENSSL_PATH)/crypto/evp/ec_support.c
+ $(OPENSSL_PATH)/crypto/evp/encode.c
+ $(OPENSSL_PATH)/crypto/evp/evp_cnf.c
+ $(OPENSSL_PATH)/crypto/evp/evp_enc.c
+ $(OPENSSL_PATH)/crypto/evp/evp_err.c
+ $(OPENSSL_PATH)/crypto/evp/evp_fetch.c
+ $(OPENSSL_PATH)/crypto/evp/evp_key.c
+ $(OPENSSL_PATH)/crypto/evp/evp_lib.c
+ $(OPENSSL_PATH)/crypto/evp/evp_pbe.c
+ $(OPENSSL_PATH)/crypto/evp/evp_pkey.c
+ $(OPENSSL_PATH)/crypto/evp/evp_rand.c
+ $(OPENSSL_PATH)/crypto/evp/evp_utils.c
+ $(OPENSSL_PATH)/crypto/evp/exchange.c
+ $(OPENSSL_PATH)/crypto/evp/kdf_lib.c
+ $(OPENSSL_PATH)/crypto/evp/kdf_meth.c
+ $(OPENSSL_PATH)/crypto/evp/kem.c
+ $(OPENSSL_PATH)/crypto/evp/keymgmt_lib.c
+ $(OPENSSL_PATH)/crypto/evp/keymgmt_meth.c
+ $(OPENSSL_PATH)/crypto/evp/legacy_md5.c
+ $(OPENSSL_PATH)/crypto/evp/legacy_md5_sha1.c
+ $(OPENSSL_PATH)/crypto/evp/legacy_sha.c
+ $(OPENSSL_PATH)/crypto/evp/m_null.c
+ $(OPENSSL_PATH)/crypto/evp/m_sigver.c
+ $(OPENSSL_PATH)/crypto/evp/mac_lib.c
+ $(OPENSSL_PATH)/crypto/evp/mac_meth.c
+ $(OPENSSL_PATH)/crypto/evp/names.c
+ $(OPENSSL_PATH)/crypto/evp/p5_crpt.c
+ $(OPENSSL_PATH)/crypto/evp/p5_crpt2.c
+ $(OPENSSL_PATH)/crypto/evp/p_dec.c
+ $(OPENSSL_PATH)/crypto/evp/p_enc.c
+ $(OPENSSL_PATH)/crypto/evp/p_legacy.c
+ $(OPENSSL_PATH)/crypto/evp/p_lib.c
+ $(OPENSSL_PATH)/crypto/evp/p_open.c
+ $(OPENSSL_PATH)/crypto/evp/p_seal.c
+ $(OPENSSL_PATH)/crypto/evp/p_sign.c
+ $(OPENSSL_PATH)/crypto/evp/p_verify.c
+ $(OPENSSL_PATH)/crypto/evp/pbe_scrypt.c
+ $(OPENSSL_PATH)/crypto/evp/pmeth_check.c
+ $(OPENSSL_PATH)/crypto/evp/pmeth_gn.c
+ $(OPENSSL_PATH)/crypto/evp/pmeth_lib.c
+ $(OPENSSL_PATH)/crypto/evp/signature.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_backend.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_dh.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_key_generate.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_key_validate.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_params.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_params_generate.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_params_validate.c
+ $(OPENSSL_PATH)/crypto/hmac/hmac.c
+ $(OPENSSL_PATH)/crypto/http/http_client.c
+ $(OPENSSL_PATH)/crypto/http/http_err.c
+ $(OPENSSL_PATH)/crypto/http/http_lib.c
+ $(OPENSSL_PATH)/crypto/kdf/kdf_err.c
+ $(OPENSSL_PATH)/crypto/lhash/lh_stats.c
+ $(OPENSSL_PATH)/crypto/lhash/lhash.c
+ $(OPENSSL_PATH)/crypto/asn1_dsa.c
+ $(OPENSSL_PATH)/crypto/bsearch.c
+ $(OPENSSL_PATH)/crypto/context.c
+ $(OPENSSL_PATH)/crypto/core_algorithm.c
+ $(OPENSSL_PATH)/crypto/core_fetch.c
+ $(OPENSSL_PATH)/crypto/core_namemap.c
+ $(OPENSSL_PATH)/crypto/cpt_err.c
+ $(OPENSSL_PATH)/crypto/cpuid.c
+ $(OPENSSL_PATH)/crypto/cryptlib.c
+ $(OPENSSL_PATH)/crypto/ctype.c
+ $(OPENSSL_PATH)/crypto/cversion.c
+ $(OPENSSL_PATH)/crypto/der_writer.c
+ $(OPENSSL_PATH)/crypto/ebcdic.c
+ $(OPENSSL_PATH)/crypto/ex_data.c
+ $(OPENSSL_PATH)/crypto/getenv.c
+ $(OPENSSL_PATH)/crypto/info.c
+ $(OPENSSL_PATH)/crypto/init.c
+ $(OPENSSL_PATH)/crypto/initthread.c
+ $(OPENSSL_PATH)/crypto/mem.c
+ $(OPENSSL_PATH)/crypto/mem_sec.c
+ $(OPENSSL_PATH)/crypto/o_dir.c
+ $(OPENSSL_PATH)/crypto/o_fopen.c
+ $(OPENSSL_PATH)/crypto/o_init.c
+ $(OPENSSL_PATH)/crypto/o_str.c
+ $(OPENSSL_PATH)/crypto/o_time.c
+ $(OPENSSL_PATH)/crypto/packet.c
+ $(OPENSSL_PATH)/crypto/param_build.c
+ $(OPENSSL_PATH)/crypto/param_build_set.c
+ $(OPENSSL_PATH)/crypto/params.c
+ $(OPENSSL_PATH)/crypto/params_dup.c
+ $(OPENSSL_PATH)/crypto/params_from_text.c
+ $(OPENSSL_PATH)/crypto/passphrase.c
+ $(OPENSSL_PATH)/crypto/provider.c
+ $(OPENSSL_PATH)/crypto/provider_child.c
+ $(OPENSSL_PATH)/crypto/provider_conf.c
+ $(OPENSSL_PATH)/crypto/provider_core.c
+ $(OPENSSL_PATH)/crypto/punycode.c
+ $(OPENSSL_PATH)/crypto/self_test_core.c
+ $(OPENSSL_PATH)/crypto/sparse_array.c
+ $(OPENSSL_PATH)/crypto/threads_lib.c
+ $(OPENSSL_PATH)/crypto/threads_none.c
+ $(OPENSSL_PATH)/crypto/threads_pthread.c
+ $(OPENSSL_PATH)/crypto/threads_win.c
+ $(OPENSSL_PATH)/crypto/trace.c
+ $(OPENSSL_PATH)/crypto/uid.c
+ $(OPENSSL_PATH)/crypto/md5/md5_dgst.c
+ $(OPENSSL_PATH)/crypto/md5/md5_one.c
+ $(OPENSSL_PATH)/crypto/md5/md5_sha1.c
+ $(OPENSSL_PATH)/crypto/modes/cbc128.c
+ $(OPENSSL_PATH)/crypto/modes/ccm128.c
+ $(OPENSSL_PATH)/crypto/modes/cfb128.c
+ $(OPENSSL_PATH)/crypto/modes/ctr128.c
+ $(OPENSSL_PATH)/crypto/modes/cts128.c
+ $(OPENSSL_PATH)/crypto/modes/gcm128.c
+ $(OPENSSL_PATH)/crypto/modes/ocb128.c
+ $(OPENSSL_PATH)/crypto/modes/ofb128.c
+ $(OPENSSL_PATH)/crypto/modes/siv128.c
+ $(OPENSSL_PATH)/crypto/modes/wrap128.c
+ $(OPENSSL_PATH)/crypto/modes/xts128.c
+ $(OPENSSL_PATH)/crypto/objects/o_names.c
+ $(OPENSSL_PATH)/crypto/objects/obj_dat.c
+ $(OPENSSL_PATH)/crypto/objects/obj_err.c
+ $(OPENSSL_PATH)/crypto/objects/obj_lib.c
+ $(OPENSSL_PATH)/crypto/objects/obj_xref.c
+ $(OPENSSL_PATH)/crypto/pem/pem_all.c
+ $(OPENSSL_PATH)/crypto/pem/pem_err.c
+ $(OPENSSL_PATH)/crypto/pem/pem_info.c
+ $(OPENSSL_PATH)/crypto/pem/pem_lib.c
+ $(OPENSSL_PATH)/crypto/pem/pem_oth.c
+ $(OPENSSL_PATH)/crypto/pem/pem_pk8.c
+ $(OPENSSL_PATH)/crypto/pem/pem_pkey.c
+ $(OPENSSL_PATH)/crypto/pem/pem_sign.c
+ $(OPENSSL_PATH)/crypto/pem/pem_x509.c
+ $(OPENSSL_PATH)/crypto/pem/pem_xaux.c
+ $(OPENSSL_PATH)/crypto/pem/pvkfmt.c
+ $(OPENSSL_PATH)/crypto/pkcs7/bio_pk7.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_asn1.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_attr.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_doit.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_lib.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_mime.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_smime.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pkcs7err.c
+ $(OPENSSL_PATH)/crypto/property/defn_cache.c
+ $(OPENSSL_PATH)/crypto/property/property.c
+ $(OPENSSL_PATH)/crypto/property/property_err.c
+ $(OPENSSL_PATH)/crypto/property/property_parse.c
+ $(OPENSSL_PATH)/crypto/property/property_query.c
+ $(OPENSSL_PATH)/crypto/property/property_string.c
+ $(OPENSSL_PATH)/crypto/rand/prov_seed.c
+ $(OPENSSL_PATH)/crypto/rand/rand_deprecated.c
+ $(OPENSSL_PATH)/crypto/rand/rand_err.c
+ $(OPENSSL_PATH)/crypto/rand/rand_lib.c
+ $(OPENSSL_PATH)/crypto/rand/rand_meth.c
+ $(OPENSSL_PATH)/crypto/rand/rand_pool.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_ameth.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_asn1.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_backend.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_chk.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_crpt.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_err.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_gen.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_lib.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_meth.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_mp.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_mp_names.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_none.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_oaep.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_ossl.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_pk1.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_pmeth.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_prn.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_pss.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_saos.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_schemes.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_sign.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_sp800_56b_check.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_sp800_56b_gen.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_x931.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_x931g.c
+ $(OPENSSL_PATH)/crypto/sha/sha1_one.c
+ $(OPENSSL_PATH)/crypto/sha/sha1dgst.c
+ $(OPENSSL_PATH)/crypto/sha/sha256.c
+ $(OPENSSL_PATH)/crypto/sha/sha3.c
+ $(OPENSSL_PATH)/crypto/sha/sha512.c
+ $(OPENSSL_PATH)/crypto/sm3/legacy_sm3.c
+ $(OPENSSL_PATH)/crypto/sm3/sm3.c
+ $(OPENSSL_PATH)/crypto/stack/stack.c
+ $(OPENSSL_PATH)/crypto/txt_db/txt_db.c
+ $(OPENSSL_PATH)/crypto/ui/ui_err.c
+ $(OPENSSL_PATH)/crypto/ui/ui_lib.c
+ $(OPENSSL_PATH)/crypto/ui/ui_null.c
+ $(OPENSSL_PATH)/crypto/ui/ui_openssl.c
+ $(OPENSSL_PATH)/crypto/ui/ui_util.c
+ $(OPENSSL_PATH)/crypto/x509/by_dir.c
+ $(OPENSSL_PATH)/crypto/x509/by_file.c
+ $(OPENSSL_PATH)/crypto/x509/by_store.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_cache.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_data.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_lib.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_map.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_node.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_tree.c
+ $(OPENSSL_PATH)/crypto/x509/t_crl.c
+ $(OPENSSL_PATH)/crypto/x509/t_req.c
+ $(OPENSSL_PATH)/crypto/x509/t_x509.c
+ $(OPENSSL_PATH)/crypto/x509/v3_addr.c
+ $(OPENSSL_PATH)/crypto/x509/v3_admis.c
+ $(OPENSSL_PATH)/crypto/x509/v3_akeya.c
+ $(OPENSSL_PATH)/crypto/x509/v3_akid.c
+ $(OPENSSL_PATH)/crypto/x509/v3_asid.c
+ $(OPENSSL_PATH)/crypto/x509/v3_bcons.c
+ $(OPENSSL_PATH)/crypto/x509/v3_bitst.c
+ $(OPENSSL_PATH)/crypto/x509/v3_conf.c
+ $(OPENSSL_PATH)/crypto/x509/v3_cpols.c
+ $(OPENSSL_PATH)/crypto/x509/v3_crld.c
+ $(OPENSSL_PATH)/crypto/x509/v3_enum.c
+ $(OPENSSL_PATH)/crypto/x509/v3_extku.c
+ $(OPENSSL_PATH)/crypto/x509/v3_genn.c
+ $(OPENSSL_PATH)/crypto/x509/v3_ia5.c
+ $(OPENSSL_PATH)/crypto/x509/v3_info.c
+ $(OPENSSL_PATH)/crypto/x509/v3_int.c
+ $(OPENSSL_PATH)/crypto/x509/v3_ist.c
+ $(OPENSSL_PATH)/crypto/x509/v3_lib.c
+ $(OPENSSL_PATH)/crypto/x509/v3_ncons.c
+ $(OPENSSL_PATH)/crypto/x509/v3_pci.c
+ $(OPENSSL_PATH)/crypto/x509/v3_pcia.c
+ $(OPENSSL_PATH)/crypto/x509/v3_pcons.c
+ $(OPENSSL_PATH)/crypto/x509/v3_pku.c
+ $(OPENSSL_PATH)/crypto/x509/v3_pmaps.c
+ $(OPENSSL_PATH)/crypto/x509/v3_prn.c
+ $(OPENSSL_PATH)/crypto/x509/v3_purp.c
+ $(OPENSSL_PATH)/crypto/x509/v3_san.c
+ $(OPENSSL_PATH)/crypto/x509/v3_skid.c
+ $(OPENSSL_PATH)/crypto/x509/v3_sxnet.c
+ $(OPENSSL_PATH)/crypto/x509/v3_tlsf.c
+ $(OPENSSL_PATH)/crypto/x509/v3_utf8.c
+ $(OPENSSL_PATH)/crypto/x509/v3_utl.c
+ $(OPENSSL_PATH)/crypto/x509/v3err.c
+ $(OPENSSL_PATH)/crypto/x509/x509_att.c
+ $(OPENSSL_PATH)/crypto/x509/x509_cmp.c
+ $(OPENSSL_PATH)/crypto/x509/x509_d2.c
+ $(OPENSSL_PATH)/crypto/x509/x509_def.c
+ $(OPENSSL_PATH)/crypto/x509/x509_err.c
+ $(OPENSSL_PATH)/crypto/x509/x509_ext.c
+ $(OPENSSL_PATH)/crypto/x509/x509_lu.c
+ $(OPENSSL_PATH)/crypto/x509/x509_meth.c
+ $(OPENSSL_PATH)/crypto/x509/x509_obj.c
+ $(OPENSSL_PATH)/crypto/x509/x509_r2x.c
+ $(OPENSSL_PATH)/crypto/x509/x509_req.c
+ $(OPENSSL_PATH)/crypto/x509/x509_set.c
+ $(OPENSSL_PATH)/crypto/x509/x509_trust.c
+ $(OPENSSL_PATH)/crypto/x509/x509_txt.c
+ $(OPENSSL_PATH)/crypto/x509/x509_v3.c
+ $(OPENSSL_PATH)/crypto/x509/x509_vfy.c
+ $(OPENSSL_PATH)/crypto/x509/x509_vpm.c
+ $(OPENSSL_PATH)/crypto/x509/x509cset.c
+ $(OPENSSL_PATH)/crypto/x509/x509name.c
+ $(OPENSSL_PATH)/crypto/x509/x509rset.c
+ $(OPENSSL_PATH)/crypto/x509/x509spki.c
+ $(OPENSSL_PATH)/crypto/x509/x509type.c
+ $(OPENSSL_PATH)/crypto/x509/x_all.c
+ $(OPENSSL_PATH)/crypto/x509/x_attrib.c
+ $(OPENSSL_PATH)/crypto/x509/x_crl.c
+ $(OPENSSL_PATH)/crypto/x509/x_exten.c
+ $(OPENSSL_PATH)/crypto/x509/x_name.c
+ $(OPENSSL_PATH)/crypto/x509/x_pubkey.c
+ $(OPENSSL_PATH)/crypto/x509/x_req.c
+ $(OPENSSL_PATH)/crypto/x509/x_x509.c
+ $(OPENSSL_PATH)/crypto/x509/x_x509a.c
+ $(OPENSSL_PATH)/providers/nullprov.c
+ $(OPENSSL_PATH)/providers/prov_running.c
+ $(OPENSSL_PATH)/providers/common/der/der_rsa_sig.c
+ $(OPENSSL_PATH)/providers/common/bio_prov.c
+ $(OPENSSL_PATH)/providers/common/capabilities.c
+ $(OPENSSL_PATH)/providers/common/digest_to_nid.c
+ $(OPENSSL_PATH)/providers/common/provider_seeding.c
+ $(OPENSSL_PATH)/providers/common/provider_util.c
+ $(OPENSSL_PATH)/providers/common/securitycheck.c
+ $(OPENSSL_PATH)/providers/common/securitycheck_default.c
+ $(OPENSSL_PATH)/providers/implementations/asymciphers/rsa_enc.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_ccm.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_ccm_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_gcm.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_gcm_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_wrp.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts_fips.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_cts.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_null.c
+ $(OPENSSL_PATH)/providers/implementations/digests/md5_prov.c
+ $(OPENSSL_PATH)/providers/implementations/digests/md5_sha1_prov.c
+ $(OPENSSL_PATH)/providers/implementations/digests/null_prov.c
+ $(OPENSSL_PATH)/providers/implementations/digests/sha2_prov.c
+ $(OPENSSL_PATH)/providers/implementations/digests/sha3_prov.c
+ $(OPENSSL_PATH)/providers/implementations/digests/sm3_prov.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_der2key.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_epki2pki.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_msblob2key.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_pem2der.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_pvk2key.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_spki2typespki.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/endecoder_common.c
+ $(OPENSSL_PATH)/providers/implementations/exchange/dh_exch.c
+ $(OPENSSL_PATH)/providers/implementations/exchange/kdf_exch.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/hkdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/kbkdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/krb5kdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/pbkdf2.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/pbkdf2_fips.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/pkcs12kdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/scrypt.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/sshkdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/sskdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/tls1_prf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/x942kdf.c
+ $(OPENSSL_PATH)/providers/implementations/kem/rsa_kem.c
+ $(OPENSSL_PATH)/providers/implementations/keymgmt/dh_kmgmt.c
+ $(OPENSSL_PATH)/providers/implementations/keymgmt/kdf_legacy_kmgmt.c
+ $(OPENSSL_PATH)/providers/implementations/keymgmt/mac_legacy_kmgmt.c
+ $(OPENSSL_PATH)/providers/implementations/keymgmt/rsa_kmgmt.c
+ $(OPENSSL_PATH)/providers/implementations/macs/gmac_prov.c
+ $(OPENSSL_PATH)/providers/implementations/macs/hmac_prov.c
+ $(OPENSSL_PATH)/providers/implementations/macs/kmac_prov.c
+ $(OPENSSL_PATH)/providers/implementations/rands/crngt.c
+ $(OPENSSL_PATH)/providers/implementations/rands/drbg.c
+ $(OPENSSL_PATH)/providers/implementations/rands/drbg_ctr.c
+ $(OPENSSL_PATH)/providers/implementations/rands/drbg_hash.c
+ $(OPENSSL_PATH)/providers/implementations/rands/drbg_hmac.c
+ $(OPENSSL_PATH)/providers/implementations/rands/seed_src.c
+ $(OPENSSL_PATH)/providers/implementations/rands/test_rng.c
+ $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_cpu_x86.c
+ $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_tsc.c
+ $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_unix.c
+ $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_win.c
+ $(OPENSSL_PATH)/providers/implementations/signature/mac_legacy_sig.c
+ $(OPENSSL_PATH)/providers/implementations/signature/rsa_sig.c
+ $(OPENSSL_PATH)/ssl/s3_cbc.c
+ $(OPENSSL_PATH)/providers/common/der/der_rsa_key.c
+ $(OPENSSL_PATH)/providers/common/provider_ctx.c
+ $(OPENSSL_PATH)/providers/common/provider_err.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_block.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_ccm.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_ccm_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_gcm.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_gcm_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_hw.c
+ $(OPENSSL_PATH)/providers/implementations/digests/digestcommon.c
+ $(OPENSSL_PATH)/ssl/record/tls_pad.c
+ $(OPENSSL_GEN_PATH)/providers/common/der/der_digests_gen.c
+ $(OPENSSL_GEN_PATH)/providers/common/der/der_rsa_gen.c
+ $(OPENSSL_GEN_PATH)/providers/common/der/der_wrap_gen.c
+ $(OPENSSL_PATH)/ssl/bio_ssl.c
+ $(OPENSSL_PATH)/ssl/d1_lib.c
+ $(OPENSSL_PATH)/ssl/d1_msg.c
+ $(OPENSSL_PATH)/ssl/d1_srtp.c
+ $(OPENSSL_PATH)/ssl/methods.c
+ $(OPENSSL_PATH)/ssl/pqueue.c
+ $(OPENSSL_PATH)/ssl/s3_enc.c
+ $(OPENSSL_PATH)/ssl/s3_lib.c
+ $(OPENSSL_PATH)/ssl/s3_msg.c
+ $(OPENSSL_PATH)/ssl/ssl_asn1.c
+ $(OPENSSL_PATH)/ssl/ssl_cert.c
+ $(OPENSSL_PATH)/ssl/ssl_ciph.c
+ $(OPENSSL_PATH)/ssl/ssl_conf.c
+ $(OPENSSL_PATH)/ssl/ssl_err.c
+ $(OPENSSL_PATH)/ssl/ssl_err_legacy.c
+ $(OPENSSL_PATH)/ssl/ssl_init.c
+ $(OPENSSL_PATH)/ssl/ssl_lib.c
+ $(OPENSSL_PATH)/ssl/ssl_mcnf.c
+ $(OPENSSL_PATH)/ssl/ssl_rsa.c
+ $(OPENSSL_PATH)/ssl/ssl_rsa_legacy.c
+ $(OPENSSL_PATH)/ssl/ssl_sess.c
+ $(OPENSSL_PATH)/ssl/ssl_stat.c
+ $(OPENSSL_PATH)/ssl/ssl_txt.c
+ $(OPENSSL_PATH)/ssl/ssl_utst.c
+ $(OPENSSL_PATH)/ssl/t1_enc.c
+ $(OPENSSL_PATH)/ssl/t1_lib.c
+ $(OPENSSL_PATH)/ssl/t1_trce.c
+ $(OPENSSL_PATH)/ssl/tls13_enc.c
+ $(OPENSSL_PATH)/ssl/tls_depr.c
+ $(OPENSSL_PATH)/ssl/tls_srp.c
+ $(OPENSSL_PATH)/ssl/record/dtls1_bitmap.c
+ $(OPENSSL_PATH)/ssl/record/rec_layer_d1.c
+ $(OPENSSL_PATH)/ssl/record/rec_layer_s3.c
+ $(OPENSSL_PATH)/ssl/record/ssl3_buffer.c
+ $(OPENSSL_PATH)/ssl/record/ssl3_record.c
+ $(OPENSSL_PATH)/ssl/record/ssl3_record_tls13.c
+ $(OPENSSL_PATH)/ssl/statem/extensions.c
+ $(OPENSSL_PATH)/ssl/statem/extensions_clnt.c
+ $(OPENSSL_PATH)/ssl/statem/extensions_cust.c
+ $(OPENSSL_PATH)/ssl/statem/statem.c
+ $(OPENSSL_PATH)/ssl/statem/statem_clnt.c
+ $(OPENSSL_PATH)/ssl/statem/statem_dtls.c
+ $(OPENSSL_PATH)/ssl/statem/statem_lib.c
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/aes/aesv8-armx.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/aes/vpaes-armv8.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/arm64cpuid.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/modes/ghashv8-armx.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/keccak1600-armv8.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha1-armv8.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha256-armv8.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha512-armv8.S | GCC
+# Autogenerated files list ends here
+
[Packages]
MdePkg/MdePkg.dec
CryptoPkg/CryptoPkg.dec
@@ -1377,7 +2002,7 @@
#
GCC:*_*_IA32_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_IA32) -Wno-error=maybe-uninitialized -Wno-error=unused-but-set-variable
GCC:*_*_X64_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_X64) -Wno-error=maybe-uninitialized -Wno-error=format -Wno-format -Wno-error=unused-but-set-variable -DNO_MSABI_VA_FUNCS
- GCC:*_CLANGDWARF_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize
+ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize
GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize
# Revisit after switching to 3.0 branch
GCC:*_GCC5_*_CC_FLAGS = -Wno-unused-but-set-variable
@@ -1401,5 +2026,18 @@
# 1: ignore "#1-D: last line of file ends without a newline"
# 3017: <entity> may be used before being set (NOTE: This was fixed in OpenSSL 1.1 HEAD with
# commit d9b8b89bec4480de3a10bdaf9425db371c19145b, and can be dropped then.)
- XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_IA32) -w -std=c99 -Wno-error=uninitialized
- XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_X64) -w -std=c99 -Wno-error=uninitialized
+ XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_IA32) -w -std=c99 -Wno-error=uninitialized -DOPENSSL_NO_APPLE_CRYPTO_RANDOM
+ XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_X64) -w -std=c99 -Wno-error=uninitialized -DOPENSSL_NO_APPLE_CRYPTO_RANDOM
+
+ GCC:*_*_AARCH64_CC_FLAGS = $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_AARCH64) -Wno-error=format -Wno-format -D_BITS_STDINT_UINTN_H -D_BITS_STDINT_INTN_H
+
+ #
+ # AARCH64 uses strict alignment and avoids SIMD registers for code that may execute
+ # with the MMU off. This involves SEC, PEI_CORE and PEIM modules as well as BASE
+ # libraries, given that they may be included into such modules.
+ # This library, even though of the BASE type, is never used in such cases, and
+ # avoiding the SIMD register file (which is shared with the FPU) prevents the
+ # compiler from successfully building some of the OpenSSL source files that
+ # use floating point types, so clear the flags here.
+ #
+ GCC:*_*_AARCH64_CC_XIPFLAGS ==
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
index d414988..77ce80f 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
@@ -30,7 +30,6 @@
[Sources]
OpensslLibConstructor.c
- $(OPENSSL_PATH)/e_os.h
$(OPENSSL_PATH)/ms/uplink.h
# Autogenerated files list starts here
$(OPENSSL_PATH)/crypto/aes/aes_cbc.c
@@ -695,8 +694,8 @@
# 1: ignore "#1-D: last line of file ends without a newline"
# 3017: <entity> may be used before being set (NOTE: This was fixed in OpenSSL 1.1 HEAD with
# commit d9b8b89bec4480de3a10bdaf9425db371c19145b, and can be dropped then.)
- XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized
- XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized
+ XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized -DOPENSSL_NO_APPLE_CRYPTO_RANDOM
+ XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized -DOPENSSL_NO_APPLE_CRYPTO_RANDOM
#
# AARCH64 uses strict alignment and avoids SIMD registers for code that may execute
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf b/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf
index 55c6342..32c79c3 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf
@@ -34,7 +34,6 @@
[Sources]
OpensslLibConstructor.c
- $(OPENSSL_PATH)/e_os.h
$(OPENSSL_PATH)/ms/uplink.h
# Autogenerated files list starts here
$(OPENSSL_PATH)/crypto/aes/aes_cbc.c
@@ -793,8 +792,8 @@
# 1: ignore "#1-D: last line of file ends without a newline"
# 3017: <entity> may be used before being set (NOTE: This was fixed in OpenSSL 1.1 HEAD with
# commit d9b8b89bec4480de3a10bdaf9425db371c19145b, and can be dropped then.)
- XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized
- XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized
+ XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized -DOPENSSL_NO_APPLE_CRYPTO_RANDOM
+ XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_NOASM) -w -std=c99 -Wno-error=uninitialized -DOPENSSL_NO_APPLE_CRYPTO_RANDOM
#
# AARCH64 uses strict alignment and avoids SIMD registers for code that may execute
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf
index 780d5fe..bbcf748 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf
@@ -1,7 +1,7 @@
## @file
# This module provides OpenSSL Library implementation with ECC and TLS
# features along with performance optimized implementations of SHA1,
-# SHA256, SHA512 AESNI, VPAED, and GHASH for IA32 and X64.
+# SHA256, SHA512 AESNI, VPAED, and GHASH for IA32 and X64 and AARCH64.
#
# This library should be used if a module module needs ECC in TLS, or
# asymmetric cryptography services such as X509 certificate or PEM format
@@ -10,6 +10,7 @@
#
# Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>
# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+# Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -29,14 +30,14 @@
DEFINE OPENSSL_FLAGS = -DL_ENDIAN -DOPENSSL_SMALL_FOOTPRINT -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
DEFINE OPENSSL_FLAGS_IA32 = -DAES_ASM -DGHASH_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM
DEFINE OPENSSL_FLAGS_X64 = -DAES_ASM -DBSAES_ASM -DGHASH_ASM -DKECCAK1600_ASM -DMD5_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM
+ DEFINE OPENSSL_FLAGS_AARCH64 = -DKECCAK1600_ASM -DOPENSSL_CPUID_OBJ -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DVPAES_ASM
#
-# VALID_ARCHITECTURES = IA32 X64
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
#
[Sources]
OpensslLibConstructor.c
- $(OPENSSL_PATH)/e_os.h
$(OPENSSL_PATH)/ms/uplink.h
$(OPENSSL_PATH)/crypto/bn/bn_asm.c
# Autogenerated files list starts here
@@ -1429,6 +1430,679 @@
$(OPENSSL_GEN_PATH)/X64-GCC/crypto/sha/sha512-x86_64.s | GCC
# Autogenerated files list ends here
+[Sources.AARCH64]
+ OpensslStub/AArch64Cap.c
+# Autogenerated files list starts here
+ $(OPENSSL_PATH)/crypto/aes/aes_cbc.c
+ $(OPENSSL_PATH)/crypto/aes/aes_cfb.c
+ $(OPENSSL_PATH)/crypto/aes/aes_core.c
+ $(OPENSSL_PATH)/crypto/aes/aes_ecb.c
+ $(OPENSSL_PATH)/crypto/aes/aes_ige.c
+ $(OPENSSL_PATH)/crypto/aes/aes_misc.c
+ $(OPENSSL_PATH)/crypto/aes/aes_ofb.c
+ $(OPENSSL_PATH)/crypto/aes/aes_wrap.c
+ $(OPENSSL_PATH)/crypto/asn1/a_bitstr.c
+ $(OPENSSL_PATH)/crypto/asn1/a_d2i_fp.c
+ $(OPENSSL_PATH)/crypto/asn1/a_digest.c
+ $(OPENSSL_PATH)/crypto/asn1/a_dup.c
+ $(OPENSSL_PATH)/crypto/asn1/a_gentm.c
+ $(OPENSSL_PATH)/crypto/asn1/a_i2d_fp.c
+ $(OPENSSL_PATH)/crypto/asn1/a_int.c
+ $(OPENSSL_PATH)/crypto/asn1/a_mbstr.c
+ $(OPENSSL_PATH)/crypto/asn1/a_object.c
+ $(OPENSSL_PATH)/crypto/asn1/a_octet.c
+ $(OPENSSL_PATH)/crypto/asn1/a_print.c
+ $(OPENSSL_PATH)/crypto/asn1/a_sign.c
+ $(OPENSSL_PATH)/crypto/asn1/a_strex.c
+ $(OPENSSL_PATH)/crypto/asn1/a_strnid.c
+ $(OPENSSL_PATH)/crypto/asn1/a_time.c
+ $(OPENSSL_PATH)/crypto/asn1/a_type.c
+ $(OPENSSL_PATH)/crypto/asn1/a_utctm.c
+ $(OPENSSL_PATH)/crypto/asn1/a_utf8.c
+ $(OPENSSL_PATH)/crypto/asn1/a_verify.c
+ $(OPENSSL_PATH)/crypto/asn1/ameth_lib.c
+ $(OPENSSL_PATH)/crypto/asn1/asn1_err.c
+ $(OPENSSL_PATH)/crypto/asn1/asn1_gen.c
+ $(OPENSSL_PATH)/crypto/asn1/asn1_item_list.c
+ $(OPENSSL_PATH)/crypto/asn1/asn1_lib.c
+ $(OPENSSL_PATH)/crypto/asn1/asn1_parse.c
+ $(OPENSSL_PATH)/crypto/asn1/asn_mime.c
+ $(OPENSSL_PATH)/crypto/asn1/asn_moid.c
+ $(OPENSSL_PATH)/crypto/asn1/asn_mstbl.c
+ $(OPENSSL_PATH)/crypto/asn1/asn_pack.c
+ $(OPENSSL_PATH)/crypto/asn1/bio_asn1.c
+ $(OPENSSL_PATH)/crypto/asn1/bio_ndef.c
+ $(OPENSSL_PATH)/crypto/asn1/d2i_param.c
+ $(OPENSSL_PATH)/crypto/asn1/d2i_pr.c
+ $(OPENSSL_PATH)/crypto/asn1/d2i_pu.c
+ $(OPENSSL_PATH)/crypto/asn1/evp_asn1.c
+ $(OPENSSL_PATH)/crypto/asn1/f_int.c
+ $(OPENSSL_PATH)/crypto/asn1/f_string.c
+ $(OPENSSL_PATH)/crypto/asn1/i2d_evp.c
+ $(OPENSSL_PATH)/crypto/asn1/nsseq.c
+ $(OPENSSL_PATH)/crypto/asn1/p5_pbe.c
+ $(OPENSSL_PATH)/crypto/asn1/p5_pbev2.c
+ $(OPENSSL_PATH)/crypto/asn1/p5_scrypt.c
+ $(OPENSSL_PATH)/crypto/asn1/p8_pkey.c
+ $(OPENSSL_PATH)/crypto/asn1/t_bitst.c
+ $(OPENSSL_PATH)/crypto/asn1/t_pkey.c
+ $(OPENSSL_PATH)/crypto/asn1/t_spki.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_dec.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_enc.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_fre.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_new.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_prn.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_scn.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_typ.c
+ $(OPENSSL_PATH)/crypto/asn1/tasn_utl.c
+ $(OPENSSL_PATH)/crypto/asn1/x_algor.c
+ $(OPENSSL_PATH)/crypto/asn1/x_bignum.c
+ $(OPENSSL_PATH)/crypto/asn1/x_info.c
+ $(OPENSSL_PATH)/crypto/asn1/x_int64.c
+ $(OPENSSL_PATH)/crypto/asn1/x_long.c
+ $(OPENSSL_PATH)/crypto/asn1/x_pkey.c
+ $(OPENSSL_PATH)/crypto/asn1/x_sig.c
+ $(OPENSSL_PATH)/crypto/asn1/x_spki.c
+ $(OPENSSL_PATH)/crypto/asn1/x_val.c
+ $(OPENSSL_PATH)/crypto/async/arch/async_null.c
+ $(OPENSSL_PATH)/crypto/async/arch/async_posix.c
+ $(OPENSSL_PATH)/crypto/async/arch/async_win.c
+ $(OPENSSL_PATH)/crypto/async/async.c
+ $(OPENSSL_PATH)/crypto/async/async_err.c
+ $(OPENSSL_PATH)/crypto/async/async_wait.c
+ $(OPENSSL_PATH)/crypto/bio/bf_buff.c
+ $(OPENSSL_PATH)/crypto/bio/bf_lbuf.c
+ $(OPENSSL_PATH)/crypto/bio/bf_nbio.c
+ $(OPENSSL_PATH)/crypto/bio/bf_null.c
+ $(OPENSSL_PATH)/crypto/bio/bf_prefix.c
+ $(OPENSSL_PATH)/crypto/bio/bf_readbuff.c
+ $(OPENSSL_PATH)/crypto/bio/bio_addr.c
+ $(OPENSSL_PATH)/crypto/bio/bio_cb.c
+ $(OPENSSL_PATH)/crypto/bio/bio_dump.c
+ $(OPENSSL_PATH)/crypto/bio/bio_err.c
+ $(OPENSSL_PATH)/crypto/bio/bio_lib.c
+ $(OPENSSL_PATH)/crypto/bio/bio_meth.c
+ $(OPENSSL_PATH)/crypto/bio/bio_print.c
+ $(OPENSSL_PATH)/crypto/bio/bio_sock.c
+ $(OPENSSL_PATH)/crypto/bio/bio_sock2.c
+ $(OPENSSL_PATH)/crypto/bio/bss_acpt.c
+ $(OPENSSL_PATH)/crypto/bio/bss_bio.c
+ $(OPENSSL_PATH)/crypto/bio/bss_conn.c
+ $(OPENSSL_PATH)/crypto/bio/bss_core.c
+ $(OPENSSL_PATH)/crypto/bio/bss_dgram.c
+ $(OPENSSL_PATH)/crypto/bio/bss_fd.c
+ $(OPENSSL_PATH)/crypto/bio/bss_file.c
+ $(OPENSSL_PATH)/crypto/bio/bss_log.c
+ $(OPENSSL_PATH)/crypto/bio/bss_mem.c
+ $(OPENSSL_PATH)/crypto/bio/bss_null.c
+ $(OPENSSL_PATH)/crypto/bio/bss_sock.c
+ $(OPENSSL_PATH)/crypto/bio/ossl_core_bio.c
+ $(OPENSSL_PATH)/crypto/bn/bn_add.c
+ $(OPENSSL_PATH)/crypto/bn/bn_asm.c
+ $(OPENSSL_PATH)/crypto/bn/bn_blind.c
+ $(OPENSSL_PATH)/crypto/bn/bn_const.c
+ $(OPENSSL_PATH)/crypto/bn/bn_conv.c
+ $(OPENSSL_PATH)/crypto/bn/bn_ctx.c
+ $(OPENSSL_PATH)/crypto/bn/bn_dh.c
+ $(OPENSSL_PATH)/crypto/bn/bn_div.c
+ $(OPENSSL_PATH)/crypto/bn/bn_err.c
+ $(OPENSSL_PATH)/crypto/bn/bn_exp.c
+ $(OPENSSL_PATH)/crypto/bn/bn_exp2.c
+ $(OPENSSL_PATH)/crypto/bn/bn_gcd.c
+ $(OPENSSL_PATH)/crypto/bn/bn_gf2m.c
+ $(OPENSSL_PATH)/crypto/bn/bn_intern.c
+ $(OPENSSL_PATH)/crypto/bn/bn_kron.c
+ $(OPENSSL_PATH)/crypto/bn/bn_lib.c
+ $(OPENSSL_PATH)/crypto/bn/bn_mod.c
+ $(OPENSSL_PATH)/crypto/bn/bn_mont.c
+ $(OPENSSL_PATH)/crypto/bn/bn_mpi.c
+ $(OPENSSL_PATH)/crypto/bn/bn_mul.c
+ $(OPENSSL_PATH)/crypto/bn/bn_nist.c
+ $(OPENSSL_PATH)/crypto/bn/bn_prime.c
+ $(OPENSSL_PATH)/crypto/bn/bn_print.c
+ $(OPENSSL_PATH)/crypto/bn/bn_rand.c
+ $(OPENSSL_PATH)/crypto/bn/bn_recp.c
+ $(OPENSSL_PATH)/crypto/bn/bn_rsa_fips186_4.c
+ $(OPENSSL_PATH)/crypto/bn/bn_shift.c
+ $(OPENSSL_PATH)/crypto/bn/bn_sqr.c
+ $(OPENSSL_PATH)/crypto/bn/bn_sqrt.c
+ $(OPENSSL_PATH)/crypto/bn/bn_srp.c
+ $(OPENSSL_PATH)/crypto/bn/bn_word.c
+ $(OPENSSL_PATH)/crypto/bn/bn_x931p.c
+ $(OPENSSL_PATH)/crypto/buffer/buf_err.c
+ $(OPENSSL_PATH)/crypto/buffer/buffer.c
+ $(OPENSSL_PATH)/crypto/comp/c_zlib.c
+ $(OPENSSL_PATH)/crypto/comp/comp_err.c
+ $(OPENSSL_PATH)/crypto/comp/comp_lib.c
+ $(OPENSSL_PATH)/crypto/conf/conf_api.c
+ $(OPENSSL_PATH)/crypto/conf/conf_def.c
+ $(OPENSSL_PATH)/crypto/conf/conf_err.c
+ $(OPENSSL_PATH)/crypto/conf/conf_lib.c
+ $(OPENSSL_PATH)/crypto/conf/conf_mall.c
+ $(OPENSSL_PATH)/crypto/conf/conf_mod.c
+ $(OPENSSL_PATH)/crypto/conf/conf_sap.c
+ $(OPENSSL_PATH)/crypto/conf/conf_ssl.c
+ $(OPENSSL_PATH)/crypto/dh/dh_ameth.c
+ $(OPENSSL_PATH)/crypto/dh/dh_asn1.c
+ $(OPENSSL_PATH)/crypto/dh/dh_backend.c
+ $(OPENSSL_PATH)/crypto/dh/dh_check.c
+ $(OPENSSL_PATH)/crypto/dh/dh_err.c
+ $(OPENSSL_PATH)/crypto/dh/dh_gen.c
+ $(OPENSSL_PATH)/crypto/dh/dh_group_params.c
+ $(OPENSSL_PATH)/crypto/dh/dh_kdf.c
+ $(OPENSSL_PATH)/crypto/dh/dh_key.c
+ $(OPENSSL_PATH)/crypto/dh/dh_lib.c
+ $(OPENSSL_PATH)/crypto/dh/dh_meth.c
+ $(OPENSSL_PATH)/crypto/dh/dh_pmeth.c
+ $(OPENSSL_PATH)/crypto/dh/dh_prn.c
+ $(OPENSSL_PATH)/crypto/dh/dh_rfc5114.c
+ $(OPENSSL_PATH)/crypto/dso/dso_dl.c
+ $(OPENSSL_PATH)/crypto/dso/dso_dlfcn.c
+ $(OPENSSL_PATH)/crypto/dso/dso_err.c
+ $(OPENSSL_PATH)/crypto/dso/dso_lib.c
+ $(OPENSSL_PATH)/crypto/dso/dso_openssl.c
+ $(OPENSSL_PATH)/crypto/dso/dso_vms.c
+ $(OPENSSL_PATH)/crypto/dso/dso_win32.c
+ $(OPENSSL_PATH)/crypto/ec/curve448/arch_32/f_impl32.c
+ $(OPENSSL_PATH)/crypto/ec/curve448/arch_64/f_impl64.c
+ $(OPENSSL_PATH)/crypto/ec/curve448/curve448.c
+ $(OPENSSL_PATH)/crypto/ec/curve448/curve448_tables.c
+ $(OPENSSL_PATH)/crypto/ec/curve448/eddsa.c
+ $(OPENSSL_PATH)/crypto/ec/curve448/f_generic.c
+ $(OPENSSL_PATH)/crypto/ec/curve448/scalar.c
+ $(OPENSSL_PATH)/crypto/ec/curve25519.c
+ $(OPENSSL_PATH)/crypto/ec/ec2_oct.c
+ $(OPENSSL_PATH)/crypto/ec/ec2_smpl.c
+ $(OPENSSL_PATH)/crypto/ec/ec_ameth.c
+ $(OPENSSL_PATH)/crypto/ec/ec_asn1.c
+ $(OPENSSL_PATH)/crypto/ec/ec_backend.c
+ $(OPENSSL_PATH)/crypto/ec/ec_check.c
+ $(OPENSSL_PATH)/crypto/ec/ec_curve.c
+ $(OPENSSL_PATH)/crypto/ec/ec_cvt.c
+ $(OPENSSL_PATH)/crypto/ec/ec_deprecated.c
+ $(OPENSSL_PATH)/crypto/ec/ec_err.c
+ $(OPENSSL_PATH)/crypto/ec/ec_key.c
+ $(OPENSSL_PATH)/crypto/ec/ec_kmeth.c
+ $(OPENSSL_PATH)/crypto/ec/ec_lib.c
+ $(OPENSSL_PATH)/crypto/ec/ec_mult.c
+ $(OPENSSL_PATH)/crypto/ec/ec_oct.c
+ $(OPENSSL_PATH)/crypto/ec/ec_pmeth.c
+ $(OPENSSL_PATH)/crypto/ec/ec_print.c
+ $(OPENSSL_PATH)/crypto/ec/ecdh_kdf.c
+ $(OPENSSL_PATH)/crypto/ec/ecdh_ossl.c
+ $(OPENSSL_PATH)/crypto/ec/ecdsa_ossl.c
+ $(OPENSSL_PATH)/crypto/ec/ecdsa_sign.c
+ $(OPENSSL_PATH)/crypto/ec/ecdsa_vrf.c
+ $(OPENSSL_PATH)/crypto/ec/eck_prn.c
+ $(OPENSSL_PATH)/crypto/ec/ecp_mont.c
+ $(OPENSSL_PATH)/crypto/ec/ecp_nist.c
+ $(OPENSSL_PATH)/crypto/ec/ecp_oct.c
+ $(OPENSSL_PATH)/crypto/ec/ecp_smpl.c
+ $(OPENSSL_PATH)/crypto/ec/ecx_backend.c
+ $(OPENSSL_PATH)/crypto/ec/ecx_key.c
+ $(OPENSSL_PATH)/crypto/ec/ecx_meth.c
+ $(OPENSSL_PATH)/crypto/encode_decode/decoder_err.c
+ $(OPENSSL_PATH)/crypto/encode_decode/decoder_lib.c
+ $(OPENSSL_PATH)/crypto/encode_decode/decoder_meth.c
+ $(OPENSSL_PATH)/crypto/encode_decode/decoder_pkey.c
+ $(OPENSSL_PATH)/crypto/err/err.c
+ $(OPENSSL_PATH)/crypto/err/err_all.c
+ $(OPENSSL_PATH)/crypto/err/err_all_legacy.c
+ $(OPENSSL_PATH)/crypto/err/err_blocks.c
+ $(OPENSSL_PATH)/crypto/err/err_prn.c
+ $(OPENSSL_PATH)/crypto/ess/ess_asn1.c
+ $(OPENSSL_PATH)/crypto/ess/ess_err.c
+ $(OPENSSL_PATH)/crypto/ess/ess_lib.c
+ $(OPENSSL_PATH)/crypto/evp/asymcipher.c
+ $(OPENSSL_PATH)/crypto/evp/bio_b64.c
+ $(OPENSSL_PATH)/crypto/evp/bio_enc.c
+ $(OPENSSL_PATH)/crypto/evp/bio_md.c
+ $(OPENSSL_PATH)/crypto/evp/bio_ok.c
+ $(OPENSSL_PATH)/crypto/evp/c_allc.c
+ $(OPENSSL_PATH)/crypto/evp/c_alld.c
+ $(OPENSSL_PATH)/crypto/evp/cmeth_lib.c
+ $(OPENSSL_PATH)/crypto/evp/ctrl_params_translate.c
+ $(OPENSSL_PATH)/crypto/evp/dh_ctrl.c
+ $(OPENSSL_PATH)/crypto/evp/dh_support.c
+ $(OPENSSL_PATH)/crypto/evp/digest.c
+ $(OPENSSL_PATH)/crypto/evp/dsa_ctrl.c
+ $(OPENSSL_PATH)/crypto/evp/e_aes.c
+ $(OPENSSL_PATH)/crypto/evp/e_aes_cbc_hmac_sha1.c
+ $(OPENSSL_PATH)/crypto/evp/e_aes_cbc_hmac_sha256.c
+ $(OPENSSL_PATH)/crypto/evp/e_aria.c
+ $(OPENSSL_PATH)/crypto/evp/e_bf.c
+ $(OPENSSL_PATH)/crypto/evp/e_cast.c
+ $(OPENSSL_PATH)/crypto/evp/e_chacha20_poly1305.c
+ $(OPENSSL_PATH)/crypto/evp/e_des.c
+ $(OPENSSL_PATH)/crypto/evp/e_des3.c
+ $(OPENSSL_PATH)/crypto/evp/e_idea.c
+ $(OPENSSL_PATH)/crypto/evp/e_null.c
+ $(OPENSSL_PATH)/crypto/evp/e_rc2.c
+ $(OPENSSL_PATH)/crypto/evp/e_rc4.c
+ $(OPENSSL_PATH)/crypto/evp/e_rc4_hmac_md5.c
+ $(OPENSSL_PATH)/crypto/evp/e_rc5.c
+ $(OPENSSL_PATH)/crypto/evp/e_sm4.c
+ $(OPENSSL_PATH)/crypto/evp/e_xcbc_d.c
+ $(OPENSSL_PATH)/crypto/evp/ec_ctrl.c
+ $(OPENSSL_PATH)/crypto/evp/ec_support.c
+ $(OPENSSL_PATH)/crypto/evp/encode.c
+ $(OPENSSL_PATH)/crypto/evp/evp_cnf.c
+ $(OPENSSL_PATH)/crypto/evp/evp_enc.c
+ $(OPENSSL_PATH)/crypto/evp/evp_err.c
+ $(OPENSSL_PATH)/crypto/evp/evp_fetch.c
+ $(OPENSSL_PATH)/crypto/evp/evp_key.c
+ $(OPENSSL_PATH)/crypto/evp/evp_lib.c
+ $(OPENSSL_PATH)/crypto/evp/evp_pbe.c
+ $(OPENSSL_PATH)/crypto/evp/evp_pkey.c
+ $(OPENSSL_PATH)/crypto/evp/evp_rand.c
+ $(OPENSSL_PATH)/crypto/evp/evp_utils.c
+ $(OPENSSL_PATH)/crypto/evp/exchange.c
+ $(OPENSSL_PATH)/crypto/evp/kdf_lib.c
+ $(OPENSSL_PATH)/crypto/evp/kdf_meth.c
+ $(OPENSSL_PATH)/crypto/evp/kem.c
+ $(OPENSSL_PATH)/crypto/evp/keymgmt_lib.c
+ $(OPENSSL_PATH)/crypto/evp/keymgmt_meth.c
+ $(OPENSSL_PATH)/crypto/evp/legacy_md5.c
+ $(OPENSSL_PATH)/crypto/evp/legacy_md5_sha1.c
+ $(OPENSSL_PATH)/crypto/evp/legacy_sha.c
+ $(OPENSSL_PATH)/crypto/evp/m_null.c
+ $(OPENSSL_PATH)/crypto/evp/m_sigver.c
+ $(OPENSSL_PATH)/crypto/evp/mac_lib.c
+ $(OPENSSL_PATH)/crypto/evp/mac_meth.c
+ $(OPENSSL_PATH)/crypto/evp/names.c
+ $(OPENSSL_PATH)/crypto/evp/p5_crpt.c
+ $(OPENSSL_PATH)/crypto/evp/p5_crpt2.c
+ $(OPENSSL_PATH)/crypto/evp/p_dec.c
+ $(OPENSSL_PATH)/crypto/evp/p_enc.c
+ $(OPENSSL_PATH)/crypto/evp/p_legacy.c
+ $(OPENSSL_PATH)/crypto/evp/p_lib.c
+ $(OPENSSL_PATH)/crypto/evp/p_open.c
+ $(OPENSSL_PATH)/crypto/evp/p_seal.c
+ $(OPENSSL_PATH)/crypto/evp/p_sign.c
+ $(OPENSSL_PATH)/crypto/evp/p_verify.c
+ $(OPENSSL_PATH)/crypto/evp/pbe_scrypt.c
+ $(OPENSSL_PATH)/crypto/evp/pmeth_check.c
+ $(OPENSSL_PATH)/crypto/evp/pmeth_gn.c
+ $(OPENSSL_PATH)/crypto/evp/pmeth_lib.c
+ $(OPENSSL_PATH)/crypto/evp/signature.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_backend.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_dh.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_key_generate.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_key_validate.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_params.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_params_generate.c
+ $(OPENSSL_PATH)/crypto/ffc/ffc_params_validate.c
+ $(OPENSSL_PATH)/crypto/hmac/hmac.c
+ $(OPENSSL_PATH)/crypto/http/http_client.c
+ $(OPENSSL_PATH)/crypto/http/http_err.c
+ $(OPENSSL_PATH)/crypto/http/http_lib.c
+ $(OPENSSL_PATH)/crypto/kdf/kdf_err.c
+ $(OPENSSL_PATH)/crypto/lhash/lh_stats.c
+ $(OPENSSL_PATH)/crypto/lhash/lhash.c
+ $(OPENSSL_PATH)/crypto/asn1_dsa.c
+ $(OPENSSL_PATH)/crypto/bsearch.c
+ $(OPENSSL_PATH)/crypto/context.c
+ $(OPENSSL_PATH)/crypto/core_algorithm.c
+ $(OPENSSL_PATH)/crypto/core_fetch.c
+ $(OPENSSL_PATH)/crypto/core_namemap.c
+ $(OPENSSL_PATH)/crypto/cpt_err.c
+ $(OPENSSL_PATH)/crypto/cpuid.c
+ $(OPENSSL_PATH)/crypto/cryptlib.c
+ $(OPENSSL_PATH)/crypto/ctype.c
+ $(OPENSSL_PATH)/crypto/cversion.c
+ $(OPENSSL_PATH)/crypto/der_writer.c
+ $(OPENSSL_PATH)/crypto/ebcdic.c
+ $(OPENSSL_PATH)/crypto/ex_data.c
+ $(OPENSSL_PATH)/crypto/getenv.c
+ $(OPENSSL_PATH)/crypto/info.c
+ $(OPENSSL_PATH)/crypto/init.c
+ $(OPENSSL_PATH)/crypto/initthread.c
+ $(OPENSSL_PATH)/crypto/mem.c
+ $(OPENSSL_PATH)/crypto/mem_sec.c
+ $(OPENSSL_PATH)/crypto/o_dir.c
+ $(OPENSSL_PATH)/crypto/o_fopen.c
+ $(OPENSSL_PATH)/crypto/o_init.c
+ $(OPENSSL_PATH)/crypto/o_str.c
+ $(OPENSSL_PATH)/crypto/o_time.c
+ $(OPENSSL_PATH)/crypto/packet.c
+ $(OPENSSL_PATH)/crypto/param_build.c
+ $(OPENSSL_PATH)/crypto/param_build_set.c
+ $(OPENSSL_PATH)/crypto/params.c
+ $(OPENSSL_PATH)/crypto/params_dup.c
+ $(OPENSSL_PATH)/crypto/params_from_text.c
+ $(OPENSSL_PATH)/crypto/passphrase.c
+ $(OPENSSL_PATH)/crypto/provider.c
+ $(OPENSSL_PATH)/crypto/provider_child.c
+ $(OPENSSL_PATH)/crypto/provider_conf.c
+ $(OPENSSL_PATH)/crypto/provider_core.c
+ $(OPENSSL_PATH)/crypto/punycode.c
+ $(OPENSSL_PATH)/crypto/self_test_core.c
+ $(OPENSSL_PATH)/crypto/sparse_array.c
+ $(OPENSSL_PATH)/crypto/threads_lib.c
+ $(OPENSSL_PATH)/crypto/threads_none.c
+ $(OPENSSL_PATH)/crypto/threads_pthread.c
+ $(OPENSSL_PATH)/crypto/threads_win.c
+ $(OPENSSL_PATH)/crypto/trace.c
+ $(OPENSSL_PATH)/crypto/uid.c
+ $(OPENSSL_PATH)/crypto/md5/md5_dgst.c
+ $(OPENSSL_PATH)/crypto/md5/md5_one.c
+ $(OPENSSL_PATH)/crypto/md5/md5_sha1.c
+ $(OPENSSL_PATH)/crypto/modes/cbc128.c
+ $(OPENSSL_PATH)/crypto/modes/ccm128.c
+ $(OPENSSL_PATH)/crypto/modes/cfb128.c
+ $(OPENSSL_PATH)/crypto/modes/ctr128.c
+ $(OPENSSL_PATH)/crypto/modes/cts128.c
+ $(OPENSSL_PATH)/crypto/modes/gcm128.c
+ $(OPENSSL_PATH)/crypto/modes/ocb128.c
+ $(OPENSSL_PATH)/crypto/modes/ofb128.c
+ $(OPENSSL_PATH)/crypto/modes/siv128.c
+ $(OPENSSL_PATH)/crypto/modes/wrap128.c
+ $(OPENSSL_PATH)/crypto/modes/xts128.c
+ $(OPENSSL_PATH)/crypto/objects/o_names.c
+ $(OPENSSL_PATH)/crypto/objects/obj_dat.c
+ $(OPENSSL_PATH)/crypto/objects/obj_err.c
+ $(OPENSSL_PATH)/crypto/objects/obj_lib.c
+ $(OPENSSL_PATH)/crypto/objects/obj_xref.c
+ $(OPENSSL_PATH)/crypto/pem/pem_all.c
+ $(OPENSSL_PATH)/crypto/pem/pem_err.c
+ $(OPENSSL_PATH)/crypto/pem/pem_info.c
+ $(OPENSSL_PATH)/crypto/pem/pem_lib.c
+ $(OPENSSL_PATH)/crypto/pem/pem_oth.c
+ $(OPENSSL_PATH)/crypto/pem/pem_pk8.c
+ $(OPENSSL_PATH)/crypto/pem/pem_pkey.c
+ $(OPENSSL_PATH)/crypto/pem/pem_sign.c
+ $(OPENSSL_PATH)/crypto/pem/pem_x509.c
+ $(OPENSSL_PATH)/crypto/pem/pem_xaux.c
+ $(OPENSSL_PATH)/crypto/pem/pvkfmt.c
+ $(OPENSSL_PATH)/crypto/pkcs7/bio_pk7.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_asn1.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_attr.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_doit.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_lib.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_mime.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pk7_smime.c
+ $(OPENSSL_PATH)/crypto/pkcs7/pkcs7err.c
+ $(OPENSSL_PATH)/crypto/property/defn_cache.c
+ $(OPENSSL_PATH)/crypto/property/property.c
+ $(OPENSSL_PATH)/crypto/property/property_err.c
+ $(OPENSSL_PATH)/crypto/property/property_parse.c
+ $(OPENSSL_PATH)/crypto/property/property_query.c
+ $(OPENSSL_PATH)/crypto/property/property_string.c
+ $(OPENSSL_PATH)/crypto/rand/prov_seed.c
+ $(OPENSSL_PATH)/crypto/rand/rand_deprecated.c
+ $(OPENSSL_PATH)/crypto/rand/rand_err.c
+ $(OPENSSL_PATH)/crypto/rand/rand_lib.c
+ $(OPENSSL_PATH)/crypto/rand/rand_meth.c
+ $(OPENSSL_PATH)/crypto/rand/rand_pool.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_ameth.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_asn1.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_backend.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_chk.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_crpt.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_err.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_gen.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_lib.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_meth.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_mp.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_mp_names.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_none.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_oaep.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_ossl.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_pk1.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_pmeth.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_prn.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_pss.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_saos.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_schemes.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_sign.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_sp800_56b_check.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_sp800_56b_gen.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_x931.c
+ $(OPENSSL_PATH)/crypto/rsa/rsa_x931g.c
+ $(OPENSSL_PATH)/crypto/sha/sha1_one.c
+ $(OPENSSL_PATH)/crypto/sha/sha1dgst.c
+ $(OPENSSL_PATH)/crypto/sha/sha256.c
+ $(OPENSSL_PATH)/crypto/sha/sha3.c
+ $(OPENSSL_PATH)/crypto/sha/sha512.c
+ $(OPENSSL_PATH)/crypto/sm3/legacy_sm3.c
+ $(OPENSSL_PATH)/crypto/sm3/sm3.c
+ $(OPENSSL_PATH)/crypto/stack/stack.c
+ $(OPENSSL_PATH)/crypto/txt_db/txt_db.c
+ $(OPENSSL_PATH)/crypto/ui/ui_err.c
+ $(OPENSSL_PATH)/crypto/ui/ui_lib.c
+ $(OPENSSL_PATH)/crypto/ui/ui_null.c
+ $(OPENSSL_PATH)/crypto/ui/ui_openssl.c
+ $(OPENSSL_PATH)/crypto/ui/ui_util.c
+ $(OPENSSL_PATH)/crypto/x509/by_dir.c
+ $(OPENSSL_PATH)/crypto/x509/by_file.c
+ $(OPENSSL_PATH)/crypto/x509/by_store.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_cache.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_data.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_lib.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_map.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_node.c
+ $(OPENSSL_PATH)/crypto/x509/pcy_tree.c
+ $(OPENSSL_PATH)/crypto/x509/t_crl.c
+ $(OPENSSL_PATH)/crypto/x509/t_req.c
+ $(OPENSSL_PATH)/crypto/x509/t_x509.c
+ $(OPENSSL_PATH)/crypto/x509/v3_addr.c
+ $(OPENSSL_PATH)/crypto/x509/v3_admis.c
+ $(OPENSSL_PATH)/crypto/x509/v3_akeya.c
+ $(OPENSSL_PATH)/crypto/x509/v3_akid.c
+ $(OPENSSL_PATH)/crypto/x509/v3_asid.c
+ $(OPENSSL_PATH)/crypto/x509/v3_bcons.c
+ $(OPENSSL_PATH)/crypto/x509/v3_bitst.c
+ $(OPENSSL_PATH)/crypto/x509/v3_conf.c
+ $(OPENSSL_PATH)/crypto/x509/v3_cpols.c
+ $(OPENSSL_PATH)/crypto/x509/v3_crld.c
+ $(OPENSSL_PATH)/crypto/x509/v3_enum.c
+ $(OPENSSL_PATH)/crypto/x509/v3_extku.c
+ $(OPENSSL_PATH)/crypto/x509/v3_genn.c
+ $(OPENSSL_PATH)/crypto/x509/v3_ia5.c
+ $(OPENSSL_PATH)/crypto/x509/v3_info.c
+ $(OPENSSL_PATH)/crypto/x509/v3_int.c
+ $(OPENSSL_PATH)/crypto/x509/v3_ist.c
+ $(OPENSSL_PATH)/crypto/x509/v3_lib.c
+ $(OPENSSL_PATH)/crypto/x509/v3_ncons.c
+ $(OPENSSL_PATH)/crypto/x509/v3_pci.c
+ $(OPENSSL_PATH)/crypto/x509/v3_pcia.c
+ $(OPENSSL_PATH)/crypto/x509/v3_pcons.c
+ $(OPENSSL_PATH)/crypto/x509/v3_pku.c
+ $(OPENSSL_PATH)/crypto/x509/v3_pmaps.c
+ $(OPENSSL_PATH)/crypto/x509/v3_prn.c
+ $(OPENSSL_PATH)/crypto/x509/v3_purp.c
+ $(OPENSSL_PATH)/crypto/x509/v3_san.c
+ $(OPENSSL_PATH)/crypto/x509/v3_skid.c
+ $(OPENSSL_PATH)/crypto/x509/v3_sxnet.c
+ $(OPENSSL_PATH)/crypto/x509/v3_tlsf.c
+ $(OPENSSL_PATH)/crypto/x509/v3_utf8.c
+ $(OPENSSL_PATH)/crypto/x509/v3_utl.c
+ $(OPENSSL_PATH)/crypto/x509/v3err.c
+ $(OPENSSL_PATH)/crypto/x509/x509_att.c
+ $(OPENSSL_PATH)/crypto/x509/x509_cmp.c
+ $(OPENSSL_PATH)/crypto/x509/x509_d2.c
+ $(OPENSSL_PATH)/crypto/x509/x509_def.c
+ $(OPENSSL_PATH)/crypto/x509/x509_err.c
+ $(OPENSSL_PATH)/crypto/x509/x509_ext.c
+ $(OPENSSL_PATH)/crypto/x509/x509_lu.c
+ $(OPENSSL_PATH)/crypto/x509/x509_meth.c
+ $(OPENSSL_PATH)/crypto/x509/x509_obj.c
+ $(OPENSSL_PATH)/crypto/x509/x509_r2x.c
+ $(OPENSSL_PATH)/crypto/x509/x509_req.c
+ $(OPENSSL_PATH)/crypto/x509/x509_set.c
+ $(OPENSSL_PATH)/crypto/x509/x509_trust.c
+ $(OPENSSL_PATH)/crypto/x509/x509_txt.c
+ $(OPENSSL_PATH)/crypto/x509/x509_v3.c
+ $(OPENSSL_PATH)/crypto/x509/x509_vfy.c
+ $(OPENSSL_PATH)/crypto/x509/x509_vpm.c
+ $(OPENSSL_PATH)/crypto/x509/x509cset.c
+ $(OPENSSL_PATH)/crypto/x509/x509name.c
+ $(OPENSSL_PATH)/crypto/x509/x509rset.c
+ $(OPENSSL_PATH)/crypto/x509/x509spki.c
+ $(OPENSSL_PATH)/crypto/x509/x509type.c
+ $(OPENSSL_PATH)/crypto/x509/x_all.c
+ $(OPENSSL_PATH)/crypto/x509/x_attrib.c
+ $(OPENSSL_PATH)/crypto/x509/x_crl.c
+ $(OPENSSL_PATH)/crypto/x509/x_exten.c
+ $(OPENSSL_PATH)/crypto/x509/x_name.c
+ $(OPENSSL_PATH)/crypto/x509/x_pubkey.c
+ $(OPENSSL_PATH)/crypto/x509/x_req.c
+ $(OPENSSL_PATH)/crypto/x509/x_x509.c
+ $(OPENSSL_PATH)/crypto/x509/x_x509a.c
+ $(OPENSSL_PATH)/providers/nullprov.c
+ $(OPENSSL_PATH)/providers/prov_running.c
+ $(OPENSSL_PATH)/providers/common/der/der_rsa_sig.c
+ $(OPENSSL_PATH)/providers/common/bio_prov.c
+ $(OPENSSL_PATH)/providers/common/capabilities.c
+ $(OPENSSL_PATH)/providers/common/digest_to_nid.c
+ $(OPENSSL_PATH)/providers/common/provider_seeding.c
+ $(OPENSSL_PATH)/providers/common/provider_util.c
+ $(OPENSSL_PATH)/providers/common/securitycheck.c
+ $(OPENSSL_PATH)/providers/common/securitycheck_default.c
+ $(OPENSSL_PATH)/providers/implementations/asymciphers/rsa_enc.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_ccm.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_ccm_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_gcm.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_gcm_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_wrp.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts_fips.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_aes_xts_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_cts.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/cipher_null.c
+ $(OPENSSL_PATH)/providers/implementations/digests/md5_prov.c
+ $(OPENSSL_PATH)/providers/implementations/digests/md5_sha1_prov.c
+ $(OPENSSL_PATH)/providers/implementations/digests/null_prov.c
+ $(OPENSSL_PATH)/providers/implementations/digests/sha2_prov.c
+ $(OPENSSL_PATH)/providers/implementations/digests/sha3_prov.c
+ $(OPENSSL_PATH)/providers/implementations/digests/sm3_prov.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_der2key.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_epki2pki.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_msblob2key.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_pem2der.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_pvk2key.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/decode_spki2typespki.c
+ $(OPENSSL_PATH)/providers/implementations/encode_decode/endecoder_common.c
+ $(OPENSSL_PATH)/providers/implementations/exchange/dh_exch.c
+ $(OPENSSL_PATH)/providers/implementations/exchange/ecdh_exch.c
+ $(OPENSSL_PATH)/providers/implementations/exchange/ecx_exch.c
+ $(OPENSSL_PATH)/providers/implementations/exchange/kdf_exch.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/hkdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/kbkdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/krb5kdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/pbkdf2.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/pbkdf2_fips.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/pkcs12kdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/scrypt.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/sshkdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/sskdf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/tls1_prf.c
+ $(OPENSSL_PATH)/providers/implementations/kdfs/x942kdf.c
+ $(OPENSSL_PATH)/providers/implementations/kem/rsa_kem.c
+ $(OPENSSL_PATH)/providers/implementations/keymgmt/dh_kmgmt.c
+ $(OPENSSL_PATH)/providers/implementations/keymgmt/ec_kmgmt.c
+ $(OPENSSL_PATH)/providers/implementations/keymgmt/ecx_kmgmt.c
+ $(OPENSSL_PATH)/providers/implementations/keymgmt/kdf_legacy_kmgmt.c
+ $(OPENSSL_PATH)/providers/implementations/keymgmt/mac_legacy_kmgmt.c
+ $(OPENSSL_PATH)/providers/implementations/keymgmt/rsa_kmgmt.c
+ $(OPENSSL_PATH)/providers/implementations/macs/gmac_prov.c
+ $(OPENSSL_PATH)/providers/implementations/macs/hmac_prov.c
+ $(OPENSSL_PATH)/providers/implementations/macs/kmac_prov.c
+ $(OPENSSL_PATH)/providers/implementations/rands/crngt.c
+ $(OPENSSL_PATH)/providers/implementations/rands/drbg.c
+ $(OPENSSL_PATH)/providers/implementations/rands/drbg_ctr.c
+ $(OPENSSL_PATH)/providers/implementations/rands/drbg_hash.c
+ $(OPENSSL_PATH)/providers/implementations/rands/drbg_hmac.c
+ $(OPENSSL_PATH)/providers/implementations/rands/seed_src.c
+ $(OPENSSL_PATH)/providers/implementations/rands/test_rng.c
+ $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_cpu_x86.c
+ $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_tsc.c
+ $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_unix.c
+ $(OPENSSL_PATH)/providers/implementations/rands/seeding/rand_win.c
+ $(OPENSSL_PATH)/providers/implementations/signature/ecdsa_sig.c
+ $(OPENSSL_PATH)/providers/implementations/signature/eddsa_sig.c
+ $(OPENSSL_PATH)/providers/implementations/signature/mac_legacy_sig.c
+ $(OPENSSL_PATH)/providers/implementations/signature/rsa_sig.c
+ $(OPENSSL_PATH)/ssl/s3_cbc.c
+ $(OPENSSL_PATH)/providers/common/der/der_ec_key.c
+ $(OPENSSL_PATH)/providers/common/der/der_ec_sig.c
+ $(OPENSSL_PATH)/providers/common/der/der_ecx_key.c
+ $(OPENSSL_PATH)/providers/common/der/der_rsa_key.c
+ $(OPENSSL_PATH)/providers/common/provider_ctx.c
+ $(OPENSSL_PATH)/providers/common/provider_err.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_block.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_ccm.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_ccm_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_gcm.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_gcm_hw.c
+ $(OPENSSL_PATH)/providers/implementations/ciphers/ciphercommon_hw.c
+ $(OPENSSL_PATH)/providers/implementations/digests/digestcommon.c
+ $(OPENSSL_PATH)/ssl/record/tls_pad.c
+ $(OPENSSL_GEN_PATH)/providers/common/der/der_digests_gen.c
+ $(OPENSSL_GEN_PATH)/providers/common/der/der_ec_gen.c
+ $(OPENSSL_GEN_PATH)/providers/common/der/der_ecx_gen.c
+ $(OPENSSL_GEN_PATH)/providers/common/der/der_rsa_gen.c
+ $(OPENSSL_GEN_PATH)/providers/common/der/der_wrap_gen.c
+ $(OPENSSL_PATH)/ssl/bio_ssl.c
+ $(OPENSSL_PATH)/ssl/d1_lib.c
+ $(OPENSSL_PATH)/ssl/d1_msg.c
+ $(OPENSSL_PATH)/ssl/d1_srtp.c
+ $(OPENSSL_PATH)/ssl/methods.c
+ $(OPENSSL_PATH)/ssl/pqueue.c
+ $(OPENSSL_PATH)/ssl/s3_enc.c
+ $(OPENSSL_PATH)/ssl/s3_lib.c
+ $(OPENSSL_PATH)/ssl/s3_msg.c
+ $(OPENSSL_PATH)/ssl/ssl_asn1.c
+ $(OPENSSL_PATH)/ssl/ssl_cert.c
+ $(OPENSSL_PATH)/ssl/ssl_ciph.c
+ $(OPENSSL_PATH)/ssl/ssl_conf.c
+ $(OPENSSL_PATH)/ssl/ssl_err.c
+ $(OPENSSL_PATH)/ssl/ssl_err_legacy.c
+ $(OPENSSL_PATH)/ssl/ssl_init.c
+ $(OPENSSL_PATH)/ssl/ssl_lib.c
+ $(OPENSSL_PATH)/ssl/ssl_mcnf.c
+ $(OPENSSL_PATH)/ssl/ssl_rsa.c
+ $(OPENSSL_PATH)/ssl/ssl_rsa_legacy.c
+ $(OPENSSL_PATH)/ssl/ssl_sess.c
+ $(OPENSSL_PATH)/ssl/ssl_stat.c
+ $(OPENSSL_PATH)/ssl/ssl_txt.c
+ $(OPENSSL_PATH)/ssl/ssl_utst.c
+ $(OPENSSL_PATH)/ssl/t1_enc.c
+ $(OPENSSL_PATH)/ssl/t1_lib.c
+ $(OPENSSL_PATH)/ssl/t1_trce.c
+ $(OPENSSL_PATH)/ssl/tls13_enc.c
+ $(OPENSSL_PATH)/ssl/tls_depr.c
+ $(OPENSSL_PATH)/ssl/tls_srp.c
+ $(OPENSSL_PATH)/ssl/record/dtls1_bitmap.c
+ $(OPENSSL_PATH)/ssl/record/rec_layer_d1.c
+ $(OPENSSL_PATH)/ssl/record/rec_layer_s3.c
+ $(OPENSSL_PATH)/ssl/record/ssl3_buffer.c
+ $(OPENSSL_PATH)/ssl/record/ssl3_record.c
+ $(OPENSSL_PATH)/ssl/record/ssl3_record_tls13.c
+ $(OPENSSL_PATH)/ssl/statem/extensions.c
+ $(OPENSSL_PATH)/ssl/statem/extensions_clnt.c
+ $(OPENSSL_PATH)/ssl/statem/extensions_cust.c
+ $(OPENSSL_PATH)/ssl/statem/statem.c
+ $(OPENSSL_PATH)/ssl/statem/statem_clnt.c
+ $(OPENSSL_PATH)/ssl/statem/statem_dtls.c
+ $(OPENSSL_PATH)/ssl/statem/statem_lib.c
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/aes/aesv8-armx.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/aes/vpaes-armv8.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/arm64cpuid.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/modes/aes-gcm-armv8_64.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/modes/ghashv8-armx.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/keccak1600-armv8.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha1-armv8.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha256-armv8.S | GCC
+ $(OPENSSL_GEN_PATH)/AARCH64-GCC/crypto/sha/sha512-armv8.S | GCC
+# Autogenerated files list ends here
+
[Packages]
MdePkg/MdePkg.dec
CryptoPkg/CryptoPkg.dec
@@ -1480,7 +2154,7 @@
#
GCC:*_*_IA32_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_IA32) -Wno-error=maybe-uninitialized -Wno-error=unused-but-set-variable
GCC:*_*_X64_CC_FLAGS = -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_X64) -Wno-error=maybe-uninitialized -Wno-error=format -Wno-format -Wno-error=unused-but-set-variable -DNO_MSABI_VA_FUNCS
- GCC:*_CLANGDWARF_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize
+ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize
GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize
# Revisit after switching to 3.0 branch
GCC:*_GCC5_*_CC_FLAGS = -Wno-unused-but-set-variable
@@ -1504,5 +2178,18 @@
# 1: ignore "#1-D: last line of file ends without a newline"
# 3017: <entity> may be used before being set (NOTE: This was fixed in OpenSSL 1.1 HEAD with
# commit d9b8b89bec4480de3a10bdaf9425db371c19145b, and can be dropped then.)
- XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_IA32) -w -std=c99 -Wno-error=uninitialized
- XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_X64) -w -std=c99 -Wno-error=uninitialized
+ XCODE:*_*_IA32_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_IA32) -w -std=c99 -Wno-error=uninitialized -DOPENSSL_NO_APPLE_CRYPTO_RANDOM
+ XCODE:*_*_X64_CC_FLAGS = -mmmx -msse -U_WIN32 -U_WIN64 $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_X64) -w -std=c99 -Wno-error=uninitialized -DOPENSSL_NO_APPLE_CRYPTO_RANDOM
+
+ GCC:*_*_AARCH64_CC_FLAGS = $(OPENSSL_FLAGS) $(OPENSSL_FLAGS_AARCH64) -Wno-error=format -Wno-format -D_BITS_STDINT_UINTN_H -D_BITS_STDINT_INTN_H
+
+ #
+ # AARCH64 uses strict alignment and avoids SIMD registers for code that may execute
+ # with the MMU off. This involves SEC, PEI_CORE and PEIM modules as well as BASE
+ # libraries, given that they may be included into such modules.
+ # This library, even though of the BASE type, is never used in such cases, and
+ # avoiding the SIMD register file (which is shared with the FPU) prevents the
+ # compiler from successfully building some of the OpenSSL source files that
+ # use floating point types, so clear the flags here.
+ #
+ GCC:*_*_AARCH64_CC_XIPFLAGS ==
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibSm3.inf b/CryptoPkg/Library/OpensslLib/OpensslLibSm3.inf
new file mode 100644
index 0000000..9e36490
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslLibSm3.inf
@@ -0,0 +1,30 @@
+## @file
+# Minimal OpensslLib implementation that only provides SM3 and nothing else.
+# Needed by MbedTlsLib.
+#
+# Copyright (c) 2024, Google LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 1.30
+ BASE_NAME = OpensslLibSm3
+ FILE_GUID = 96469bab-9c3f-4a60-a583-71a8bda64ec9
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = OpensslLib
+
+ DEFINE OPENSSL_PATH = openssl
+
+[Sources]
+ $(OPENSSL_PATH)/crypto/sm3/sm3.c
+ OpensslStub/OpensslCleanse.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
diff --git a/CryptoPkg/Library/OpensslLib/OpensslStub/AArch64Cap.c b/CryptoPkg/Library/OpensslLib/OpensslStub/AArch64Cap.c
new file mode 100644
index 0000000..e45961a
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslStub/AArch64Cap.c
@@ -0,0 +1,107 @@
+/** @file
+ Arm capabilities probing.
+
+ Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <openssl/types.h>
+#include "crypto/arm_arch.h"
+
+#include <Library/BaseLib.h>
+
+/** Get bits from a value.
+
+ Shift the input value from 'shift' bits and apply 'mask'.
+
+ @param value The value to get the bits from.
+ @param shift Index of the bits to read.
+ @param mask Mask to apply to the value once shifted.
+
+ @return The desired bitfield from the value.
+**/
+#define GET_BITFIELD(value, shift, mask) \
+ ((value >> shift) & mask)
+
+UINT32 OPENSSL_armcap_P = 0;
+
+void
+OPENSSL_cpuid_setup (
+ void
+ )
+{
+ UINT64 Isar0;
+
+ OPENSSL_armcap_P = 0;
+ Isar0 = ArmReadIdAA64Isar0Reg ();
+
+ /* Access to EL0 registers is possible from higher ELx. */
+ OPENSSL_armcap_P |= ARMV8_CPUID;
+ /* Access to Physical timer is possible. */
+ OPENSSL_armcap_P |= ARMV7_TICK;
+
+ /* Neon support is not guaranteed, but it is assumed to be present.
+ Arm ARM for Armv8, sA1.5 Advanced SIMD and floating-point support
+ */
+ OPENSSL_armcap_P |= ARMV7_NEON;
+
+ if (GET_BITFIELD (
+ Isar0,
+ ARM_ID_AA64ISAR0_EL1_AES_SHIFT,
+ ARM_ID_AA64ISAR0_EL1_AES_MASK
+ ) != 0)
+ {
+ OPENSSL_armcap_P |= ARMV8_AES;
+ }
+
+ if (GET_BITFIELD (
+ Isar0,
+ ARM_ID_AA64ISAR0_EL1_SHA1_SHIFT,
+ ARM_ID_AA64ISAR0_EL1_SHA1_MASK
+ ) != 0)
+ {
+ OPENSSL_armcap_P |= ARMV8_SHA1;
+ }
+
+ if (GET_BITFIELD (
+ Isar0,
+ ARM_ID_AA64ISAR0_EL1_SHA2_SHIFT,
+ ARM_ID_AA64ISAR0_EL1_SHA2_MASK
+ ) != 0)
+ {
+ OPENSSL_armcap_P |= ARMV8_SHA256;
+ }
+
+ if (GET_BITFIELD (
+ Isar0,
+ ARM_ID_AA64ISAR0_EL1_AES_SHIFT,
+ ARM_ID_AA64ISAR0_EL1_AES_MASK
+ ) >= ARM_ID_AA64ISAR0_EL1_AES_FEAT_PMULL_MASK)
+ {
+ OPENSSL_armcap_P |= ARMV8_PMULL;
+ }
+
+ if (GET_BITFIELD (
+ Isar0,
+ ARM_ID_AA64ISAR0_EL1_SHA2_SHIFT,
+ ARM_ID_AA64ISAR0_EL1_SHA2_MASK
+ ) >= ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA512_MASK)
+ {
+ OPENSSL_armcap_P |= ARMV8_SHA512;
+ }
+}
+
+/** Read system counter value.
+
+ Used to get some non-trusted entropy.
+
+ @return Lower bits of the physical counter.
+**/
+uint32_t
+OPENSSL_rdtsc (
+ void
+ )
+{
+ return (UINT32)ArmReadCntPctReg ();
+}
diff --git a/CryptoPkg/Library/OpensslLib/OpensslStub/OpensslCleanse.c b/CryptoPkg/Library/OpensslLib/OpensslStub/OpensslCleanse.c
new file mode 100644
index 0000000..21c9399
--- /dev/null
+++ b/CryptoPkg/Library/OpensslLib/OpensslStub/OpensslCleanse.c
@@ -0,0 +1,20 @@
+/** @file
+ Minimal implementation of OPENSSL_cleanse for OpensslLibSm3.inf.
+
+ Copyright (c) 2024, Google LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/BaseMemoryLib.h>
+
+VOID
+OPENSSL_cleanse (
+ VOID *Buffer,
+ UINTN Size
+ )
+{
+ ZeroMem (Buffer, Size);
+}
diff --git a/CryptoPkg/Library/OpensslLib/UefiAsm.conf b/CryptoPkg/Library/OpensslLib/UefiAsm.conf
index 907582f..98a8eb0 100644
--- a/CryptoPkg/Library/OpensslLib/UefiAsm.conf
+++ b/CryptoPkg/Library/OpensslLib/UefiAsm.conf
@@ -2,6 +2,7 @@
# UEFI assembly openssl configuration targets.
#
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -28,4 +29,9 @@ my %targets = (
perlasm_scheme => "elf",
asm_arch => "x86_64",
},
+ "UEFI-AARCH64-GCC" => {
+ inherit_from => [ "UEFI" ],
+ asm_arch => "aarch64",
+ perlasm_scheme => "linux64-aarch64",
+ },
);
diff --git a/CryptoPkg/Library/OpensslLib/configure.py b/CryptoPkg/Library/OpensslLib/configure.py
index 4243ca4..dc09124 100755
--- a/CryptoPkg/Library/OpensslLib/configure.py
+++ b/CryptoPkg/Library/OpensslLib/configure.py
@@ -262,6 +262,7 @@ def sources_filter_fn(filename):
'provider_predefined.c',
'ecp_nistz256.c',
'x86_64-gcc.c',
+ 'armcap.c',
]
for item in exclude:
if item in filename:
@@ -353,7 +354,8 @@ def main():
sources = {}
defines = {}
for asm in [ 'UEFI-IA32-MSFT', 'UEFI-IA32-GCC',
- 'UEFI-X64-MSFT', 'UEFI-X64-GCC']:
+ 'UEFI-X64-MSFT', 'UEFI-X64-GCC',
+ 'UEFI-AARCH64-GCC']:
(uefi, arch, cc) = asm.split('-')
archcc = f'{arch}-{cc}'
@@ -375,6 +377,8 @@ def main():
x64accel = sources['X64'] + sources['X64-MSFT'] + sources['X64-GCC']
update_inf(inf, ia32accel, 'IA32', defines['IA32'])
update_inf(inf, x64accel, 'X64', defines['X64'])
+ aarch64accel = sources['AARCH64'] + sources['AARCH64-GCC']
+ update_inf(inf, aarch64accel, 'AARCH64', defines['AARCH64'])
# noaccel - ec enabled
openssl_configure(openssldir, 'UEFI', ec = True);
diff --git a/CryptoPkg/Library/OpensslLib/openssl b/CryptoPkg/Library/OpensslLib/openssl
-Subproject de90e54bbe82e5be4fb9608b6f5c308bb837d35
+Subproject c523121f902fde2929909dc7f76b13ceb4961ef
diff --git a/CryptoPkg/Readme.md b/CryptoPkg/Readme.md
index 5a68dfb..cb2228b 100644
--- a/CryptoPkg/Readme.md
+++ b/CryptoPkg/Readme.md
@@ -246,13 +246,13 @@ specific set of enabled cryptographic services. If ECC services are not
required, then the size can be reduced by using OpensslLib.inf instead of
`OpensslLibFull.inf`. Performance optimization requires a size increase.
-| OpensslLib Instance | SSL | ECC | Perf Opt | CPU Arch | Size |
-|:------------------------|:---:|:---:|:--------:|:--------:|:-----:|
-| OpensslLibCrypto.inf | N | N | N | All | +0K |
-| OpensslLib.inf | Y | N | N | All | +0K |
-| OpensslLibAccel.inf | Y | N | Y | IA32/X64 | +20K |
-| OpensslLibFull.inf | Y | Y | N | All | +115K |
-| OpensslLibFullAccel.inf | Y | Y | Y | IA32/X64 | +135K |
+| OpensslLib Instance | SSL | ECC | Perf Opt | CPU Arch | Size |
+|:------------------------|:---:|:---:|:--------:|:----------------:|:-----:|
+| OpensslLibCrypto.inf | N | N | N | All | +0K |
+| OpensslLib.inf | Y | N | N | All | +0K |
+| OpensslLibAccel.inf | Y | N | Y | IA32/X64/AARCH64 | +20K |
+| OpensslLibFull.inf | Y | Y | N | All | +115K |
+| OpensslLibFullAccel.inf | Y | Y | Y | IA32/X64/AARCH64 | +135K |
### SEC Phase Library Mappings
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c
index dc58202..ab5c0d7 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/HashTests.c
@@ -62,6 +62,15 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sha512Digest[SHA512_DIGEST_SIZE] = {
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f
};
+//
+// Result for SM3("abc"). (From "A.1 Example 1" of
+// http://www.gmbz.org.cn/upload/2018-07-24/1532401392982079739.pdf)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 Sm3Digest[SM3_256_DIGEST_SIZE] = {
+ 0x66, 0xc7, 0xf0, 0xf4, 0x62, 0xee, 0xed, 0xd9, 0xd1, 0xf2, 0xd4, 0x6b, 0xdc, 0x10, 0xe4, 0xe2,
+ 0x41, 0x67, 0xc4, 0x87, 0x5c, 0xf2, 0xf7, 0xa2, 0x29, 0x7d, 0xa0, 0x2b, 0x8f, 0x4b, 0xa8, 0xe0
+};
+
typedef
UINTN
(EFIAPI *EFI_HASH_GET_CONTEXT_SIZE)(
@@ -123,6 +132,7 @@ HASH_TEST_CONTEXT mSha1TestCtx = { SHA1_DIGEST_SIZE, Sha1GetContextSize, Sha1
HASH_TEST_CONTEXT mSha256TestCtx = { SHA256_DIGEST_SIZE, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Duplicate, Sha256Final, Sha256HashAll, Sha256Digest };
HASH_TEST_CONTEXT mSha384TestCtx = { SHA384_DIGEST_SIZE, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Duplicate, Sha384Final, Sha384HashAll, Sha384Digest };
HASH_TEST_CONTEXT mSha512TestCtx = { SHA512_DIGEST_SIZE, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Duplicate, Sha512Final, Sha512HashAll, Sha512Digest };
+HASH_TEST_CONTEXT mSm3TestCtx = { SM3_256_DIGEST_SIZE, Sm3GetContextSize, Sm3Init, Sm3Update, Sm3Duplicate, Sm3Final, Sm3HashAll, Sm3Digest };
UNIT_TEST_STATUS
EFIAPI
@@ -220,6 +230,7 @@ TEST_DESC mHashTest[] = {
{ "TestVerifySha256()", "CryptoPkg.BaseCryptLib.Hash", TestVerifyHash, TestVerifyHashPreReq, TestVerifyHashCleanUp, &mSha256TestCtx },
{ "TestVerifySha384()", "CryptoPkg.BaseCryptLib.Hash", TestVerifyHash, TestVerifyHashPreReq, TestVerifyHashCleanUp, &mSha384TestCtx },
{ "TestVerifySha512()", "CryptoPkg.BaseCryptLib.Hash", TestVerifyHash, TestVerifyHashPreReq, TestVerifyHashCleanUp, &mSha512TestCtx },
+ { "TestVerifySm3()", "CryptoPkg.BaseCryptLib.Hash", TestVerifyHash, TestVerifyHashPreReq, TestVerifyHashCleanUp, &mSm3TestCtx },
};
UINTN mHashTestNum = ARRAY_SIZE (mHashTest);
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/Arm/ArmDynamicTableManager.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/Arm/ArmDynamicTableManager.c
new file mode 100644
index 0000000..4874fe8
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/Arm/ArmDynamicTableManager.c
@@ -0,0 +1,63 @@
+/** @file
+ ARM Dynamic Table Manager Dxe
+
+ Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <DeviceTreeTableGenerator.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+#include "DynamicTableManagerDxe.h"
+
+///
+/// Array containing the ACPI tables to check.
+/// We require the FADT, MADT, GTDT and the DSDT tables to boot.
+/// This list also include optional ACPI tables: DBG2, SPCR.
+/// The FADT table must be placed at index 0.
+///
+STATIC ACPI_TABLE_PRESENCE_INFO mAcpiVerifyTables[] = {
+ { EStdAcpiTableIdFadt, EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, "FADT", TRUE, 0 },
+ { EStdAcpiTableIdMadt, EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, "MADT", TRUE, 0 },
+ { EStdAcpiTableIdGtdt, EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, "GTDT", TRUE, 0 },
+ { EStdAcpiTableIdDsdt, EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, "DSDT", TRUE, 0 },
+ { EStdAcpiTableIdDbg2, EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, "DBG2", FALSE, 0 },
+ { EStdAcpiTableIdSpcr, EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, "SPCR", FALSE, 0 },
+};
+
+/** Get the arch specific ACPI table presence information.
+
+ @param [out] PresenceArray Array containing the ACPI tables to check.
+ @param [out] PresenceArrayCount Count of elements in the PresenceArray.
+ @param [out] FadtIndex Index of the FADT table in the PresenceArray.
+ -1 if absent.
+
+ @retval EFI_SUCCESS Success.
+**/
+EFI_STATUS
+EFIAPI
+GetAcpiTablePresenceInfo (
+ OUT ACPI_TABLE_PRESENCE_INFO **PresenceArray,
+ OUT UINT32 *PresenceArrayCount,
+ OUT INT32 *FadtIndex
+ )
+{
+ *PresenceArray = mAcpiVerifyTables;
+ *PresenceArrayCount = ARRAY_SIZE (mAcpiVerifyTables);
+ *FadtIndex = ACPI_TABLE_VERIFY_FADT;
+
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
index 1e9b811..dfccccb 100644
--- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
@@ -23,57 +23,15 @@
#include <Protocol/DynamicTableFactoryProtocol.h>
#include <SmbiosTableGenerator.h>
-///
-/// Bit definitions for acceptable ACPI table presence formats.
-/// Currently only ACPI tables present in the ACPI info list and
-/// already installed will count towards "Table Present" during
-/// verification routine.
-///
-#define ACPI_TABLE_PRESENT_INFO_LIST BIT0
-#define ACPI_TABLE_PRESENT_INSTALLED BIT1
-
-///
-/// Order of ACPI table being verified during presence inspection.
-///
-#define ACPI_TABLE_VERIFY_FADT 0
-#define ACPI_TABLE_VERIFY_MADT 1
-#define ACPI_TABLE_VERIFY_GTDT 2
-#define ACPI_TABLE_VERIFY_DSDT 3
-#define ACPI_TABLE_VERIFY_DBG2 4
-#define ACPI_TABLE_VERIFY_SPCR 5
-#define ACPI_TABLE_VERIFY_COUNT 6
-
-///
-/// Private data structure to verify the presence of mandatory
-/// or optional ACPI tables.
-///
-typedef struct {
- /// ESTD ID for the ACPI table of interest.
- ESTD_ACPI_TABLE_ID EstdTableId;
- /// Standard UINT32 ACPI signature.
- UINT32 AcpiTableSignature;
- /// 4 character ACPI table name (the 5th char8 is for null terminator).
- CHAR8 AcpiTableName[sizeof (UINT32) + 1];
- /// Indicator on whether the ACPI table is required.
- BOOLEAN IsMandatory;
- /// Formats of verified presences, as defined by ACPI_TABLE_PRESENT_*
- /// This field should be initialized to 0 and will be populated during
- /// verification routine.
- UINT16 Presence;
-} ACPI_TABLE_PRESENCE_INFO;
+#include "DynamicTableManagerDxe.h"
///
/// We require the FADT, MADT, GTDT and the DSDT tables to boot.
/// This list also include optional ACPI tables: DBG2, SPCR.
///
-ACPI_TABLE_PRESENCE_INFO mAcpiVerifyTables[ACPI_TABLE_VERIFY_COUNT] = {
- { EStdAcpiTableIdFadt, EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, "FADT", TRUE, 0 },
- { EStdAcpiTableIdMadt, EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, "MADT", TRUE, 0 },
- { EStdAcpiTableIdGtdt, EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, "GTDT", TRUE, 0 },
- { EStdAcpiTableIdDsdt, EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, "DSDT", TRUE, 0 },
- { EStdAcpiTableIdDbg2, EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, "DBG2", FALSE, 0 },
- { EStdAcpiTableIdSpcr, EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, "SPCR", FALSE, 0 },
-};
+STATIC ACPI_TABLE_PRESENCE_INFO *mAcpiVerifyTables;
+STATIC UINT32 mAcpiVerifyTablesCount;
+STATIC INT32 mAcpiVerifyTablesFadtIndex;
/** This macro expands to a function that retrieves the ACPI Table
List from the Configuration Manager.
@@ -472,7 +430,7 @@ VerifyMandatoryTablesArePresent (
// Check against the statically initialized ACPI tables to see if they are in ACPI info list
while (AcpiTableCount-- != 0) {
- for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) {
+ for (Index = 0; Index < mAcpiVerifyTablesCount; Index++) {
if (AcpiTableInfo[AcpiTableCount].AcpiTableSignature == mAcpiVerifyTables[Index].AcpiTableSignature) {
mAcpiVerifyTables[Index].Presence |= ACPI_TABLE_PRESENT_INFO_LIST;
// Found this table, skip the rest.
@@ -491,7 +449,7 @@ VerifyMandatoryTablesArePresent (
return Status;
}
- for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) {
+ for (Index = 0; Index < mAcpiVerifyTablesCount; Index++) {
Handle = 0;
InstalledTableIndex = 0;
do {
@@ -511,7 +469,7 @@ VerifyMandatoryTablesArePresent (
// Reset the return Status value to EFI_SUCCESS. We do not fully care if the table look up has failed.
Status = EFI_SUCCESS;
- for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) {
+ for (Index = 0; Index < mAcpiVerifyTablesCount; Index++) {
if (mAcpiVerifyTables[Index].Presence == 0) {
if (mAcpiVerifyTables[Index].IsMandatory) {
DEBUG ((DEBUG_ERROR, "ERROR: %a Table not found.\n", mAcpiVerifyTables[Index].AcpiTableName));
@@ -623,7 +581,9 @@ ProcessAcpiTables (
}
// Add the FADT Table first.
- if ((mAcpiVerifyTables[ACPI_TABLE_VERIFY_FADT].Presence & ACPI_TABLE_PRESENT_INSTALLED) == 0) {
+ if ((mAcpiVerifyTablesFadtIndex >= 0) &&
+ ((mAcpiVerifyTables[mAcpiVerifyTablesFadtIndex].Presence & ACPI_TABLE_PRESENT_INSTALLED) == 0))
+ {
// FADT is not yet installed
for (Idx = 0; Idx < AcpiTableCount; Idx++) {
if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) ==
@@ -785,6 +745,16 @@ DynamicTableManagerDxeInitialize (
CfgMfrInfo->OemId[5]
));
+ Status = GetAcpiTablePresenceInfo (
+ &mAcpiVerifyTables,
+ &mAcpiVerifyTablesCount,
+ &mAcpiVerifyTablesFadtIndex
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
Status = ProcessAcpiTables (TableFactoryProtocol, CfgMgrProtocol);
if (EFI_ERROR (Status)) {
DEBUG ((
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.h b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.h
new file mode 100644
index 0000000..a12a775
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.h
@@ -0,0 +1,63 @@
+/** @file
+ Dynamic Table Manager Dxe
+
+ Copyright (c) 2017 - 2024, ARM Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef DYNAMIC_TABLE_MANAGER_DXE_H_
+#define DYNAMIC_TABLE_MANAGER_DXE_H_
+
+#include <AcpiTableGenerator.h>
+
+///
+/// Bit definitions for acceptable ACPI table presence formats.
+/// Currently only ACPI tables present in the ACPI info list and
+/// already installed will count towards "Table Present" during
+/// verification routine.
+///
+#define ACPI_TABLE_PRESENT_INFO_LIST BIT0
+#define ACPI_TABLE_PRESENT_INSTALLED BIT1
+
+/// The FADT table must be placed at index 0 in mAcpiVerifyTables.
+#define ACPI_TABLE_VERIFY_FADT 0
+
+///
+/// Private data structure to verify the presence of mandatory
+/// or optional ACPI tables.
+///
+typedef struct {
+ /// ESTD ID for the ACPI table of interest.
+ ESTD_ACPI_TABLE_ID EstdTableId;
+ /// Standard UINT32 ACPI signature.
+ UINT32 AcpiTableSignature;
+ /// 4 character ACPI table name (the 5th char8 is for null terminator).
+ CHAR8 AcpiTableName[sizeof (UINT32) + 1];
+ /// Indicator on whether the ACPI table is required.
+ BOOLEAN IsMandatory;
+ /// Formats of verified presences, as defined by ACPI_TABLE_PRESENT_*
+ /// This field should be initialized to 0 and will be populated during
+ /// verification routine.
+ UINT16 Presence;
+} ACPI_TABLE_PRESENCE_INFO;
+
+/** Get the arch specific ACPI table presence information.
+
+ @param [out] PresenceArray Array containing the ACPI tables to check.
+ @param [out] PresenceArrayCount Count of elements in the PresenceArray.
+ @param [out] FadtIndex Index of the FADT table in the PresenceArray.
+ -1 if absent.
+
+ @retval EFI_SUCCESS Success.
+**/
+EFI_STATUS
+EFIAPI
+GetAcpiTablePresenceInfo (
+ OUT ACPI_TABLE_PRESENCE_INFO **PresenceArray,
+ OUT UINT32 *PresenceArrayCount,
+ OUT INT32 *FadtIndex
+ );
+
+#endif // DYNAMIC_TABLE_MANAGER_DXE_H_
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
index ad8b3d0..c982b24 100644
--- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
@@ -2,6 +2,7 @@
# Module that drives the table generation and installation process.
#
# Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
+# Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
@@ -22,6 +23,13 @@
[Sources]
DynamicTableManagerDxe.c
+ DynamicTableManagerDxe.h
+
+[Sources.ARM, Sources.AARCH64]
+ Arm/ArmDynamicTableManager.c
+
+[Sources.IA32, Sources.X64]
+ X64/X64DynamicTableManager.c
[Packages]
MdePkg/MdePkg.dec
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/X64/X64DynamicTableManager.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/X64/X64DynamicTableManager.c
new file mode 100755
index 0000000..a5457f3
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/X64/X64DynamicTableManager.c
@@ -0,0 +1,56 @@
+/** @file
+ X64 Dynamic Table Manager Dxe
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.
+ Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <DeviceTreeTableGenerator.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+#include "DynamicTableManagerDxe.h"
+
+///
+/// Array containing the ACPI tables to check.
+///
+STATIC ACPI_TABLE_PRESENCE_INFO mAcpiVerifyTables[] = {
+ { EStdAcpiTableIdFadt, EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, "FADT", TRUE, 0 }
+};
+
+/** Get the arch specific ACPI table presence information.
+
+ @param [out] PresenceArray Array containing the ACPI tables to check.
+ @param [out] PresenceArrayCount Count of elements in the PresenceArray.
+ @param [out] FadtIndex Index of the FADT table in the PresenceArray.
+ -1 if absent.
+
+ @retval EFI_SUCCESS Success.
+**/
+EFI_STATUS
+EFIAPI
+GetAcpiTablePresenceInfo (
+ OUT ACPI_TABLE_PRESENCE_INFO **PresenceArray,
+ OUT UINT32 *PresenceArrayCount,
+ OUT INT32 *FadtIndex
+ )
+{
+ *PresenceArray = mAcpiVerifyTables;
+ *PresenceArrayCount = ARRAY_SIZE (mAcpiVerifyTables);
+ *FadtIndex = ACPI_TABLE_VERIFY_FADT;
+
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 19ca62d..c9bfa75 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -3,6 +3,7 @@
#
# Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.<BR>
# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -26,63 +27,92 @@
[Components.common]
#
+ # Generators (Common)
+ #
+ DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf
+ DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf
+ DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf
+ DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf
+ DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf
+ DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf
+ DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf
+ DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf
+ DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf
+
+ # AML Fixup (Common)
+ DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf
+
+ # AML Codegen (Common)
+ DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf
+ DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf
+
+ #
# Dynamic Tables Manager Dxe
#
DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
[Components.IA32, Components.X64]
#
+ # Generators (IA32/X64 specific)
+ #
+ DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf
+ DynamicTablesPkg/Library/Acpi/X64/AcpiHpetLib/AcpiHpetLib.inf
+ DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.inf
+
+ #
# Dynamic Table Factory Dxe
#
- DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
+ DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf {
+ <LibraryClasses>
+ # Generators
+ # Common
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/X64/AcpiHpetLib/AcpiHpetLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.inf
+ }
[Components.ARM, Components.AARCH64]
#
- # Generators
+ # Generators (Arm specific)
#
- DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf
- DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf
DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf
DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
- DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf
- DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf
- DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
- DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf
- DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf
- DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf
-
- # AML Fixup
- DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf
- DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf
- # AML Codegen
- DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf
- DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf
+ # AML Fixup (Arm specific)
+ DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf
#
# Dynamic Table Factory Dxe
#
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf {
<LibraryClasses>
- NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf
- NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
+ # Generators
+ # Common
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf
+ # Arm specific
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
- NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf
- NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf
- NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
- NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf
- NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf
- NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf
# AML Fixup
- NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf
+ # Common
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf
+ # Arm specific
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf
# AML Codegen
- NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf
- NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf
+ # Common
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf
}
diff --git a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
index 42829f3..f7c8897 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
+++ b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
@@ -104,6 +104,7 @@
"CCIDX",
"CCSIDR",
"countof",
+ "EArch",
"edynamic",
"EOBJECT",
"invoc",
@@ -112,6 +113,7 @@
"lgreater",
"lless",
"MPIDR",
+ "NAMESPACEID",
"PASID",
"PERIPHBASE",
"phandle",
diff --git a/DynamicTablesPkg/DynamicTablesPkg.dsc b/DynamicTablesPkg/DynamicTablesPkg.dsc
index cf06f07..8cac9d5 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dsc
+++ b/DynamicTablesPkg/DynamicTablesPkg.dsc
@@ -34,9 +34,11 @@
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.ARM, LibraryClasses.AARCH64]
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
[Components.common]
diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h
index d0eda01..69c012e 100644
--- a/DynamicTablesPkg/Include/AcpiTableGenerator.h
+++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h
@@ -1,6 +1,8 @@
/** @file
Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.<BR>
+ Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.<BR>
+ Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -71,6 +73,8 @@ The Dynamic Tables Framework implements the following ACPI table generators:
The SSDT Pci Express generator collates the Pci Express
information from the Configuration Manager and generates a
SSDT table describing a Pci Express bus.
+ - WSMT : The WSMT generator collates the WSMT protection flag information
+ from the Configuration Manager and builds the WSMT table.
*/
/** The ACPI_TABLE_GENERATOR_ID type describes ACPI table generator ID.
@@ -99,6 +103,10 @@ typedef enum StdAcpiTableId {
EStdAcpiTableIdSsdtCpuTopology, ///< SSDT Cpu Topology
EStdAcpiTableIdSsdtPciExpress, ///< SSDT Pci Express Generator
EStdAcpiTableIdPcct, ///< PCCT Generator
+ EStdAcpiTableIdTpm2, ///< TPM2 Generator
+ EStdAcpiTableIdWsmt, ///< WSMT Generator
+ EStdAcpiTableIdHpet, ///< HPET Generator
+ EStdAcpiTableIdSsdtHpet, ///< SSDT HPET Generator
EStdAcpiTableIdMax
} ESTD_ACPI_TABLE_ID;
@@ -154,9 +162,14 @@ typedef enum StdAcpiTableId {
TableId \
)
-/** The Creator ID for the ACPI tables generated using
+/** The generic creator ID for the ACPI tables generated using
the standard ACPI table generators.
*/
+#define TABLE_GENERATOR_CREATOR_ID SIGNATURE_32('D', 'Y', 'N', 'T')
+
+/** The Creator ID for the ACPI tables generated using
+ the standard ACPI table generators for ARM.
+*/
#define TABLE_GENERATOR_CREATOR_ID_ARM SIGNATURE_32('A', 'R', 'M', 'H')
/** A macro to initialise the common header part of EFI ACPI tables as
@@ -214,7 +227,7 @@ typedef struct AcpiTableGenerator ACPI_TABLE_GENERATOR;
@return EFI_SUCCESS If the table is generated successfully or other
failure codes as returned by the generator.
**/
-typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_BUILD_TABLE) (
+typedef EFI_STATUS (EFIAPI *ACPI_TABLE_GENERATOR_BUILD_TABLE)(
IN CONST ACPI_TABLE_GENERATOR *This,
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
@@ -234,7 +247,7 @@ typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_BUILD_TABLE) (
@return EFI_SUCCESS If freed successfully or other failure codes
as returned by the generator.
**/
-typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_FREE_TABLE) (
+typedef EFI_STATUS (EFIAPI *ACPI_TABLE_GENERATOR_FREE_TABLE)(
IN CONST ACPI_TABLE_GENERATOR *CONST This,
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
@@ -257,7 +270,7 @@ typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_FREE_TABLE) (
@return EFI_SUCCESS If the table is generated successfully or other
failure codes as returned by the generator.
**/
-typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_BUILD_TABLEEX) (
+typedef EFI_STATUS (EFIAPI *ACPI_TABLE_GENERATOR_BUILD_TABLEEX)(
IN CONST ACPI_TABLE_GENERATOR *This,
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
@@ -280,7 +293,7 @@ typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_BUILD_TABLEEX) (
@return EFI_SUCCESS If freed successfully or other failure codes
as returned by the generator.
**/
-typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_FREE_TABLEEX) (
+typedef EFI_STATUS (EFIAPI *ACPI_TABLE_GENERATOR_FREE_TABLEEX)(
IN CONST ACPI_TABLE_GENERATOR *CONST This,
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h
new file mode 100644
index 0000000..4b83e53
--- /dev/null
+++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h
@@ -0,0 +1,696 @@
+/** @file
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
+ Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+ - Std or STD - Standard
+**/
+
+#ifndef ARCH_COMMON_NAMESPACE_OBJECTS_H_
+#define ARCH_COMMON_NAMESPACE_OBJECTS_H_
+
+#include <AcpiObjects.h>
+#include <StandardNameSpaceObjects.h>
+
+#include <IndustryStandard/Tpm2Acpi.h>
+
+/** The EARCH_COMMON_OBJECT_ID enum describes the Object IDs
+ in the Arch Common Namespace
+*/
+typedef enum ArchCommonObjectID {
+ EArchCommonObjReserved, ///< 0 - Reserved
+ EArchCommonObjPowerManagementProfileInfo, ///< 1 - Power Management Profile Info
+ EArchCommonObjSerialPortInfo, ///< 2 - Generic Serial Port Info
+ EArchCommonObjConsolePortInfo, ///< 3 - Serial Console Port Info
+ EArchCommonObjSerialDebugPortInfo, ///< 4 - Serial Debug Port Info
+ EArchCommonObjHypervisorVendorIdentity, ///< 5 - Hypervisor Vendor Id
+ EArchCommonObjFixedFeatureFlags, ///< 6 - Fixed feature flags for FADT
+ EArchCommonObjCmRef, ///< 7 - CM Object Reference
+ EArchCommonObjPciConfigSpaceInfo, ///< 8 - PCI Configuration Space Info
+ EArchCommonObjPciAddressMapInfo, ///< 9 - Pci Address Map Info
+ EArchCommonObjPciInterruptMapInfo, ///< 10 - Pci Interrupt Map Info
+ EArchCommonObjMemoryAffinityInfo, ///< 11 - Memory Affinity Info
+ EArchCommonObjDeviceHandleAcpi, ///< 12 - Device Handle Acpi
+ EArchCommonObjDeviceHandlePci, ///< 13 - Device Handle Pci
+ EArchCommonObjGenericInitiatorAffinityInfo, ///< 14 - Generic Initiator Affinity
+ EArchCommonObjLpiInfo, ///< 15 - Lpi Info
+ EArchCommonObjProcHierarchyInfo, ///< 16 - Processor Hierarchy Info
+ EArchCommonObjCacheInfo, ///< 17 - Cache Info
+ EArchCommonObjCpcInfo, ///< 18 - Continuous Performance Control Info
+ EArchCommonObjPccSubspaceType0Info, ///< 19 - Pcc Subspace Type 0 Info
+ EArchCommonObjPccSubspaceType1Info, ///< 20 - Pcc Subspace Type 1 Info
+ EArchCommonObjPccSubspaceType2Info, ///< 21 - Pcc Subspace Type 2 Info
+ EArchCommonObjPccSubspaceType3Info, ///< 22 - Pcc Subspace Type 3 Info
+ EArchCommonObjPccSubspaceType4Info, ///< 23 - Pcc Subspace Type 4 Info
+ EArchCommonObjPccSubspaceType5Info, ///< 24 - Pcc Subspace Type 5 Info
+ EArchCommonObjPsdInfo, ///< 25 - P-State Dependency (PSD) Info
+ EArchCommonObjTpm2InterfaceInfo, ///< 26 - TPM Interface Info
+ EArchCommonObjMax
+} EARCH_COMMON_OBJECT_ID;
+
+#pragma pack(1)
+
+/** A structure that describes the
+ Power Management Profile Information for the Platform.
+
+ ID: EArchCommonObjPowerManagementProfileInfo
+*/
+typedef struct CmArchCommonPowerManagementProfileInfo {
+ /** This is the Preferred_PM_Profile field of the FADT Table
+ described in the ACPI Specification
+ */
+ UINT8 PowerManagementProfile;
+} CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO;
+
+/** A structure that describes the
+ Serial Port information for the Platform.
+
+ ID: EArchCommonObjConsolePortInfo or
+ EArchCommonObjSerialDebugPortInfo or
+ EArchCommonObjSerialPortInfo
+*/
+typedef struct EArchCommonSerialPortInfo {
+ /// The physical base address for the serial port
+ UINT64 BaseAddress;
+
+ /** The serial port interrupt.
+ 0 indicates that the serial port does not
+ have an interrupt wired.
+ */
+ UINT32 Interrupt;
+
+ /// The serial port baud rate
+ UINT64 BaudRate;
+
+ /// The serial port clock
+ UINT32 Clock;
+
+ /// Serial Port subtype
+ UINT16 PortSubtype;
+
+ /// The Base address length
+ UINT64 BaseAddressLength;
+
+ /// The access size
+ UINT8 AccessSize;
+} CM_ARCH_COMMON_SERIAL_PORT_INFO;
+
+/** A structure that describes the
+ Hypervisor Vendor ID information for the Platform.
+
+ ID: EArchCommonObjHypervisorVendorIdentity
+*/
+typedef struct CmArchCommonHypervisorVendorIdentity {
+ /// The hypervisor Vendor ID
+ UINT64 HypervisorVendorId;
+} CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID;
+
+/** A structure that describes the
+ Fixed feature flags for the Platform.
+
+ ID: EArchCommonObjFixedFeatureFlags
+*/
+typedef struct CmArchCommonFixedFeatureFlags {
+ /// The Fixed feature flags
+ UINT32 Flags;
+} CM_ARCH_COMMON_FIXED_FEATURE_FLAGS;
+
+/** A structure that describes a reference to another Configuration Manager
+ object.
+
+ This is useful for creating an array of reference tokens. The framework
+ can then query the configuration manager for these arrays using the
+ object ID EArchCommonObjCmRef.
+
+ This can be used is to represent one-to-many relationships between objects.
+
+ ID: EArchCommonObjCmRef
+*/
+typedef struct CmArchCommonObjRef {
+ /// Token of the CM object being referenced
+ CM_OBJECT_TOKEN ReferenceToken;
+} CM_ARCH_COMMON_OBJ_REF;
+
+/** A structure that describes the
+ PCI Configuration Space information for the Platform.
+
+ ID: EArchCommonObjPciConfigSpaceInfo
+*/
+typedef struct CmArchCommonPciConfigSpaceInfo {
+ /// The physical base address for the PCI segment
+ UINT64 BaseAddress;
+
+ /// The PCI segment group number
+ UINT16 PciSegmentGroupNumber;
+
+ /// The start bus number
+ UINT8 StartBusNumber;
+
+ /// The end bus number
+ UINT8 EndBusNumber;
+
+ /// Optional field: Reference Token for address mapping.
+ /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure.
+ CM_OBJECT_TOKEN AddressMapToken;
+
+ /// Optional field: Reference Token for interrupt mapping.
+ /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure.
+ CM_OBJECT_TOKEN InterruptMapToken;
+} CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO;
+
+/** A structure that describes a PCI Address Map.
+
+ The memory-ranges used by the PCI bus are described by this object.
+
+ ID: EArchCommonObjPciAddressMapInfo
+*/
+typedef struct CmArchCommonPciAddressMapInfo {
+ /** Pci address space code
+
+ Available values are:
+ - 0: Configuration Space
+ - 1: I/O Space
+ - 2: 32-bit-address Memory Space
+ - 3: 64-bit-address Memory Space
+ */
+ UINT8 SpaceCode;
+
+ /// PCI address
+ UINT64 PciAddress;
+
+ /// Cpu address
+ UINT64 CpuAddress;
+
+ /// Address size
+ UINT64 AddressSize;
+} CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO;
+
+/** A structure that describes the
+ Generic Interrupts.
+*/
+typedef struct CmArchCommonGenericInterrupt {
+ /// Interrupt number
+ UINT32 Interrupt;
+
+ /// Flags
+ /// BIT0: 0: Interrupt is Level triggered
+ /// 1: Interrupt is Edge triggered
+ /// BIT1: 0: Interrupt is Active high
+ /// 1: Interrupt is Active low
+ UINT32 Flags;
+} CM_ARCH_COMMON_GENERIC_INTERRUPT;
+
+/** A structure that describes a PCI Interrupt Map.
+
+ The legacy PCI interrupts used by PCI devices are described by this object.
+
+ Cf Devicetree Specification - Release v0.3
+ s2.4.3 "Interrupt Nexus Properties"
+
+ ID: EArchCommonObjPciInterruptMapInfo
+*/
+typedef struct CmArchCommonPciInterruptMapInfo {
+ /// Pci Bus.
+ /// Value on 8 bits (max 255).
+ UINT8 PciBus;
+
+ /// Pci Device.
+ /// Value on 5 bits (max 31).
+ UINT8 PciDevice;
+
+ /** PCI interrupt
+
+ ACPI bindings are used:
+ Cf. ACPI 6.4, s6.2.13 _PRT (PCI Routing Table):
+ "0-INTA, 1-INTB, 2-INTC, 3-INTD"
+
+ Device-tree bindings are shifted by 1:
+ "INTA=1, INTB=2, INTC=3, INTD=4"
+ */
+ UINT8 PciInterrupt;
+
+ /** Interrupt controller interrupt.
+
+ Cf Devicetree Specification - Release v0.3
+ s2.4.3 "Interrupt Nexus Properties": "parent interrupt specifier"
+ */
+ CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt;
+} CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO;
+
+/** A structure that describes the Memory Affinity Structure (Type 1) in SRAT
+
+ ID: EArchCommonObjMemoryAffinityInfo
+*/
+typedef struct CmArchCommonMemoryAffinityInfo {
+ /// The proximity domain to which the "range of memory" belongs.
+ UINT32 ProximityDomain;
+
+ /// Base Address
+ UINT64 BaseAddress;
+
+ /// Length
+ UINT64 Length;
+
+ /// Flags
+ UINT32 Flags;
+} CM_ARCH_COMMON_MEMORY_AFFINITY_INFO;
+
+/** A structure that describes the ACPI Device Handle (Type 0) in the
+ Generic Initiator Affinity structure in SRAT
+
+ ID: EArchCommonObjDeviceHandleAcpi
+*/
+typedef struct CmArchCommonDeviceHandleAcpi {
+ /// Hardware ID
+ UINT64 Hid;
+
+ /// Unique Id
+ UINT32 Uid;
+} CM_ARCH_COMMON_DEVICE_HANDLE_ACPI;
+
+/** A structure that describes the PCI Device Handle (Type 1) in the
+ Generic Initiator Affinity structure in SRAT
+
+ ID: EArchCommonObjDeviceHandlePci
+*/
+typedef struct CmArchCommonDeviceHandlePci {
+ /// PCI Segment Number
+ UINT16 SegmentNumber;
+
+ /// PCI Bus Number - Max 256 busses (Bits 15:8 of BDF)
+ UINT8 BusNumber;
+
+ /// PCI Device Number - Max 32 devices (Bits 7:3 of BDF)
+ UINT8 DeviceNumber;
+
+ /// PCI Function Number - Max 8 functions (Bits 2:0 of BDF)
+ UINT8 FunctionNumber;
+} CM_ARCH_COMMON_DEVICE_HANDLE_PCI;
+
+/** A structure that describes the Generic Initiator Affinity structure in SRAT
+
+ ID: EArchCommonObjGenericInitiatorAffinityInfo
+*/
+typedef struct CmArchCommonGenericInitiatorAffinityInfo {
+ /// The proximity domain to which the generic initiator belongs.
+ UINT32 ProximityDomain;
+
+ /// Flags
+ UINT32 Flags;
+
+ /// Device Handle Type
+ UINT8 DeviceHandleType;
+
+ /// Reference Token for the Device Handle
+ CM_OBJECT_TOKEN DeviceHandleToken;
+} CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO;
+
+/** A structure that describes the Lpi information.
+
+ The Low Power Idle states are described in DSDT/SSDT and associated
+ to cpus/clusters in the cpu topology.
+
+ ID: EArchCommonObjLpiInfo
+*/
+typedef struct CmArchCommonLpiInfo {
+ /** Minimum Residency. Time in microseconds after which a
+ state becomes more energy efficient than any shallower state.
+ */
+ UINT32 MinResidency;
+
+ /** Worst case time in microseconds from a wake interrupt
+ being asserted to the return to a running state
+ */
+ UINT32 WorstCaseWakeLatency;
+
+ /** Flags.
+ */
+ UINT32 Flags;
+
+ /** Architecture specific context loss flags.
+ */
+ UINT32 ArchFlags;
+
+ /** Residency counter frequency in cycles-per-second (Hz).
+ */
+ UINT32 ResCntFreq;
+
+ /** Every shallower power state in the parent is also enabled.
+ */
+ UINT32 EnableParentState;
+
+ /** The EntryMethod _LPI field can be described as an integer
+ or in a Register resource data descriptor.
+
+ If IsInteger is TRUE, the IntegerEntryMethod field is used.
+ If IsInteger is FALSE, the RegisterEntryMethod field is used.
+ */
+ BOOLEAN IsInteger;
+
+ /** EntryMethod described as an Integer.
+ */
+ UINT64 IntegerEntryMethod;
+
+ /** EntryMethod described as a EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR.
+ */
+ EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE RegisterEntryMethod;
+
+ /** Residency counter register.
+ */
+ EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ResidencyCounterRegister;
+
+ /** Usage counter register.
+ */
+ EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE UsageCounterRegister;
+
+ /** String representing the Lpi state
+ */
+ CHAR8 StateName[16];
+} CM_ARCH_COMMON_LPI_INFO;
+
+/** A structure that describes the Processor Hierarchy Node (Type 0) in PPTT
+
+ ID: EArchCommonObjProcHierarchyInfo
+*/
+typedef struct CmArchCommonProcHierarchyInfo {
+ /// A unique token used to identify this object
+ CM_OBJECT_TOKEN Token;
+ /// Processor structure flags (ACPI 6.3 - January 2019, PPTT, Table 5-155)
+ UINT32 Flags;
+ /// Token for the parent CM_ARCH_COMMON_PROC_HIERARCHY_INFO object in the processor
+ /// topology. A value of CM_NULL_TOKEN means this node has no parent.
+ CM_OBJECT_TOKEN ParentToken;
+ /// Token of the associated object which has the corresponding ACPI Processor
+ /// ID, e.g. for Arm systems this is a reference to CM_ARM_GICC_INFO object.
+ /// A value of CM_NULL_TOKEN means this node represents a group of associated
+ /// processors and it does not have an associated CPU interface.
+ CM_OBJECT_TOKEN AcpiIdObjectToken;
+ /// Number of resources private to this Node
+ UINT32 NoOfPrivateResources;
+ /// Token of the array which contains references to the resources private to
+ /// this CM_ARCH_COMMON_PROC_HIERARCHY_INFO instance. This field is ignored if
+ /// the NoOfPrivateResources is 0, in which case it is recommended to set
+ /// this field to CM_NULL_TOKEN.
+ CM_OBJECT_TOKEN PrivateResourcesArrayToken;
+ /// Optional field: Reference Token for the Lpi state of this processor.
+ /// Token identifying a CM_ARCH_COMMON_OBJ_REF structure, itself referencing
+ /// CM_ARCH_COMMON_LPI_INFO objects.
+ CM_OBJECT_TOKEN LpiToken;
+ /// Set to TRUE if UID should override index for name and _UID
+ /// for processor container nodes and name of processors.
+ /// This should be consistently set for containers or processors to avoid
+ /// duplicate values
+ BOOLEAN OverrideNameUidEnabled;
+ /// If OverrideNameUidEnabled is TRUE then this value will be used for name of
+ /// processors and processor containers.
+ UINT16 OverrideName;
+ /// If OverrideNameUidEnabled is TRUE then this value will be used for
+ /// the UID of processor containers.
+ UINT32 OverrideUid;
+} CM_ARCH_COMMON_PROC_HIERARCHY_INFO;
+
+/** A structure that describes the Cache Type Structure (Type 1) in PPTT
+
+ ID: EArchCommonObjCacheInfo
+*/
+typedef struct CmArchCommonCacheInfo {
+ /// A unique token used to identify this object
+ CM_OBJECT_TOKEN Token;
+ /// Reference token for the next level of cache that is private to the same
+ /// CM_ARCH_COMMON_PROC_HIERARCHY_INFO instance. A value of CM_NULL_TOKEN
+ /// means this entry represents the last cache level appropriate to the
+ /// processor hierarchy node structures using this entry.
+ CM_OBJECT_TOKEN NextLevelOfCacheToken;
+ /// Size of the cache in bytes
+ UINT32 Size;
+ /// Number of sets in the cache
+ UINT32 NumberOfSets;
+ /// Integer number of ways. The maximum associativity supported by
+ /// ACPI Cache type structure is limited to MAX_UINT8. However,
+ /// the maximum number of ways supported by the architecture is
+ /// PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX. Therfore this field
+ /// is 32-bit wide.
+ UINT32 Associativity;
+ /// Cache attributes (ACPI 6.4 - January 2021, PPTT, Table 5.140)
+ UINT8 Attributes;
+ /// Line size in bytes
+ UINT16 LineSize;
+ /// Unique ID for the cache
+ UINT32 CacheId;
+} CM_ARCH_COMMON_CACHE_INFO;
+
+/** A structure that describes the Cpc information.
+
+ Continuous Performance Control is described in DSDT/SSDT and associated
+ to cpus/clusters in the cpu topology.
+
+ Unsupported Optional registers should be encoded with NULL resource
+ Register {(SystemMemory, 0, 0, 0, 0)}
+
+ For values that support Integer or Buffer, integer will be used
+ if buffer is NULL resource.
+ If resource is not NULL then Integer must be 0
+
+ Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)
+
+ ID: EArchCommonObjCpcInfo
+*/
+typedef AML_CPC_INFO CM_ARCH_COMMON_CPC_INFO;
+
+/** A structure that describes a
+ PCC Mailbox Register.
+*/
+typedef struct PccMailboxRegisterInfo {
+ /// GAS describing the Register.
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE Register;
+
+ /** Mask of bits to preserve when writing.
+
+ This mask is also used for registers. The Register is only read
+ and there is no write mask required. E.g.:
+ - Error Status mask (Cf. PCC Subspace types 3/4/5).
+ - Command Complete Check mask (Cf. PCC Subspace types 3/4/5).
+ */
+ UINT64 PreserveMask;
+
+ /// Mask of bits to set when writing.
+ UINT64 WriteMask;
+} PCC_MAILBOX_REGISTER_INFO;
+
+/** A structure that describes the
+ PCC Subspace CHannel Timings.
+*/
+typedef struct PccSubspaceChannelTimingInfo {
+ /// Expected latency to process a command, in microseconds.
+ UINT32 NominalLatency;
+
+ /** Maximum number of periodic requests that the subspace channel can
+ support, reported in commands per minute. 0 indicates no limitation.
+
+ This field is ignored for the PCC Subspace type 5 (HW Registers based).
+ */
+ UINT32 MaxPeriodicAccessRate;
+
+ /** Minimum amount of time that OSPM must wait after the completion
+ of a command before issuing the next command, in microseconds.
+ */
+ UINT16 MinRequestTurnaroundTime;
+} PCC_SUBSPACE_CHANNEL_TIMING_INFO;
+
+/** A structure that describes a
+ Generic PCC Subspace (Type 0).
+*/
+typedef struct PccSubspaceGenericInfo {
+ /** Subspace Id.
+
+ Cf. ACPI 6.4, s14.7 Referencing the PCC address space
+ Cf. s14.1.2 Platform Communications Channel Subspace Structures
+ The subspace ID of a PCC subspace is its index in the array of
+ subspace structures, starting with subspace 0.
+
+ At most 256 subspaces are supported.
+ */
+ UINT8 SubspaceId;
+
+ /// Table type (or subspace).
+ UINT8 Type;
+
+ /// Base address of the shared memory range.
+ /// This field is ignored for the PCC Subspace type 5 (HW Registers based).
+ UINT64 BaseAddress;
+
+ /// Address length.
+ UINT64 AddressLength;
+
+ /// Doorbell Register.
+ PCC_MAILBOX_REGISTER_INFO DoorbellReg;
+
+ /// Mailbox Timings.
+ PCC_SUBSPACE_CHANNEL_TIMING_INFO ChannelTiming;
+} PCC_SUBSPACE_GENERIC_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 0 (Generic).
+
+ ID: EArchCommonObjPccSubspaceType0Info
+*/
+typedef PCC_SUBSPACE_GENERIC_INFO CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 1 (HW-Reduced).
+
+ ID: EArchCommonObjPccSubspaceType1Info
+*/
+typedef struct CmArchCommonPccSubspaceType1Info {
+ /** Generic Pcc information.
+
+ The Subspace of Type0 contains information that can be re-used
+ in other Subspace types.
+ */
+ PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
+
+ /// Platform Interrupt.
+ CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq;
+} CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 2 (HW-Reduced).
+
+ ID: EArchCommonObjPccSubspaceType2Info
+*/
+typedef struct CmArchCommonPccSubspaceType2Info {
+ /** Generic Pcc information.
+
+ The Subspace of Type0 contains information that can be re-used
+ in other Subspace types.
+ */
+ PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
+
+ /// Platform Interrupt.
+ CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq;
+
+ /// Platform Interrupt Register.
+ PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg;
+} CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 3 (Extended)
+
+ ID: EArchCommonObjPccSubspaceType3Info
+*/
+typedef struct CmArchCommonPccSubspaceType3Info {
+ /** Generic Pcc information.
+
+ The Subspace of Type0 contains information that can be re-used
+ in other Subspace types.
+ */
+ PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
+
+ /// Platform Interrupt.
+ CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq;
+
+ /// Platform Interrupt Register.
+ PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg;
+
+ /// Command Complete Check Register.
+ /// The WriteMask field is not used.
+ PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg;
+
+ /// Command Complete Update Register.
+ PCC_MAILBOX_REGISTER_INFO CmdCompleteUpdateReg;
+
+ /// Error Status Register.
+ /// The WriteMask field is not used.
+ PCC_MAILBOX_REGISTER_INFO ErrorStatusReg;
+} CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 4 (Extended)
+
+ ID: EArchCommonObjPccSubspaceType4Info
+*/
+typedef CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 5 (HW-Registers).
+
+ ID: EArchCommonObjPccSubspaceType5Info
+*/
+typedef struct CmArchCommonPccSubspaceType5Info {
+ /** Generic Pcc information.
+
+ The Subspace of Type0 contains information that can be re-used
+ in other Subspace types.
+
+ MaximumPeriodicAccessRate doesn't need to be populated for
+ this structure.
+ */
+ PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
+
+ /// Version.
+ UINT16 Version;
+
+ /// Platform Interrupt.
+ CM_ARCH_COMMON_GENERIC_INTERRUPT PlatIrq;
+
+ /// Command Complete Check Register.
+ /// The WriteMask field is not used.
+ PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg;
+
+ /// Error Status Register.
+ /// The WriteMask field is not used.
+ PCC_MAILBOX_REGISTER_INFO ErrorStatusReg;
+} CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO;
+
+/** A structure that describes a
+ P-State Dependency (PSD) Info.
+
+ Cf. ACPI 6.5, s8.4.5.5 _PSD (P-State Dependency).
+
+ ID: EArchCommonObjPsdInfo
+*/
+typedef AML_PSD_INFO CM_ARCH_COMMON_PSD_INFO;
+
+/** A structure that describes TPM interface and access method.
+
+ TCG ACPI Specification 2.0
+
+ ID: EArchCommonObjTpm2InterfaceInfo
+*/
+typedef struct CmArchCommonTpm2InterfaceInfo {
+ /** Platform Class
+ 0: Client platform
+ 1: Server platform
+ */
+ UINT16 PlatformClass;
+
+ /** Physical address of the Control Area */
+ UINT64 AddressOfControlArea;
+
+ /** The Start Method selector determines which mechanism the
+ device driver uses to notify the TPM 2.0 device that a
+ command is available for processing.
+ */
+ UINT32 StartMethod;
+
+ /** The number of bytes stored in StartMethodParameters[] */
+ UINT8 StartMethodParametersSize;
+
+ /** Start method specific parameters */
+ UINT8 StartMethodParameters[EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE];
+
+ /** Log Area Minimum Length */
+ UINT32 Laml;
+
+ /** Log Area Start Address */
+ UINT64 Lasa;
+} CM_ARCH_COMMON_TPM2_INTERFACE_INFO;
+
+#pragma pack()
+
+#endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_
diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index 4a419a8..958c3dc 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -20,59 +20,38 @@
/** The EARM_OBJECT_ID enum describes the Object IDs
in the ARM Namespace
+
+ Note: Whenever an entry in this enum is updated,
+ the following data structures must also be
+ updated:
+ - CM_OBJECT_TOKEN_FIXER TokenFixer[] in
+ Library\Common\DynamicPlatRepoLib\CmObjectTokenFixer.c
*/
typedef enum ArmObjectID {
EArmObjReserved, ///< 0 - Reserved
EArmObjBootArchInfo, ///< 1 - Boot Architecture Info
- EArmObjCpuInfo, ///< 2 - CPU Info
- EArmObjPowerManagementProfileInfo, ///< 3 - Power Management Profile Info
- EArmObjGicCInfo, ///< 4 - GIC CPU Interface Info
- EArmObjGicDInfo, ///< 5 - GIC Distributor Info
- EArmObjGicMsiFrameInfo, ///< 6 - GIC MSI Frame Info
- EArmObjGicRedistributorInfo, ///< 7 - GIC Redistributor Info
- EArmObjGicItsInfo, ///< 8 - GIC ITS Info
- EArmObjSerialConsolePortInfo, ///< 9 - Serial Console Port Info
- EArmObjSerialDebugPortInfo, ///< 10 - Serial Debug Port Info
- EArmObjGenericTimerInfo, ///< 11 - Generic Timer Info
- EArmObjPlatformGTBlockInfo, ///< 12 - Platform GT Block Info
- EArmObjGTBlockTimerFrameInfo, ///< 13 - Generic Timer Block Frame Info
- EArmObjPlatformGenericWatchdogInfo, ///< 14 - Platform Generic Watchdog
- EArmObjPciConfigSpaceInfo, ///< 15 - PCI Configuration Space Info
- EArmObjHypervisorVendorIdentity, ///< 16 - Hypervisor Vendor Id
- EArmObjFixedFeatureFlags, ///< 17 - Fixed feature flags for FADT
- EArmObjItsGroup, ///< 18 - ITS Group
- EArmObjNamedComponent, ///< 19 - Named Component
- EArmObjRootComplex, ///< 20 - Root Complex
- EArmObjSmmuV1SmmuV2, ///< 21 - SMMUv1 or SMMUv2
- EArmObjSmmuV3, ///< 22 - SMMUv3
- EArmObjPmcg, ///< 23 - PMCG
- EArmObjGicItsIdentifierArray, ///< 24 - GIC ITS Identifier Array
- EArmObjIdMappingArray, ///< 25 - ID Mapping Array
- EArmObjSmmuInterruptArray, ///< 26 - SMMU Interrupt Array
- EArmObjProcHierarchyInfo, ///< 27 - Processor Hierarchy Info
- EArmObjCacheInfo, ///< 28 - Cache Info
- EArmObjReserved29, ///< 29 - Reserved
- EArmObjCmRef, ///< 30 - CM Object Reference
- EArmObjMemoryAffinityInfo, ///< 31 - Memory Affinity Info
- EArmObjDeviceHandleAcpi, ///< 32 - Device Handle Acpi
- EArmObjDeviceHandlePci, ///< 33 - Device Handle Pci
- EArmObjGenericInitiatorAffinityInfo, ///< 34 - Generic Initiator Affinity
- EArmObjSerialPortInfo, ///< 35 - Generic Serial Port Info
- EArmObjCmn600Info, ///< 36 - CMN-600 Info
- EArmObjLpiInfo, ///< 37 - Lpi Info
- EArmObjPciAddressMapInfo, ///< 38 - Pci Address Map Info
- EArmObjPciInterruptMapInfo, ///< 39 - Pci Interrupt Map Info
- EArmObjRmr, ///< 40 - Reserved Memory Range Node
- EArmObjMemoryRangeDescriptor, ///< 41 - Memory Range Descriptor
- EArmObjCpcInfo, ///< 42 - Continuous Performance Control Info
- EArmObjPccSubspaceType0Info, ///< 43 - Pcc Subspace Type 0 Info
- EArmObjPccSubspaceType1Info, ///< 44 - Pcc Subspace Type 2 Info
- EArmObjPccSubspaceType2Info, ///< 45 - Pcc Subspace Type 2 Info
- EArmObjPccSubspaceType3Info, ///< 46 - Pcc Subspace Type 3 Info
- EArmObjPccSubspaceType4Info, ///< 47 - Pcc Subspace Type 4 Info
- EArmObjPccSubspaceType5Info, ///< 48 - Pcc Subspace Type 5 Info
- EArmObjEtInfo, ///< 49 - Embedded Trace Extension/Module Info
- EArmObjPsdInfo, ///< 50 - P-State Dependency (PSD) Info
+ EArmObjGicCInfo, ///< 2 - GIC CPU Interface Info
+ EArmObjGicDInfo, ///< 3 - GIC Distributor Info
+ EArmObjGicMsiFrameInfo, ///< 4 - GIC MSI Frame Info
+ EArmObjGicRedistributorInfo, ///< 5 - GIC Redistributor Info
+ EArmObjGicItsInfo, ///< 6 - GIC ITS Info
+ EArmObjGenericTimerInfo, ///< 7 - Generic Timer Info
+ EArmObjPlatformGTBlockInfo, ///< 8 - Platform GT Block Info
+ EArmObjGTBlockTimerFrameInfo, ///< 9 - Generic Timer Block Frame Info
+ EArmObjPlatformGenericWatchdogInfo, ///< 10 - Platform Generic Watchdog
+ EArmObjItsGroup, ///< 11 - ITS Group
+ EArmObjNamedComponent, ///< 12 - Named Component
+ EArmObjRootComplex, ///< 13 - Root Complex
+ EArmObjSmmuV1SmmuV2, ///< 14 - SMMUv1 or SMMUv2
+ EArmObjSmmuV3, ///< 15 - SMMUv3
+ EArmObjPmcg, ///< 16 - PMCG
+ EArmObjGicItsIdentifierArray, ///< 17 - GIC ITS Identifier Array
+ EArmObjIdMappingArray, ///< 18 - ID Mapping Array
+ EArmObjSmmuInterruptArray, ///< 19 - SMMU Interrupt Array
+ EArmObjCmn600Info, ///< 20 - CMN-600 Info
+ EArmObjRmr, ///< 21 - Reserved Memory Range Node
+ EArmObjMemoryRangeDescriptor, ///< 22 - Memory Range Descriptor
+ EArmObjEtInfo, ///< 23 - Embedded Trace Extension/Module Info
EArmObjMax
} EARM_OBJECT_ID;
@@ -89,18 +68,6 @@ typedef struct CmArmBootArchInfo {
} CM_ARM_BOOT_ARCH_INFO;
/** A structure that describes the
- Power Management Profile Information for the Platform.
-
- ID: EArmObjPowerManagementProfileInfo
-*/
-typedef struct CmArmPowerManagementProfileInfo {
- /** This is the Preferred_PM_Profile field of the FADT Table
- described in the ACPI Specification
- */
- UINT8 PowerManagementProfile;
-} CM_ARM_POWER_MANAGEMENT_PROFILE_INFO;
-
-/** A structure that describes the
GIC CPU Interface for the Platform.
ID: EArmObjGicCInfo
@@ -202,7 +169,7 @@ typedef struct CmArmGicCInfo {
UINT32 AffinityFlags;
/** Optional field: Reference Token for the Cpc info of this processor.
- i.e. a token referencing a CM_ARM_CPC_INFO object.
+ i.e. a token referencing a CM_ARCH_COMMON_CPC_INFO object.
*/
CM_OBJECT_TOKEN CpcToken;
@@ -220,7 +187,7 @@ typedef struct CmArmGicCInfo {
CM_OBJECT_TOKEN EtToken;
/** Optional field: Reference Token for the Psd info of this processor.
- i.e. a token referencing a CM_ARM_PSD_INFO object.
+ i.e. a token referencing a CM_ARCH_COMMON_PSD_INFO object.
*/
CM_OBJECT_TOKEN PsdToken;
} CM_ARM_GICC_INFO;
@@ -307,39 +274,6 @@ typedef struct CmArmGicItsInfo {
} CM_ARM_GIC_ITS_INFO;
/** A structure that describes the
- Serial Port information for the Platform.
-
- ID: EArmObjSerialConsolePortInfo or
- EArmObjSerialDebugPortInfo or
- EArmObjSerialPortInfo
-*/
-typedef struct CmArmSerialPortInfo {
- /// The physical base address for the serial port
- UINT64 BaseAddress;
-
- /** The serial port interrupt.
- 0 indicates that the serial port does not
- have an interrupt wired.
- */
- UINT32 Interrupt;
-
- /// The serial port baud rate
- UINT64 BaudRate;
-
- /// The serial port clock
- UINT32 Clock;
-
- /// Serial Port subtype
- UINT16 PortSubtype;
-
- /// The Base address length
- UINT64 BaseAddressLength;
-
- /// The access size
- UINT8 AccessSize;
-} CM_ARM_SERIAL_PORT_INFO;
-
-/** A structure that describes the
Generic Timer information for the Platform.
ID: EArmObjGenericTimerInfo
@@ -457,53 +391,6 @@ typedef struct CmArmGenericWatchdogInfo {
} CM_ARM_GENERIC_WATCHDOG_INFO;
/** A structure that describes the
- PCI Configuration Space information for the Platform.
-
- ID: EArmObjPciConfigSpaceInfo
-*/
-typedef struct CmArmPciConfigSpaceInfo {
- /// The physical base address for the PCI segment
- UINT64 BaseAddress;
-
- /// The PCI segment group number
- UINT16 PciSegmentGroupNumber;
-
- /// The start bus number
- UINT8 StartBusNumber;
-
- /// The end bus number
- UINT8 EndBusNumber;
-
- /// Optional field: Reference Token for address mapping.
- /// Token identifying a CM_ARM_OBJ_REF structure.
- CM_OBJECT_TOKEN AddressMapToken;
-
- /// Optional field: Reference Token for interrupt mapping.
- /// Token identifying a CM_ARM_OBJ_REF structure.
- CM_OBJECT_TOKEN InterruptMapToken;
-} CM_ARM_PCI_CONFIG_SPACE_INFO;
-
-/** A structure that describes the
- Hypervisor Vendor ID information for the Platform.
-
- ID: EArmObjHypervisorVendorIdentity
-*/
-typedef struct CmArmHypervisorVendorId {
- /// The hypervisor Vendor ID
- UINT64 HypervisorVendorId;
-} CM_ARM_HYPERVISOR_VENDOR_ID;
-
-/** A structure that describes the
- Fixed feature flags for the Platform.
-
- ID: EArmObjFixedFeatureFlags
-*/
-typedef struct CmArmFixedFeatureFlags {
- /// The Fixed feature flags
- UINT32 Flags;
-} CM_ARM_FIXED_FEATURE_FLAGS;
-
-/** A structure that describes the
ITS Group node for the Platform.
ID: EArmObjItsGroup
@@ -729,21 +616,6 @@ typedef struct CmArmIdMapping {
UINT32 Flags;
} CM_ARM_ID_MAPPING;
-/** A structure that describes the Arm
- Generic Interrupts.
-*/
-typedef struct CmArmGenericInterrupt {
- /// Interrupt number
- UINT32 Interrupt;
-
- /// Flags
- /// BIT0: 0: Interrupt is Level triggered
- /// 1: Interrupt is Edge triggered
- /// BIT1: 0: Interrupt is Active high
- /// 1: Interrupt is Active low
- UINT32 Flags;
-} CM_ARM_GENERIC_INTERRUPT;
-
/** A structure that describes the SMMU interrupts for the Platform.
Interrupt Interrupt number.
@@ -751,7 +623,7 @@ typedef struct CmArmGenericInterrupt {
ID: EArmObjSmmuInterruptArray
*/
-typedef CM_ARM_GENERIC_INTERRUPT CM_ARM_SMMU_INTERRUPT;
+typedef CM_ARCH_COMMON_GENERIC_INTERRUPT CM_ARM_SMMU_INTERRUPT;
/** A structure that describes the AML Extended Interrupts.
@@ -761,162 +633,7 @@ typedef CM_ARM_GENERIC_INTERRUPT CM_ARM_SMMU_INTERRUPT;
resource descriptor.
See EFI_ACPI_EXTENDED_INTERRUPT_FLAG_xxx in Acpi10.h
*/
-typedef CM_ARM_GENERIC_INTERRUPT CM_ARM_EXTENDED_INTERRUPT;
-
-/** A structure that describes the Processor Hierarchy Node (Type 0) in PPTT
-
- ID: EArmObjProcHierarchyInfo
-*/
-typedef struct CmArmProcHierarchyInfo {
- /// A unique token used to identify this object
- CM_OBJECT_TOKEN Token;
- /// Processor structure flags (ACPI 6.3 - January 2019, PPTT, Table 5-155)
- UINT32 Flags;
- /// Token for the parent CM_ARM_PROC_HIERARCHY_INFO object in the processor
- /// topology. A value of CM_NULL_TOKEN means this node has no parent.
- CM_OBJECT_TOKEN ParentToken;
- /// Token of the associated CM_ARM_GICC_INFO object which has the
- /// corresponding ACPI Processor ID. A value of CM_NULL_TOKEN means this
- /// node represents a group of associated processors and it does not have an
- /// associated GIC CPU interface.
- CM_OBJECT_TOKEN GicCToken;
- /// Number of resources private to this Node
- UINT32 NoOfPrivateResources;
- /// Token of the array which contains references to the resources private to
- /// this CM_ARM_PROC_HIERARCHY_INFO instance. This field is ignored if
- /// the NoOfPrivateResources is 0, in which case it is recommended to set
- /// this field to CM_NULL_TOKEN.
- CM_OBJECT_TOKEN PrivateResourcesArrayToken;
- /// Optional field: Reference Token for the Lpi state of this processor.
- /// Token identifying a CM_ARM_OBJ_REF structure, itself referencing
- /// CM_ARM_LPI_INFO objects.
- CM_OBJECT_TOKEN LpiToken;
- /// Set to TRUE if UID should override index for name and _UID
- /// for processor container nodes and name of processors.
- /// This should be consistently set for containers or processors to avoid
- /// duplicate values
- BOOLEAN OverrideNameUidEnabled;
- /// If OverrideNameUidEnabled is TRUE then this value will be used for name of
- /// processors and processor containers.
- UINT16 OverrideName;
- /// If OverrideNameUidEnabled is TRUE then this value will be used for
- /// the UID of processor containers.
- UINT32 OverrideUid;
-} CM_ARM_PROC_HIERARCHY_INFO;
-
-/** A structure that describes the Cache Type Structure (Type 1) in PPTT
-
- ID: EArmObjCacheInfo
-*/
-typedef struct CmArmCacheInfo {
- /// A unique token used to identify this object
- CM_OBJECT_TOKEN Token;
- /// Reference token for the next level of cache that is private to the same
- /// CM_ARM_PROC_HIERARCHY_INFO instance. A value of CM_NULL_TOKEN means this
- /// entry represents the last cache level appropriate to the processor
- /// hierarchy node structures using this entry.
- CM_OBJECT_TOKEN NextLevelOfCacheToken;
- /// Size of the cache in bytes
- UINT32 Size;
- /// Number of sets in the cache
- UINT32 NumberOfSets;
- /// Integer number of ways. The maximum associativity supported by
- /// ACPI Cache type structure is limited to MAX_UINT8. However,
- /// the maximum number of ways supported by the architecture is
- /// PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX. Therfore this field
- /// is 32-bit wide.
- UINT32 Associativity;
- /// Cache attributes (ACPI 6.4 - January 2021, PPTT, Table 5.140)
- UINT8 Attributes;
- /// Line size in bytes
- UINT16 LineSize;
- /// Unique ID for the cache
- UINT32 CacheId;
-} CM_ARM_CACHE_INFO;
-
-/** A structure that describes a reference to another Configuration Manager
- object.
-
- This is useful for creating an array of reference tokens. The framework
- can then query the configuration manager for these arrays using the
- object ID EArmObjCmRef.
-
- This can be used is to represent one-to-many relationships between objects.
-
- ID: EArmObjCmRef
-*/
-typedef struct CmArmObjRef {
- /// Token of the CM object being referenced
- CM_OBJECT_TOKEN ReferenceToken;
-} CM_ARM_OBJ_REF;
-
-/** A structure that describes the Memory Affinity Structure (Type 1) in SRAT
-
- ID: EArmObjMemoryAffinityInfo
-*/
-typedef struct CmArmMemoryAffinityInfo {
- /// The proximity domain to which the "range of memory" belongs.
- UINT32 ProximityDomain;
-
- /// Base Address
- UINT64 BaseAddress;
-
- /// Length
- UINT64 Length;
-
- /// Flags
- UINT32 Flags;
-} CM_ARM_MEMORY_AFFINITY_INFO;
-
-/** A structure that describes the ACPI Device Handle (Type 0) in the
- Generic Initiator Affinity structure in SRAT
-
- ID: EArmObjDeviceHandleAcpi
-*/
-typedef struct CmArmDeviceHandleAcpi {
- /// Hardware ID
- UINT64 Hid;
-
- /// Unique Id
- UINT32 Uid;
-} CM_ARM_DEVICE_HANDLE_ACPI;
-
-/** A structure that describes the PCI Device Handle (Type 1) in the
- Generic Initiator Affinity structure in SRAT
-
- ID: EArmObjDeviceHandlePci
-*/
-typedef struct CmArmDeviceHandlePci {
- /// PCI Segment Number
- UINT16 SegmentNumber;
-
- /// PCI Bus Number - Max 256 busses (Bits 15:8 of BDF)
- UINT8 BusNumber;
-
- /// PCI Device Number - Max 32 devices (Bits 7:3 of BDF)
- UINT8 DeviceNumber;
-
- /// PCI Function Number - Max 8 functions (Bits 2:0 of BDF)
- UINT8 FunctionNumber;
-} CM_ARM_DEVICE_HANDLE_PCI;
-
-/** A structure that describes the Generic Initiator Affinity structure in SRAT
-
- ID: EArmObjGenericInitiatorAffinityInfo
-*/
-typedef struct CmArmGenericInitiatorAffinityInfo {
- /// The proximity domain to which the generic initiator belongs.
- UINT32 ProximityDomain;
-
- /// Flags
- UINT32 Flags;
-
- /// Device Handle Type
- UINT8 DeviceHandleType;
-
- /// Reference Token for the Device Handle
- CM_OBJECT_TOKEN DeviceHandleToken;
-} CM_ARM_GENERIC_INITIATOR_AFFINITY_INFO;
+typedef CM_ARCH_COMMON_GENERIC_INTERRUPT CM_ARM_EXTENDED_INTERRUPT;
/** A structure that describes the CMN-600 hardware.
@@ -950,133 +667,6 @@ typedef struct CmArmCmn600Info {
CM_ARM_EXTENDED_INTERRUPT DtcInterrupt[4];
} CM_ARM_CMN_600_INFO;
-/** A structure that describes the Lpi information.
-
- The Low Power Idle states are described in DSDT/SSDT and associated
- to cpus/clusters in the cpu topology.
-
- ID: EArmObjLpiInfo
-*/
-typedef struct CmArmLpiInfo {
- /** Minimum Residency. Time in microseconds after which a
- state becomes more energy efficient than any shallower state.
- */
- UINT32 MinResidency;
-
- /** Worst case time in microseconds from a wake interrupt
- being asserted to the return to a running state
- */
- UINT32 WorstCaseWakeLatency;
-
- /** Flags.
- */
- UINT32 Flags;
-
- /** Architecture specific context loss flags.
- */
- UINT32 ArchFlags;
-
- /** Residency counter frequency in cycles-per-second (Hz).
- */
- UINT32 ResCntFreq;
-
- /** Every shallower power state in the parent is also enabled.
- */
- UINT32 EnableParentState;
-
- /** The EntryMethod _LPI field can be described as an integer
- or in a Register resource data descriptor.
-
- If IsInteger is TRUE, the IntegerEntryMethod field is used.
- If IsInteger is FALSE, the RegisterEntryMethod field is used.
- */
- BOOLEAN IsInteger;
-
- /** EntryMethod described as an Integer.
- */
- UINT64 IntegerEntryMethod;
-
- /** EntryMethod described as a EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR.
- */
- EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE RegisterEntryMethod;
-
- /** Residency counter register.
- */
- EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ResidencyCounterRegister;
-
- /** Usage counter register.
- */
- EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE UsageCounterRegister;
-
- /** String representing the Lpi state
- */
- CHAR8 StateName[16];
-} CM_ARM_LPI_INFO;
-
-/** A structure that describes a PCI Address Map.
-
- The memory-ranges used by the PCI bus are described by this object.
-
- ID: EArmObjPciAddressMapInfo
-*/
-typedef struct CmArmPciAddressMapInfo {
- /** Pci address space code
-
- Available values are:
- - 0: Configuration Space
- - 1: I/O Space
- - 2: 32-bit-address Memory Space
- - 3: 64-bit-address Memory Space
- */
- UINT8 SpaceCode;
-
- /// PCI address
- UINT64 PciAddress;
-
- /// Cpu address
- UINT64 CpuAddress;
-
- /// Address size
- UINT64 AddressSize;
-} CM_ARM_PCI_ADDRESS_MAP_INFO;
-
-/** A structure that describes a PCI Interrupt Map.
-
- The legacy PCI interrupts used by PCI devices are described by this object.
-
- Cf Devicetree Specification - Release v0.3
- s2.4.3 "Interrupt Nexus Properties"
-
- ID: EArmObjPciInterruptMapInfo
-*/
-typedef struct CmArmPciInterruptMapInfo {
- /// Pci Bus.
- /// Value on 8 bits (max 255).
- UINT8 PciBus;
-
- /// Pci Device.
- /// Value on 5 bits (max 31).
- UINT8 PciDevice;
-
- /** PCI interrupt
-
- ACPI bindings are used:
- Cf. ACPI 6.4, s6.2.13 _PRT (PCI Routing Table):
- "0-INTA, 1-INTB, 2-INTC, 3-INTD"
-
- Device-tree bindings are shifted by 1:
- "INTA=1, INTB=2, INTC=3, INTD=4"
- */
- UINT8 PciInterrupt;
-
- /** Interrupt controller interrupt.
-
- Cf Devicetree Specification - Release v0.3
- s2.4.3 "Interrupt Nexus Properties": "parent interrupt specifier"
- */
- CM_ARM_GENERIC_INTERRUPT IntcInterrupt;
-} CM_ARM_PCI_INTERRUPT_MAP_INFO;
-
/** A structure that describes the
RMR node for the Platform.
@@ -1117,209 +707,6 @@ typedef struct CmArmRmrDescriptor {
UINT64 Length;
} CM_ARM_MEMORY_RANGE_DESCRIPTOR;
-/** A structure that describes the Cpc information.
-
- Continuous Performance Control is described in DSDT/SSDT and associated
- to cpus/clusters in the cpu topology.
-
- Unsupported Optional registers should be encoded with NULL resource
- Register {(SystemMemory, 0, 0, 0, 0)}
-
- For values that support Integer or Buffer, integer will be used
- if buffer is NULL resource.
- If resource is not NULL then Integer must be 0
-
- Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)
-
- ID: EArmObjCpcInfo
-*/
-typedef AML_CPC_INFO CM_ARM_CPC_INFO;
-
-/** A structure that describes a
- PCC Mailbox Register.
-*/
-typedef struct PccMailboxRegisterInfo {
- /// GAS describing the Register.
- EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE Register;
-
- /** Mask of bits to preserve when writing.
-
- This mask is also used for registers. The Register is only read
- and there is no write mask required. E.g.:
- - Error Status mask (Cf. PCC Subspace types 3/4/5).
- - Command Complete Check mask (Cf. PCC Subspace types 3/4/5).
- */
- UINT64 PreserveMask;
-
- /// Mask of bits to set when writing.
- UINT64 WriteMask;
-} PCC_MAILBOX_REGISTER_INFO;
-
-/** A structure that describes the
- PCC Subspace CHannel Timings.
-*/
-typedef struct PccSubspaceChannelTimingInfo {
- /// Expected latency to process a command, in microseconds.
- UINT32 NominalLatency;
-
- /** Maximum number of periodic requests that the subspace channel can
- support, reported in commands per minute. 0 indicates no limitation.
-
- This field is ignored for the PCC Subspace type 5 (HW Registers based).
- */
- UINT32 MaxPeriodicAccessRate;
-
- /** Minimum amount of time that OSPM must wait after the completion
- of a command before issuing the next command, in microseconds.
- */
- UINT16 MinRequestTurnaroundTime;
-} PCC_SUBSPACE_CHANNEL_TIMING_INFO;
-
-/** A structure that describes a
- Generic PCC Subspace (Type 0).
-*/
-typedef struct CmArmPccSubspaceGenericInfo {
- /** Subspace Id.
-
- Cf. ACPI 6.4, s14.7 Referencing the PCC address space
- Cf. s14.1.2 Platform Communications Channel Subspace Structures
- The subspace ID of a PCC subspace is its index in the array of
- subspace structures, starting with subspace 0.
-
- At most 256 subspaces are supported.
- */
- UINT8 SubspaceId;
-
- /// Table type (or subspace).
- UINT8 Type;
-
- /// Base address of the shared memory range.
- /// This field is ignored for the PCC Subspace type 5 (HW Registers based).
- UINT64 BaseAddress;
-
- /// Address length.
- UINT64 AddressLength;
-
- /// Doorbell Register.
- PCC_MAILBOX_REGISTER_INFO DoorbellReg;
-
- /// Mailbox Timings.
- PCC_SUBSPACE_CHANNEL_TIMING_INFO ChannelTiming;
-} PCC_SUBSPACE_GENERIC_INFO;
-
-/** A structure that describes a
- PCC Subspace of type 0 (Generic).
-
- ID: EArmObjPccSubspaceType0Info
-*/
-typedef PCC_SUBSPACE_GENERIC_INFO CM_ARM_PCC_SUBSPACE_TYPE0_INFO;
-
-/** A structure that describes a
- PCC Subspace of type 1 (HW-Reduced).
-
- ID: EArmObjPccSubspaceType1Info
-*/
-typedef struct CmArmPccSubspaceType1Info {
- /** Generic Pcc information.
-
- The Subspace of Type0 contains information that can be re-used
- in other Subspace types.
- */
- PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
-
- /// Platform Interrupt.
- CM_ARM_GENERIC_INTERRUPT PlatIrq;
-} CM_ARM_PCC_SUBSPACE_TYPE1_INFO;
-
-/** A structure that describes a
- PCC Subspace of type 2 (HW-Reduced).
-
- ID: EArmObjPccSubspaceType2Info
-*/
-typedef struct CmArmPccSubspaceType2Info {
- /** Generic Pcc information.
-
- The Subspace of Type0 contains information that can be re-used
- in other Subspace types.
- */
- PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
-
- /// Platform Interrupt.
- CM_ARM_GENERIC_INTERRUPT PlatIrq;
-
- /// Platform Interrupt Register.
- PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg;
-} CM_ARM_PCC_SUBSPACE_TYPE2_INFO;
-
-/** A structure that describes a
- PCC Subspace of type 3 (Extended)
-
- ID: EArmObjPccSubspaceType3Info
-*/
-typedef struct CmArmPccSubspaceType3Info {
- /** Generic Pcc information.
-
- The Subspace of Type0 contains information that can be re-used
- in other Subspace types.
- */
- PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
-
- /// Platform Interrupt.
- CM_ARM_GENERIC_INTERRUPT PlatIrq;
-
- /// Platform Interrupt Register.
- PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg;
-
- /// Command Complete Check Register.
- /// The WriteMask field is not used.
- PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg;
-
- /// Command Complete Update Register.
- PCC_MAILBOX_REGISTER_INFO CmdCompleteUpdateReg;
-
- /// Error Status Register.
- /// The WriteMask field is not used.
- PCC_MAILBOX_REGISTER_INFO ErrorStatusReg;
-} CM_ARM_PCC_SUBSPACE_TYPE3_INFO;
-
-/** A structure that describes a
- PCC Subspace of type 4 (Extended)
-
- ID: EArmObjPccSubspaceType4Info
-*/
-typedef CM_ARM_PCC_SUBSPACE_TYPE3_INFO CM_ARM_PCC_SUBSPACE_TYPE4_INFO;
-
-/** A structure that describes a
- PCC Subspace of type 5 (HW-Registers).
-
- ID: EArmObjPccSubspaceType5Info
-*/
-typedef struct CmArmPccSubspaceType5Info {
- /** Generic Pcc information.
-
- The Subspace of Type0 contains information that can be re-used
- in other Subspace types.
-
- MaximumPeriodicAccessRate doesn't need to be populated for
- this structure.
- */
- PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
-
- /// Version.
- UINT16 Version;
-
- /// Platform Interrupt.
- CM_ARM_GENERIC_INTERRUPT PlatIrq;
-
- /// Command Complete Check Register.
- /// The WriteMask field is not used.
- PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg;
-
- /// Error Status Register.
- /// The WriteMask field is not used.
- PCC_MAILBOX_REGISTER_INFO ErrorStatusReg;
-} CM_ARM_PCC_SUBSPACE_TYPE5_INFO;
-
/** An enum describing the Arm Embedded Trace device type.
*/
typedef enum ArmEtType {
@@ -1336,15 +723,6 @@ typedef struct CmArmEtInfo {
ARM_ET_TYPE EtType;
} CM_ARM_ET_INFO;
-/** A structure that describes a
- P-State Dependency (PSD) Info.
-
- Cf. ACPI 6.5, s8.4.5.5 _PSD (P-State Dependency).
-
- ID: EArmObjPsdInfo
-*/
-typedef AML_PSD_INFO CM_ARM_PSD_INFO;
-
#pragma pack()
#endif // ARM_NAMESPACE_OBJECTS_H_
diff --git a/DynamicTablesPkg/Include/ConfigurationManagerObject.h b/DynamicTablesPkg/Include/ConfigurationManagerObject.h
index 74ad25d..2660522 100644
--- a/DynamicTablesPkg/Include/ConfigurationManagerObject.h
+++ b/DynamicTablesPkg/Include/ConfigurationManagerObject.h
@@ -1,19 +1,23 @@
/** @file
- Copyright (c) 2017 - 2022, ARM Limited. All rights reserved.
+ Copyright (c) 2017 - 2024, Arm Limited. All rights reserved.
+ Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Glossary:
- Cm or CM - Configuration Manager
- Obj or OBJ - Object
+ - X64 or x64 - X64 Architecture
**/
#ifndef CONFIGURATION_MANAGER_OBJECT_H_
#define CONFIGURATION_MANAGER_OBJECT_H_
+#include <ArchCommonNameSpaceObjects.h>
#include <ArmNameSpaceObjects.h>
#include <StandardNameSpaceObjects.h>
+#include <X64NameSpaceObjects.h>
#pragma pack(1)
@@ -29,8 +33,10 @@ _______________________________________________________________________________
Bits: [31:28] - Name Space ID
0000 - Standard
- 0001 - ARM
- 1000 - Custom/OEM
+ 0001 - Arch Common
+ 0010 - ARM
+ 0011 - X64
+ 1111 - Custom/OEM
All other values are reserved.
Bits: [27:16] - Reserved.
@@ -49,38 +55,11 @@ Object ID's in the Standard Namespace:
1 - ACPI Table List
2 - SMBIOS Table List
+Object ID's in the Arch Common Namespace:
+ See EARCH_COMMON_OBJECT_ID.
+
Object ID's in the ARM Namespace:
- 0 - Reserved
- 1 - Boot Architecture Info
- 2 - CPU Info
- 3 - Power Management Profile Info
- 4 - GICC Info
- 5 - GICD Info
- 6 - GIC MSI Frame Info
- 7 - GIC Redistributor Info
- 8 - GIC ITS Info
- 9 - Serial Console Port Info
- 10 - Serial Debug Port Info
- 11 - Generic Timer Info
- 12 - Platform GT Block Info
- 13 - Generic Timer Block Frame Info
- 14 - Platform Generic Watchdog
- 15 - PCI Configuration Space Info
- 16 - Hypervisor Vendor Id
- 17 - Fixed feature flags for FADT
- 18 - ITS Group
- 19 - Named Component
- 20 - Root Complex
- 21 - SMMUv1 or SMMUv2
- 22 - SMMUv3
- 23 - PMCG
- 24 - GIC ITS Identifier Array
- 25 - ID Mapping Array
- 26 - SMMU Interrupt Array
- 27 - Processor Hierarchy Info
- 28 - Cache Info
- 29 - Processor Hierarchy Node ID Info
- 30 - CM Object Reference
+ See EARM_OBJECT_ID.
*/
typedef UINT32 CM_OBJECT_ID;
@@ -105,10 +84,12 @@ typedef UINT32 CM_OBJECT_ID;
for the Configuration Manager Objects.
*/
typedef enum ObjectNameSpaceID {
- EObjNameSpaceStandard, ///< Standard Objects Namespace
- EObjNameSpaceArm, ///< ARM Objects Namespace
- EObjNameSpaceOem = 0x8, ///< OEM Objects Namespace
- EObjNameSpaceMax
+ EObjNameSpaceStandard, ///< Standard Objects Namespace
+ EObjNameSpaceArchCommon, ///< Arch Common Objects Namespace
+ EObjNameSpaceArm, ///< ARM Objects Namespace
+ EObjNameSpaceX64, ///< X64 Objects Namespace
+ EObjNameSpaceOem = 0xF, ///< OEM Objects Namespace
+ EObjNameSpaceMax,
} EOBJECT_NAMESPACE_ID;
/** A descriptor for Configuration Manager Objects.
@@ -183,6 +164,16 @@ typedef struct CmObjDescriptor {
(CREATE_CM_OBJECT_ID (EObjNameSpaceArm, ObjectId))
/** This macro returns a Configuration Manager Object ID
+ in the Arch Common Object Namespace.
+
+ @param [in] ObjectId The Object ID.
+
+ @retval Returns an Arch Common Configuration Manager Object ID.
+**/
+#define CREATE_CM_ARCH_COMMON_OBJECT_ID(ObjectId) \
+ (CREATE_CM_OBJECT_ID (EObjNameSpaceArchCommon, ObjectId))
+
+/** This macro returns a Configuration Manager Object ID
in the OEM Object Namespace.
@param [in] ObjectId The Object ID.
@@ -192,4 +183,14 @@ typedef struct CmObjDescriptor {
#define CREATE_CM_OEM_OBJECT_ID(ObjectId) \
(CREATE_CM_OBJECT_ID (EObjNameSpaceOem, ObjectId))
+/** This macro returns a Configuration Manager Object ID
+ in the X64 Object Namespace.
+
+ @param [in] ObjectId The Object ID.
+
+ @retval Returns X64 Configuration Manager Object ID.
+**/
+#define CREATE_CM_X64_OBJECT_ID(ObjectId) \
+ (CREATE_CM_OBJECT_ID (EObjNameSpaceX64, ObjectId))
+
#endif // CONFIGURATION_MANAGER_OBJECT_H_
diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
index 7c13073..13ce97c 100644
--- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
+++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
@@ -1028,6 +1028,48 @@ AmlCodeGenRdInterrupt (
OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
);
+/** Code generation for the "IO ()" ASL function.
+
+ The Resource Data effectively created is a IO Resource
+ Data. Cf ACPI 6.5:
+ - s19.6.65 IO (IO Resource Descriptor Macro)
+ - s6.4.2.5 I/O Port Descriptor
+
+ The created resource data node can be:
+ - appended to the list of resource data elements of the NameOpNode.
+ In such case NameOpNode must be defined by a the "Name ()" ASL statement
+ and initially contain a "ResourceTemplate ()".
+ - returned through the NewRdNode parameter.
+
+ @param [in] IsDecoder16 Decoder parameter.
+ TRUE if 16-bit decoder.
+ FALSE if 10-bit decoder.
+ @param [in] AddressMinimum Minimum address.
+ @param [in] AddressMaximum Maximum address.
+ @param [in] Alignment Alignment.
+ @param [in] RangeLength Range length.
+ @param [in] NameOpNode NameOp object node defining a named object.
+ If provided, append the new resource data
+ node to the list of resource data elements
+ of this node.
+ @param [out] NewRdNode If provided and success,
+ contain the created node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenRdIo (
+ IN BOOLEAN IsDecoder16,
+ IN UINT16 AddressMinimum,
+ IN UINT16 AddressMaximum,
+ IN UINT8 Alignment,
+ IN UINT8 RangeLength,
+ IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
+ OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
+ );
+
/** AML code generation for DefinitionBlock.
Create a Root Node handle.
diff --git a/DynamicTablesPkg/Include/Library/SsdtPcieSupportLib.h b/DynamicTablesPkg/Include/Library/SsdtPcieSupportLib.h
index 4171dab..50a335e 100644
--- a/DynamicTablesPkg/Include/Library/SsdtPcieSupportLib.h
+++ b/DynamicTablesPkg/Include/Library/SsdtPcieSupportLib.h
@@ -43,8 +43,8 @@ typedef struct MappingTable {
EFI_STATUS
EFIAPI
AddOscMethod (
- IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,
- IN OUT AML_OBJECT_NODE_HANDLE PciNode
+ IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo,
+ IN OUT AML_OBJECT_NODE_HANDLE PciNode
);
/** Generate Pci slots devices.
@@ -66,10 +66,10 @@ AddOscMethod (
EFI_STATUS
EFIAPI
GeneratePciSlots (
- IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,
- IN CONST MAPPING_TABLE *MappingTable,
- IN UINT32 Uid,
- IN OUT AML_OBJECT_NODE_HANDLE PciNode
+ IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo,
+ IN CONST MAPPING_TABLE *MappingTable,
+ IN UINT32 Uid,
+ IN OUT AML_OBJECT_NODE_HANDLE PciNode
);
#endif // SSDT_PCIE_SUPPORT_LIB_H_
diff --git a/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h b/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h
index 4835f31..ac7b39f 100644
--- a/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h
+++ b/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h
@@ -29,11 +29,11 @@
EFI_STATUS
EFIAPI
BuildSsdtSerialPortTable (
- IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo,
- IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo,
- IN CONST CHAR8 *Name,
- IN CONST UINT64 Uid,
- OUT EFI_ACPI_DESCRIPTION_HEADER **Table
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo,
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo,
+ IN CONST CHAR8 *Name,
+ IN CONST UINT64 Uid,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **Table
);
/** Free an SSDT table previously created by
@@ -52,7 +52,7 @@ FreeSsdtSerialPortTable (
/** Validate the Serial Port Information.
- @param [in] SerialPortInfoTable Table of CM_ARM_SERIAL_PORT_INFO.
+ @param [in] SerialPortInfoTable Table of CM_ARCH_COMMON_SERIAL_PORT_INFO.
@param [in] SerialPortCount Count of SerialPort in the table.
@retval EFI_SUCCESS Success.
@@ -61,8 +61,8 @@ FreeSsdtSerialPortTable (
EFI_STATUS
EFIAPI
ValidateSerialPortInfo (
- IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfoTable,
- IN UINT32 SerialPortCount
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfoTable,
+ IN UINT32 SerialPortCount
);
#endif // SSDT_SERIAL_PORT_LIB_H_
diff --git a/DynamicTablesPkg/Include/X64NameSpaceObjects.h b/DynamicTablesPkg/Include/X64NameSpaceObjects.h
new file mode 100644
index 0000000..f153461
--- /dev/null
+++ b/DynamicTablesPkg/Include/X64NameSpaceObjects.h
@@ -0,0 +1,191 @@
+/** @file
+
+ Defines the X64 Namespace Object.
+
+ Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+ - X64 or x64 - X64 Architecture
+**/
+
+#ifndef X64_NAMESPACE_OBJECTS_H_
+#define X64_NAMESPACE_OBJECTS_H_
+
+#include <IndustryStandard/Acpi.h>
+
+/** The EX64_OBJECT_ID enum describes the Object IDs
+ in the X64 Namespace
+*/
+typedef enum X64ObjectID {
+ EX64ObjReserved, ///< 0 - Reserved
+ EX64ObjFadtSciInterrupt, ///< 1 - FADT SCI Interrupt information
+ EX64ObjFadtSciCmdInfo, ///< 2 - FADT SCI CMD information
+ EX64ObjFadtPmBlockInfo, ///< 3 - FADT Power management block info
+ EX64ObjFadtGpeBlockInfo, ///< 4 - FADT GPE block info
+ EX64ObjFadtXpmBlockInfo, ///< 5 - FADT 64-bit Power Management block info
+ EX64ObjFadtXgpeBlockInfo, ///< 6 - FADT 64-bit GPE block info
+ EX64ObjFadtSleepBlockInfo, ///< 7 - FADT Sleep block info
+ EX64ObjFadtResetBlockInfo, ///< 8 - FADT Reset block info
+ EX64ObjFadtMiscInfo, ///< 9 - FADT Legacy fields info
+ EX64ObjWsmtFlagsInfo, ///< 10 - WSMT protection flags info
+ EX64ObjHpetInfo, ///< 11 - HPET device info
+ EX64ObjMax ///< 12 - Maximum Object ID
+} EX64_OBJECT_ID;
+
+/** A structure that describes the
+ SCI interrupt Information for the Platform.
+
+ ID: EX64ObjFadtSciInterrupt
+*/
+typedef struct CmX64FadtSciInterrupt {
+ /** This is the SCI interrupt field of the FADT Table
+ described in the ACPI Specification
+ */
+ UINT16 SciInterrupt;
+} CM_X64_FADT_SCI_INTERRUPT;
+
+/** A structure that describes the
+ SCI CMD Information for the Platform.
+
+ ID: EX64ObjFadtSciCmdInfo
+*/
+typedef struct CmX64FadtSciCmdInfo {
+ /** This is the System control interrupt command information of the FADT Table
+ described in the ACPI Specification
+ */
+ UINT32 SciCmd;
+ UINT8 AcpiEnable;
+ UINT8 AcpiDisable;
+ UINT8 S4BiosReq;
+ UINT8 PstateCnt;
+ UINT8 CstCnt;
+} CM_X64_FADT_SCI_CMD_INFO;
+
+/** A structure that describes the
+ power management block information.
+
+ ID: EX64ObjFadtPmBlockInfo
+*/
+typedef struct CmX64FadtPmBlockInfo {
+ /** This is the PM event block information of the FADT Table
+ described in the ACPI Specification
+ */
+ UINT32 Pm1aEvtBlk;
+ UINT32 Pm1bEvtBlk;
+ UINT32 Pm1aCntBlk;
+ UINT32 Pm1bCntBlk;
+ UINT32 Pm2CntBlk;
+ UINT32 PmTmrBlk;
+ UINT8 Pm1EvtLen;
+ UINT8 Pm1CntLen;
+ UINT8 Pm2CntLen;
+ UINT8 PmTmrLen;
+} CM_X64_FADT_PM_BLOCK_INFO;
+
+/** A structure that describes the
+ GPE block information.
+
+ ID: EX64ObjFadtGpeBlockInfo
+*/
+typedef struct CmX64FadtGpeBlockInfo {
+ /** This is the GPE Block information of the FADT Table
+ described in the ACPI Specification
+ */
+ UINT32 Gpe0Blk;
+ UINT32 Gpe1Blk;
+ UINT8 Gpe0BlkLen;
+ UINT8 Gpe1BlkLen;
+ UINT8 Gpe1Base;
+} CM_X64_FADT_GPE_BLOCK_INFO;
+
+/** A structure that describes the
+ 64bit power management block information.
+
+ ID: EX64ObjFadtXpmBlockInfo
+*/
+typedef struct CmX64FadtXpmBlockInfo {
+ /** This is the System control interrupt command information of the FADT Table
+ described in the ACPI Specification
+ */
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk;
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk;
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk;
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk;
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk;
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk;
+} CM_X64_FADT_X_PM_BLOCK_INFO;
+
+/** A structure that describes the
+ 64-bit GPE block information.
+
+ ID: EX64ObjFadtXgpeBlockInfo
+*/
+typedef struct CmX64FadtXgpeBlockInfo {
+ /** This is the GPE Block information of the FADT Table
+ described in the ACPI Specification
+ */
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XGpe0Blk;
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE XGpe1Blk;
+} CM_X64_FADT_X_GPE_BLOCK_INFO;
+
+/** A structure that describes the
+ sleep control block information.
+
+ ID: EX64ObjFadtSleepBlockInfo
+*/
+typedef struct CmX64FadtSleepBlockInfo {
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE SleepControlReg;
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE SleepStatusReg;
+} CM_X64_FADT_SLEEP_BLOCK_INFO;
+
+/** A structure that describes the
+ Reset control block information.
+
+ ID: EX64ObjFadtResetBlockInfo
+*/
+typedef struct CmX64FadtResetBlockInfo {
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ResetReg;
+ UINT8 ResetValue;
+} CM_X64_FADT_RESET_BLOCK_INFO;
+
+/** A structure that describes the
+ miscellaneous FADT fields information.
+
+ ID: EX64ObjFadtMiscInfo
+*/
+typedef struct CmX64FadtFadtMiscInfo {
+ UINT16 PLvl2Lat;
+ UINT16 PLvl3Lat;
+ UINT16 FlushSize;
+ UINT16 FlushStride;
+ UINT8 DutyOffset;
+ UINT8 DutyWidth;
+ UINT8 DayAlrm;
+ UINT8 MonAlrm;
+ UINT8 Century;
+} CM_X64_FADT_MISC_INFO;
+
+/**
+ A structure that describes the WSMT protection flags information.
+
+ ID: EX64ObjWsmtFlagsInfo
+*/
+typedef struct CmX64WsmtFlagsInfo {
+ UINT32 ProtectionFlags;
+} CM_X64_WSMT_FLAGS_INFO;
+
+/**
+ A structure that describes the HPET device information.
+
+ ID: EX64ObjHpetInfo
+*/
+typedef struct CmX64HpetInfo {
+ UINT32 BaseAddressLower32Bit;
+ UINT16 MainCounterMinimumClockTickInPeriodicMode;
+ UINT8 PageProtectionAndOemAttribute;
+} CM_X64_HPET_INFO;
+#endif // X64_NAMESPACE_OBJECTS_H_
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c
index 6118df0..3585a53 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c
@@ -65,10 +65,10 @@ ValidateCmn600Info (
IN CONST UINT32 Cmn600Count
)
{
- UINT32 Index;
- UINT32 DtcIndex;
- CONST CM_ARM_CMN_600_INFO *Cmn600Info;
- CONST CM_ARM_GENERIC_INTERRUPT *DtcInterrupt;
+ UINT32 Index;
+ UINT32 DtcIndex;
+ CONST CM_ARM_CMN_600_INFO *Cmn600Info;
+ CONST CM_ARCH_COMMON_GENERIC_INTERRUPT *DtcInterrupt;
if ((Cmn600InfoList == NULL) ||
(Cmn600Count == 0))
@@ -231,10 +231,10 @@ FixupCmn600Info (
OUT EFI_ACPI_DESCRIPTION_HEADER **Table
)
{
- EFI_STATUS Status;
- EFI_STATUS Status1;
- UINT8 Index;
- CONST CM_ARM_GENERIC_INTERRUPT *DtcInt;
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ UINT8 Index;
+ CONST CM_ARCH_COMMON_GENERIC_INTERRUPT *DtcInt;
EFI_ACPI_DESCRIPTION_HEADER *SsdtCmn600Template;
AML_ROOT_NODE_HANDLE RootNodeHandle;
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h
deleted file mode 100644
index 0c7a0b0..0000000
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/** @file
- SSDT Cpu Topology Table Generator.
-
- Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.3 Specification - January 2019 - s8.4 Declaring Processors
- - ACPI for CoreSight version 1.2 Platform Design Document
- (https://developer.arm.com/documentation/den0067/a/?lang=en)
-
- @par Glossary:
- - ETE - Embedded Trace Extension.
- - ETM - Embedded Trace Macrocell.
-**/
-
-#ifndef SSDT_CPU_TOPOLOGY_GENERATOR_H_
-#define SSDT_CPU_TOPOLOGY_GENERATOR_H_
-
-#pragma pack(1)
-
-// Mask for the flags that need to be checked.
-#define PPTT_PROCESSOR_MASK ( \
- (EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL) | \
- (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \
- (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3))
-
-// Mask for the cpu flags.
-#define PPTT_CPU_PROCESSOR_MASK ( \
- (EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL) | \
- (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \
- (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3))
-
-// Mask for the cluster flags.
-// Even though a _UID is generated for clusters, it is simpler to use
-// EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID and to not match the cluster id of
-// the PPTT table (not sure the PPTT table is generated).
-#define PPTT_CLUSTER_PROCESSOR_MASK ( \
- (EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL) | \
- (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID << 1) | \
- (EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF << 3))
-
-// Leaf nodes specific mask.
-#define PPTT_LEAF_MASK ((EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \
- (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3))
-
-/** LPI states are stored in the ASL namespace at '\_SB_.Lxxx',
- with xxx being the node index of the LPI state.
-*/
-#define SB_SCOPE "\\_SB_"
-#define SB_SCOPE_PREFIX SB_SCOPE "."
-/// Size of the SB_SCOPE_PREFIX string.
-#define SB_SCOPE_PREFIX_SIZE sizeof (SB_SCOPE_PREFIX)
-
-/// HID for a processor device.
-#define ACPI_HID_PROCESSOR_DEVICE "ACPI0007"
-
-/// HID for a ETM/ETE device.
-#define ACPI_HID_ET_DEVICE "ARMHC500"
-
-/// HID for a processor container device.
-#define ACPI_HID_PROCESSOR_CONTAINER_DEVICE "ACPI0010"
-
-/** Node names of Cpus and Clusters are 'Cxxx', and 'Lxxx' for LPI states.
- The 'xxx' is an index on 12 bits is given to node name,
- thus the limitation in the number of nodes.
-*/
-#define MAX_NODE_COUNT (1 << 12)
-
-/** A structure used to handle the Lpi structures referencing.
-
- A CM_ARM_PROC_HIERARCHY_INFO structure references a CM_ARM_OBJ_REF.
- This CM_ARM_OBJ_REF references CM_ARM_LPI_INFO structures.
-
- Example:
- (Cpu0) (Cpu1)
- CM_ARM_PROC_HIERARCHY_INFO CM_ARM_PROC_HIERARCHY_INFO
- | |
- +----------------------------------------
- |
- v
- (List of references to Lpi states)
- CM_ARM_OBJ_REF
- |
- +----------------------------------------
- | |
- v v
- (A first Lpi state) (A second Lpi state)
- CM_ARM_LPI_INFO[0] CM_ARM_LPI_INFO[1]
-
- Here, Cpu0 and Cpu1 have the same Lpi states. Both CM_ARM_PROC_HIERARCHY_INFO
- structures reference the same CM_ARM_OBJ_REF. An entry is created in the
- TokenTable such as:
- 0 <-> CM_ARM_OBJ_REF
-
- This will lead to the creation of this pseudo-ASL code where Cpu0 and Cpu1
- return the same object at \_SB.L000:
- Scope (\_SB) {
- Device (C000) {
- [...]
- Method (_LPI) {
- Return (\_SB.L000)
- }
- } // C000
-
- Device (C001) {
- [...]
- Method (_LPI) {
- Return (\_SB.L000)
- }
- } // C001
-
- // Lpi states
- Name (L000, Package (0x05) {
- [...]
- }
- }
-*/
-typedef struct TokenTable {
- /// TokenTable, a table allowing to map:
- /// Index <-> CM_OBJECT_TOKEN (to CM_ARM_LPI_INFO structures).
- CM_OBJECT_TOKEN *Table;
-
- /// Last used index of the TokenTable.
- /// LastIndex is bound by ProcNodeCount.
- UINT32 LastIndex;
-} TOKEN_TABLE;
-
-/** A structure holding the Cpu topology generator and additional private data.
-*/
-typedef struct AcpiCpuTopologyGenerator {
- /// ACPI Table generator header
- ACPI_TABLE_GENERATOR Header;
-
- // Private fields are defined from here.
-
- /// Private object used to handle token referencing.
- TOKEN_TABLE TokenTable;
- /// List of CM_ARM_PROC_HIERARCHY_INFO CM objects.
- CM_ARM_PROC_HIERARCHY_INFO *ProcNodeList;
- /// Count of CM_ARM_PROC_HIERARCHY_INFO CM objects.
- UINT32 ProcNodeCount;
-} ACPI_CPU_TOPOLOGY_GENERATOR;
-
-#pragma pack()
-
-#endif // SSDT_CPU_TOPOLOGY_GENERATOR_H_
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf
index f7b7c1c..ed049ea 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf
@@ -8,7 +8,7 @@
[Defines]
INF_VERSION = 0x00010019
- BASE_NAME = AcpiDbg2LibArm
+ BASE_NAME = AcpiDbg2Lib
FILE_GUID = A17BA4F0-3DEB-4FE5-BD27-EC008E541B22
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
@@ -18,17 +18,28 @@
[Sources]
Dbg2Generator.c
+ Dbg2Generator.h
+
+[Sources.ARM, Sources.AARCH64]
+ Arm/ArmDbg2Generator.c
+
+[Sources.IA32, Sources.X86]
+ Dbg2GeneratorNull.c
+
+[Packages.ARM, Packages.AARCH64]
+ ArmPlatformPkg/ArmPlatformPkg.dec
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
DynamicTablesPkg/DynamicTablesPkg.dec
+[LibraryClasses.ARM, LibraryClasses.AARCH64]
+ PL011UartLib
+
[LibraryClasses]
BaseLib
- PL011UartLib
SsdtSerialPortFixupLib
[FixedPcd]
@@ -36,8 +47,3 @@
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
-
-[Protocols]
-
-[Guids]
-
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Arm/ArmDbg2Generator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Arm/ArmDbg2Generator.c
new file mode 100644
index 0000000..a063f49
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Arm/ArmDbg2Generator.c
@@ -0,0 +1,67 @@
+/** @file
+ Arm DBG2 Table Generator
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
+**/
+
+#include <ConfigurationManagerObject.h>
+#include <Library/PL011UartLib.h>
+#include <Protocol/SerialIo.h>
+#include "Dbg2Generator.h"
+
+/**
+ Initialise the serial port to the specified settings.
+ The serial port is re-configured only if the specified settings
+ are different from the current settings.
+ All unspecified settings will be set to the default values.
+
+ @param SerialPortInfo CM_ARCH_COMMON_SERIAL_PORT_INFO object describing
+ the serial port.
+ @param BaudRate The baud rate of the serial device. If the
+ baud rate is not supported, the speed will be
+ reduced to the nearest supported one and the
+ variable's value will be updated accordingly.
+ @param ReceiveFifoDepth The number of characters the device will
+ buffer on input. Value of 0 will use the
+ device's default FIFO depth.
+ @param Parity If applicable, this is the EFI_PARITY_TYPE
+ that is computed or checked as each character
+ is transmitted or received. If the device
+ does not support parity, the value is the
+ default parity value.
+ @param DataBits The number of data bits in each character.
+ @param StopBits If applicable, the EFI_STOP_BITS_TYPE number
+ of stop bits per character.
+ If the device does not support stop bits, the
+ value is the default stop bit value.
+
+ @retval RETURN_SUCCESS All attributes were set correctly on the
+ serial device.
+ @retval RETURN_INVALID_PARAMETER One or more of the attributes has an
+ unsupported value.
+**/
+RETURN_STATUS
+EFIAPI
+Dbg2InitializePort (
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo,
+ IN OUT UINT64 *BaudRate,
+ IN OUT UINT32 *ReceiveFifoDepth,
+ IN OUT EFI_PARITY_TYPE *Parity,
+ IN OUT UINT8 *DataBits,
+ IN OUT EFI_STOP_BITS_TYPE *StopBits
+ )
+{
+ return PL011UartInitializePort (
+ (UINTN)SerialPortInfo->BaseAddress,
+ SerialPortInfo->Clock,
+ BaudRate,
+ ReceiveFifoDepth,
+ Parity,
+ DataBits,
+ StopBits
+ );
+}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c
index f6dfb3d..f387319 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.c
@@ -14,7 +14,6 @@
#include <Library/AcpiLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
-#include <Library/PL011UartLib.h>
#include <Protocol/AcpiTable.h>
#include <Protocol/SerialIo.h>
@@ -26,14 +25,16 @@
#include <Library/TableHelperLib.h>
#include <Protocol/ConfigurationManagerProtocol.h>
+#include "Dbg2Generator.h"
+
/** ARM standard DBG2 Table Generator
- Constructs the DBG2 table for PL011 or SBSA UART peripherals.
+ Constructs the DBG2 table for corresponding DBG2 peripheral.
Requirements:
The following Configuration Manager Object(s) are required by
this Generator:
- - EArmObjSerialDebugPortInfo
+ - EArchCommonObjSerialDebugPortInfo
*/
#pragma pack(1)
@@ -169,7 +170,7 @@ DBG2_TABLE AcpiDbg2 = {
DBG2_DEBUG_PORT_DDI (
0, // {Template}: Serial Port Subtype
0, // {Template}: Serial Port Base Address
- PL011_UART_LENGTH,
+ 0, // {Template}: Serial Port Base Address Size
NAMESPACE_STR_DBG_PORT0
)
}
@@ -181,12 +182,12 @@ DBG2_TABLE AcpiDbg2 = {
debug port information from the Configuration Manager
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjSerialDebugPortInfo,
- CM_ARM_SERIAL_PORT_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjSerialDebugPortInfo,
+ CM_ARCH_COMMON_SERIAL_PORT_INFO
);
-/** Initialize the PL011/SBSA UART with the parameters obtained from
+/** Initialize the DBG2 UART with the parameters obtained from
the Configuration Manager.
@param [in] SerialPortInfo Pointer to the Serial Port Information.
@@ -198,7 +199,7 @@ GET_OBJECT_LIST (
STATIC
EFI_STATUS
SetupDebugUart (
- IN CONST CM_ARM_SERIAL_PORT_INFO *CONST SerialPortInfo
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *CONST SerialPortInfo
)
{
EFI_STATUS Status;
@@ -218,9 +219,8 @@ SetupDebugUart (
StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
BaudRate = SerialPortInfo->BaudRate;
- Status = PL011UartInitializePort (
- (UINTN)SerialPortInfo->BaseAddress,
- SerialPortInfo->Clock,
+ Status = Dbg2InitializePort (
+ SerialPortInfo,
&BaudRate,
&ReceiveFifoDepth,
&Parity,
@@ -329,10 +329,10 @@ BuildDbg2TableEx (
OUT UINTN *CONST TableCount
)
{
- EFI_STATUS Status;
- CM_ARM_SERIAL_PORT_INFO *SerialPortInfo;
- UINT32 SerialPortCount;
- EFI_ACPI_DESCRIPTION_HEADER **TableList;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo;
+ UINT32 SerialPortCount;
+ EFI_ACPI_DESCRIPTION_HEADER **TableList;
ASSERT (This != NULL);
ASSERT (AcpiTableInfo != NULL);
@@ -358,7 +358,7 @@ BuildDbg2TableEx (
*Table = NULL;
- Status = GetEArmObjSerialDebugPortInfo (
+ Status = GetEArchCommonObjSerialDebugPortInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&SerialPortInfo,
@@ -460,6 +460,9 @@ BuildDbg2TableEx (
(SerialPortInfo->PortSubtype ==
EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART))
{
+ // Setup the PL011 length.
+ AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].AddressSize = PL011_UART_LENGTH;
+
// Initialize the serial port
Status = SetupDebugUart (SerialPortInfo);
if (EFI_ERROR (Status)) {
@@ -470,6 +473,13 @@ BuildDbg2TableEx (
));
goto error_handler;
}
+ } else if ((SerialPortInfo->PortSubtype ==
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_16550_WITH_GAS))
+ {
+ AcpiDbg2.Dbg2DeviceInfo[INDEX_DBG_PORT0].AddressSize = SIZE_4KB;
+ } else {
+ // Try to catch other serial ports, but don't return an error.
+ ASSERT (0);
}
TableList[0] = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiDbg2;
@@ -524,7 +534,7 @@ ACPI_TABLE_GENERATOR Dbg2Generator = {
// Minimum supported ACPI Table Revision
EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,
// Creator ID
- TABLE_GENERATOR_CREATOR_ID_ARM,
+ TABLE_GENERATOR_CREATOR_ID,
// Creator Revision
DBG2_GENERATOR_REVISION,
// Build table function. Use the extended version instead.
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.h
new file mode 100644
index 0000000..5424be4
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2Generator.h
@@ -0,0 +1,56 @@
+/** @file
+ DBG2 Table Generator
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
+**/
+
+#ifndef DBG2_GENERATOR_H_
+#define DBG2_GENERATOR_H_
+
+/**
+ Initialise the serial port to the specified settings.
+ The serial port is re-configured only if the specified settings
+ are different from the current settings.
+ All unspecified settings will be set to the default values.
+
+ @param SerialPortInfo CM_ARCH_COMMON_SERIAL_PORT_INFO object describing
+ the serial port.
+ @param BaudRate The baud rate of the serial device. If the
+ baud rate is not supported, the speed will be
+ reduced to the nearest supported one and the
+ variable's value will be updated accordingly.
+ @param ReceiveFifoDepth The number of characters the device will
+ buffer on input. Value of 0 will use the
+ device's default FIFO depth.
+ @param Parity If applicable, this is the EFI_PARITY_TYPE
+ that is computed or checked as each character
+ is transmitted or received. If the device
+ does not support parity, the value is the
+ default parity value.
+ @param DataBits The number of data bits in each character.
+ @param StopBits If applicable, the EFI_STOP_BITS_TYPE number
+ of stop bits per character.
+ If the device does not support stop bits, the
+ value is the default stop bit value.
+
+ @retval RETURN_SUCCESS All attributes were set correctly on the
+ serial device.
+ @retval RETURN_INVALID_PARAMETER One or more of the attributes has an
+ unsupported value.
+**/
+RETURN_STATUS
+EFIAPI
+Dbg2InitializePort (
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo,
+ IN OUT UINT64 *BaudRate,
+ IN OUT UINT32 *ReceiveFifoDepth,
+ IN OUT EFI_PARITY_TYPE *Parity,
+ IN OUT UINT8 *DataBits,
+ IN OUT EFI_STOP_BITS_TYPE *StopBits
+ );
+
+#endif // DBG2_GENERATOR_H_
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2GeneratorNull.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2GeneratorNull.c
new file mode 100644
index 0000000..3219f6f
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/Dbg2GeneratorNull.c
@@ -0,0 +1,60 @@
+/** @file
+ Common DBG2 Table Generator
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
+**/
+
+#include <ConfigurationManagerObject.h>
+#include <Protocol/SerialIo.h>
+#include "Dbg2Generator.h"
+
+/**
+ Initialise the serial port to the specified settings.
+ The serial port is re-configured only if the specified settings
+ are different from the current settings.
+ All unspecified settings will be set to the default values.
+
+ @param SerialPortInfo CM_ARCH_COMMON_SERIAL_PORT_INFO object describing
+ the serial port.
+ @param BaudRate The baud rate of the serial device. If the
+ baud rate is not supported, the speed will be
+ reduced to the nearest supported one and the
+ variable's value will be updated accordingly.
+ @param ReceiveFifoDepth The number of characters the device will
+ buffer on input. Value of 0 will use the
+ device's default FIFO depth.
+ @param Parity If applicable, this is the EFI_PARITY_TYPE
+ that is computed or checked as each character
+ is transmitted or received. If the device
+ does not support parity, the value is the
+ default parity value.
+ @param DataBits The number of data bits in each character.
+ @param StopBits If applicable, the EFI_STOP_BITS_TYPE number
+ of stop bits per character.
+ If the device does not support stop bits, the
+ value is the default stop bit value.
+
+ @retval RETURN_SUCCESS All attributes were set correctly on the
+ serial device.
+ @retval RETURN_UNSUPPORTED Not supported.
+ @retval RETURN_INVALID_PARAMETER One or more of the attributes has an
+ unsupported value.
+**/
+RETURN_STATUS
+EFIAPI
+Dbg2InitializePort (
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo,
+ IN OUT UINT64 *BaudRate,
+ IN OUT UINT32 *ReceiveFifoDepth,
+ IN OUT EFI_PARITY_TYPE *Parity,
+ IN OUT UINT8 *DataBits,
+ IN OUT EFI_STOP_BITS_TYPE *StopBits
+ )
+{
+ // Not implemented.
+ return RETURN_UNSUPPORTED;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf
index 8fe3401..b4b899c 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf
@@ -8,7 +8,7 @@
[Defines]
INF_VERSION = 0x00010019
- BASE_NAME = AcpiFadtLibArm
+ BASE_NAME = AcpiFadtLib
FILE_GUID = 686FE5FE-B944-485F-8B1C-7D60E0056487
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
@@ -18,6 +18,13 @@
[Sources]
FadtGenerator.c
+ FadtGenerator.h
+
+[Sources.ARM, Sources.AARCH64]
+ Arm/ArmFadtGenerator.c
+
+[Sources.IA32, Sources.X64]
+ X64/X64FadtGenerator.c
[Packages]
MdePkg/MdePkg.dec
@@ -27,10 +34,3 @@
[LibraryClasses]
BaseLib
-
-[Pcd]
-
-[Protocols]
-
-[Guids]
-
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/Arm/ArmFadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/Arm/ArmFadtGenerator.c
new file mode 100644
index 0000000..2d2afe9
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/Arm/ArmFadtGenerator.c
@@ -0,0 +1,126 @@
+/** @file
+ ARM FADT Table Helpers
+
+ Copyright (c) 2017 - 2023, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.5 Specification, Aug 29, 2022
+
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include "FadtGenerator.h"
+
+/** ARM Standard FADT Generator
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArmObjBootArchInfo
+*/
+
+/** This macro expands to a function that retrieves the Boot
+ Architecture Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjBootArchInfo,
+ CM_ARM_BOOT_ARCH_INFO
+ );
+
+/** This macro defines the FADT flag options for ARM Platforms.
+*/
+#define FADT_FLAGS (EFI_ACPI_6_5_HW_REDUCED_ACPI | \
+ EFI_ACPI_6_5_LOW_POWER_S0_IDLE_CAPABLE)
+
+/** Updates the Architecture specific information in the FADT Table.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] Fadt Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ArmFadtBootArchInfoUpdate (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *Fadt
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_BOOT_ARCH_INFO *BootArchInfo;
+
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Fadt != NULL);
+
+ // Get the Boot Architecture flags from the Platform Configuration Manager
+ Status = GetEArmObjBootArchInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &BootArchInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Failed to get Boot Architecture flags. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "FADT BootArchFlag = 0x%x\n",
+ BootArchInfo->BootArchFlags
+ ));
+
+ Fadt->ArmBootArch = BootArchInfo->BootArchFlags;
+
+ return Status;
+}
+
+/** Updates the Architecture specific information in the FADT Table.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] Fadt Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+EFI_STATUS
+EFIAPI
+FadtArchUpdate (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *Fadt
+ )
+{
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Fadt != NULL);
+
+ Fadt->Flags = FADT_FLAGS;
+
+ return ArmFadtBootArchInfoUpdate (CfgMgrProtocol, Fadt);
+}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c
index 57aaaf8..3ba3fc2 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.c
@@ -19,22 +19,17 @@
#include <ConfigurationManagerHelper.h>
#include <Library/TableHelperLib.h>
#include <Protocol/ConfigurationManagerProtocol.h>
+#include "FadtGenerator.h"
-/** ARM standard FADT Generator
+/** Standard FADT Generator
Requirements:
The following Configuration Manager Object(s) are required by
this Generator:
- - EArmObjPowerManagementProfileInfo
- - EArmObjBootArchInfo
- - EArmObjHypervisorVendorIdentity (OPTIONAL)
+ - EArchCommonObjPowerManagementProfileInfo
+ - EArchCommonObjHypervisorVendorIdentity (OPTIONAL)
*/
-/** This macro defines the FADT flag options for ARM Platforms.
-*/
-#define FADT_FLAGS (EFI_ACPI_6_5_HW_REDUCED_ACPI | \
- EFI_ACPI_6_5_LOW_POWER_S0_IDLE_CAPABLE)
-
/** This macro defines the valid mask for the FADT flag option
if HW_REDUCED_ACPI flag in the table is set.
@@ -159,13 +154,13 @@ EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE AcpiFadt = {
// UINT8 Reserved1
0,
// UINT32 Flags
- FADT_FLAGS,
+ 0,
// EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE ResetReg
NULL_GAS,
// UINT8 ResetValue
0,
// UINT16 ArmBootArch
- EFI_ACPI_6_5_ARM_PSCI_COMPLIANT, // {Template}: ARM Boot Architecture Flags
+ 0, // {Template}: ARM Boot Architecture Flags
// UINT8 MinorRevision
EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION, // {Template}
// UINT64 XFirmwareCtrl
@@ -202,36 +197,27 @@ EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE AcpiFadt = {
Management Profile Information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPowerManagementProfileInfo,
- CM_ARM_POWER_MANAGEMENT_PROFILE_INFO
- );
-
-/** This macro expands to a function that retrieves the Boot
- Architecture Information from the Configuration Manager.
-*/
-GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjBootArchInfo,
- CM_ARM_BOOT_ARCH_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPowerManagementProfileInfo,
+ CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO
);
/** This macro expands to a function that retrieves the Hypervisor
Vendor ID from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjHypervisorVendorIdentity,
- CM_ARM_HYPERVISOR_VENDOR_ID
+ EObjNameSpaceArchCommon,
+ EArchCommonObjHypervisorVendorIdentity,
+ CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID
);
/** This macro expands to a function that retrieves the Fixed
feature flags for the platform from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjFixedFeatureFlags,
- CM_ARM_FIXED_FEATURE_FLAGS
+ EObjNameSpaceArchCommon,
+ EArchCommonObjFixedFeatureFlags,
+ CM_ARCH_COMMON_FIXED_FEATURE_FLAGS
);
/** Update the Power Management Profile information in the FADT Table.
@@ -253,13 +239,13 @@ FadtAddPmProfileInfo (
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol
)
{
- EFI_STATUS Status;
- CM_ARM_POWER_MANAGEMENT_PROFILE_INFO *PmProfile;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_POWER_MANAGEMENT_PROFILE_INFO *PmProfile;
ASSERT (CfgMgrProtocol != NULL);
// Get the Power Management Profile from the Platform Configuration Manager
- Status = GetEArmObjPowerManagementProfileInfo (
+ Status = GetEArchCommonObjPowerManagementProfileInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&PmProfile,
@@ -287,58 +273,6 @@ error_handler:
return Status;
}
-/** Updates the Boot Architecture information in the FADT Table.
-
- @param [in] CfgMgrProtocol Pointer to the Configuration Manager
- Protocol Interface.
-
- @retval EFI_SUCCESS Success.
- @retval EFI_INVALID_PARAMETER A parameter is invalid.
- @retval EFI_NOT_FOUND The required object was not found.
- @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
- Manager is less than the Object size for the
- requested object.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-FadtAddBootArchInfo (
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol
- )
-{
- EFI_STATUS Status;
- CM_ARM_BOOT_ARCH_INFO *BootArchInfo;
-
- ASSERT (CfgMgrProtocol != NULL);
-
- // Get the Boot Architecture flags from the Platform Configuration Manager
- Status = GetEArmObjBootArchInfo (
- CfgMgrProtocol,
- CM_NULL_TOKEN,
- &BootArchInfo,
- NULL
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: FADT: Failed to get Boot Architecture flags. Status = %r\n",
- Status
- ));
- goto error_handler;
- }
-
- DEBUG ((
- DEBUG_INFO,
- "FADT BootArchFlag = 0x%x\n",
- BootArchInfo->BootArchFlags
- ));
-
- AcpiFadt.ArmBootArch = BootArchInfo->BootArchFlags;
-
-error_handler:
- return Status;
-}
-
/** Update the Hypervisor Vendor ID in the FADT Table.
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
@@ -358,13 +292,13 @@ FadtAddHypervisorVendorId (
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol
)
{
- EFI_STATUS Status;
- CM_ARM_HYPERVISOR_VENDOR_ID *HypervisorVendorInfo;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_HYPERVISOR_VENDOR_ID *HypervisorVendorInfo;
ASSERT (CfgMgrProtocol != NULL);
// Get the Hypervisor Vendor ID from the Platform Configuration Manager
- Status = GetEArmObjHypervisorVendorIdentity (
+ Status = GetEArchCommonObjHypervisorVendorIdentity (
CfgMgrProtocol,
CM_NULL_TOKEN,
&HypervisorVendorInfo,
@@ -391,7 +325,7 @@ FadtAddHypervisorVendorId (
DEBUG ((
DEBUG_INFO,
- "FADT: EArmObjHypervisorVendorIdentity = 0x%lx\n",
+ "FADT: EArchCommonObjHypervisorVendorIdentity = 0x%lx\n",
HypervisorVendorInfo->HypervisorVendorId
));
@@ -420,13 +354,13 @@ FadtAddFixedFeatureFlags (
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol
)
{
- EFI_STATUS Status;
- CM_ARM_FIXED_FEATURE_FLAGS *FixedFeatureFlags;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_FIXED_FEATURE_FLAGS *FixedFeatureFlags;
ASSERT (CfgMgrProtocol != NULL);
// Get the Fixed feature flags from the Platform Configuration Manager
- Status = GetEArmObjFixedFeatureFlags (
+ Status = GetEArchCommonObjFixedFeatureFlags (
CfgMgrProtocol,
CM_NULL_TOKEN,
&FixedFeatureFlags,
@@ -453,7 +387,7 @@ FadtAddFixedFeatureFlags (
DEBUG ((
DEBUG_INFO,
- "FADT: EArmObjFixedFeatureFlags = 0x%x\n",
+ "FADT: EArchCommonObjFixedFeatureFlags = 0x%x\n",
FixedFeatureFlags->Flags
));
@@ -577,12 +511,6 @@ BuildFadtTable (
goto error_handler;
}
- // Update BootArch Info
- Status = FadtAddBootArchInfo (CfgMgrProtocol);
- if (EFI_ERROR (Status)) {
- goto error_handler;
- }
-
// Add the Hypervisor Vendor Id if present
// Note if no hypervisor is present the zero bytes
// will be placed in this field.
@@ -623,6 +551,12 @@ BuildFadtTable (
}
}
+ // Update Arch specific Info
+ Status = FadtArchUpdate (CfgMgrProtocol, &AcpiFadt);
+ if (EFI_ERROR (Status)) {
+ goto error_handler;
+ }
+
*Table = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiFadt;
error_handler:
return Status;
@@ -648,7 +582,7 @@ ACPI_TABLE_GENERATOR FadtGenerator = {
// Minimum supported ACPI Table Revision
EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
// Creator ID
- TABLE_GENERATOR_CREATOR_ID_ARM,
+ TABLE_GENERATOR_CREATOR_ID,
// Creator Revision
FADT_GENERATOR_REVISION,
// Build Table function
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.h
new file mode 100644
index 0000000..08ac59e
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/FadtGenerator.h
@@ -0,0 +1,35 @@
+/** @file
+ FADT Table Generator
+
+ Copyright (c) 2017 - 2023, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.5 Specification, Aug 29, 2022
+
+**/
+
+#ifndef FADT_GENERATOR_H_
+#define FADT_GENERATOR_H_
+
+/** Updates the Architecture specific information in the FADT Table.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] Fadt Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+EFI_STATUS
+EFIAPI
+FadtArchUpdate (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *Fadt
+ );
+
+#endif // FADT_GENERATOR_H_
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/X64/X64FadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/X64/X64FadtGenerator.c
new file mode 100644
index 0000000..1138941
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/X64/X64FadtGenerator.c
@@ -0,0 +1,382 @@
+/** @file
+ X64 FADT Table Helpers
+
+ Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.5 Specification, Aug 29, 2022
+
+**/
+
+#include <X64NameSpaceObjects.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/AcpiLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include "FadtGenerator.h"
+
+/** This macro expands to a function that retrieves the
+ SCI interrupt information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjFadtSciInterrupt,
+ CM_X64_FADT_SCI_INTERRUPT
+ );
+
+/** This macro expands to a function that retrieves the
+ SCI command information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjFadtSciCmdInfo,
+ CM_X64_FADT_SCI_CMD_INFO
+ );
+
+/** This macro expands to a function that retrieves the
+ legacy power management information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjFadtPmBlockInfo,
+ CM_X64_FADT_PM_BLOCK_INFO
+ );
+
+/** This macro expands to a function that retrieves the
+ legacy GPE block information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjFadtGpeBlockInfo,
+ CM_X64_FADT_GPE_BLOCK_INFO
+ );
+
+/** This macro expands to a function that retrieves the
+ legacy level2 latency, level 3 latency, RTC information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjFadtMiscInfo,
+ CM_X64_FADT_MISC_INFO
+ );
+
+/** This macro expands to a function that retrieves the
+ 64-bit power management information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjFadtXpmBlockInfo,
+ CM_X64_FADT_X_PM_BLOCK_INFO
+ );
+
+/** This macro expands to a function that retrieves the
+ 64-bit GPE block information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjFadtXgpeBlockInfo,
+ CM_X64_FADT_X_GPE_BLOCK_INFO
+ );
+
+/** This macro expands to a function that retrieves the
+ sleep block information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjFadtSleepBlockInfo,
+ CM_X64_FADT_SLEEP_BLOCK_INFO
+ );
+
+/** This macro expands to a function that retrieves the
+ reset block information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjFadtResetBlockInfo,
+ CM_X64_FADT_RESET_BLOCK_INFO
+ );
+
+/** Updates the Architecture specific information in the FADT Table.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] Fadt Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+EFI_STATUS
+EFIAPI
+FadtArchUpdate (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE *Fadt
+ )
+{
+ EFI_STATUS Status;
+ CM_X64_FADT_SCI_INTERRUPT *SciInterrupt;
+ CM_X64_FADT_SCI_CMD_INFO *SciCmdinfo;
+ CM_X64_FADT_PM_BLOCK_INFO *PmBlockInfo;
+ CM_X64_FADT_GPE_BLOCK_INFO *GpeBlockInfo;
+ CM_X64_FADT_X_PM_BLOCK_INFO *XpmBlockInfo;
+ CM_X64_FADT_X_GPE_BLOCK_INFO *XgpeBlockInfo;
+ CM_X64_FADT_SLEEP_BLOCK_INFO *SleepBlockInfo;
+ CM_X64_FADT_RESET_BLOCK_INFO *ResetBlockInfo;
+ CM_X64_FADT_MISC_INFO *FadtMiscInfo;
+
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Fadt != NULL);
+
+ // Get the SCI interrupt from the Platform Configuration Manager
+ Status = GetEX64ObjFadtSciInterrupt (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &SciInterrupt,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Failed to get SCI Interrupt information." \
+ " Status = %r\n",
+ Status
+ ));
+ } else {
+ Fadt->SciInt = SciInterrupt->SciInterrupt;
+ }
+
+ // Get the SCI CMD information from the Platform Configuration Manager
+ Status = GetEX64ObjFadtSciCmdInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &SciCmdinfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Failed to get SCI CMD information." \
+ " Status = %r\n",
+ Status
+ ));
+ } else {
+ Fadt->SmiCmd = SciCmdinfo->SciCmd;
+ Fadt->AcpiEnable = SciCmdinfo->AcpiEnable;
+ Fadt->AcpiDisable = SciCmdinfo->AcpiDisable;
+ Fadt->S4BiosReq = SciCmdinfo->S4BiosReq;
+ Fadt->PstateCnt = SciCmdinfo->PstateCnt;
+ Fadt->CstCnt = SciCmdinfo->CstCnt;
+ }
+
+ // Get the SCI PM Block information from the Platform Configuration Manager
+ Status = GetEX64ObjFadtPmBlockInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &PmBlockInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Failed to get PM Block information." \
+ " Status = %r\n",
+ Status
+ ));
+ } else {
+ Fadt->Pm1aEvtBlk = PmBlockInfo->Pm1aEvtBlk;
+ Fadt->Pm1bEvtBlk = PmBlockInfo->Pm1bEvtBlk;
+ Fadt->Pm1aCntBlk = PmBlockInfo->Pm1aCntBlk;
+ Fadt->Pm1bCntBlk = PmBlockInfo->Pm1bCntBlk;
+ Fadt->Pm2CntBlk = PmBlockInfo->Pm2CntBlk;
+ Fadt->PmTmrBlk = PmBlockInfo->PmTmrBlk;
+ Fadt->Pm1EvtLen = PmBlockInfo->Pm1EvtLen;
+ Fadt->Pm1CntLen = PmBlockInfo->Pm1CntLen;
+ Fadt->Pm2CntLen = PmBlockInfo->Pm2CntLen;
+ Fadt->PmTmrLen = PmBlockInfo->PmTmrLen;
+ }
+
+ // Get the SCI PM Block information from the Platform Configuration Manager
+ Status = GetEX64ObjFadtGpeBlockInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &GpeBlockInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Failed to get PM Block information." \
+ " Status = %r\n",
+ Status
+ ));
+ } else {
+ Fadt->Gpe0Blk = GpeBlockInfo->Gpe0Blk;
+ Fadt->Gpe1Blk = GpeBlockInfo->Gpe1Blk;
+ Fadt->Gpe0BlkLen = GpeBlockInfo->Gpe0BlkLen;
+ Fadt->Gpe1BlkLen = GpeBlockInfo->Gpe1BlkLen;
+ Fadt->Gpe1Base = GpeBlockInfo->Gpe1Base;
+ }
+
+ // Get the 64-bit PM Block information from the Platform Configuration Manager
+ Status = GetEX64ObjFadtXpmBlockInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &XpmBlockInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Failed to get 64-bit PM Block information." \
+ " Status = %r\n",
+ Status
+ ));
+ } else {
+ CopyMem (
+ &Fadt->XPm1aCntBlk,
+ &XpmBlockInfo->XPm1aCntBlk,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+ CopyMem (
+ &Fadt->XPm1bEvtBlk,
+ &XpmBlockInfo->XPm1bEvtBlk,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+ CopyMem (
+ &Fadt->XPm1aCntBlk,
+ &XpmBlockInfo->XPm1aCntBlk,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+ CopyMem (
+ &Fadt->XPm1bCntBlk,
+ &XpmBlockInfo->XPm1bCntBlk,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+ CopyMem (
+ &Fadt->XPm2CntBlk,
+ &XpmBlockInfo->XPm2CntBlk,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+ CopyMem (
+ &Fadt->XPmTmrBlk,
+ &XpmBlockInfo->XPmTmrBlk,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+ }
+
+ // Get the various platform information from the Platform Configuration manager
+ Status = GetEX64ObjFadtMiscInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &FadtMiscInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Failed to get various platform information." \
+ " Status = %r\n",
+ Status
+ ));
+ } else {
+ Fadt->PLvl2Lat = FadtMiscInfo->PLvl2Lat;
+ Fadt->PLvl3Lat = FadtMiscInfo->PLvl3Lat;
+ Fadt->FlushSize = FadtMiscInfo->FlushSize;
+ Fadt->FlushStride = FadtMiscInfo->FlushStride;
+ Fadt->DutyOffset = FadtMiscInfo->DutyOffset;
+ Fadt->DutyWidth = FadtMiscInfo->DutyWidth;
+ Fadt->DayAlrm = FadtMiscInfo->DayAlrm;
+ Fadt->MonAlrm = FadtMiscInfo->MonAlrm;
+ Fadt->Century = FadtMiscInfo->Century;
+ }
+
+ // Get the 64-bit GPE Block information from the Platform Configuration Manager
+ Status = GetEX64ObjFadtXgpeBlockInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &XgpeBlockInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Failed to get 64-bit GPE Block information." \
+ " Status = %r\n",
+ Status
+ ));
+ } else {
+ CopyMem (
+ &Fadt->XGpe0Blk,
+ &XgpeBlockInfo->XGpe0Blk,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+ CopyMem (
+ &Fadt->XGpe1Blk,
+ &XgpeBlockInfo->XGpe1Blk,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+ }
+
+ // Get the sleep Block information from the Platform Configuration Manager
+ Status = GetEX64ObjFadtSleepBlockInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &SleepBlockInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Failed to get Sleep Block information." \
+ " Status = %r\n",
+ Status
+ ));
+ } else {
+ CopyMem (
+ &Fadt->SleepControlReg,
+ &SleepBlockInfo->SleepControlReg,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+ CopyMem (
+ &Fadt->SleepStatusReg,
+ &SleepBlockInfo->SleepStatusReg,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+ }
+
+ // Get the sleep Block information from the Platform Configuration Manager
+ Status = GetEX64ObjFadtResetBlockInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &ResetBlockInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Failed to get Reset Block information." \
+ " Status = %r\n",
+ Status
+ ));
+ } else {
+ CopyMem (
+ &Fadt->ResetReg,
+ &ResetBlockInfo->ResetReg,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+ Fadt->ResetValue = ResetBlockInfo->ResetValue;
+ }
+
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf
index 1c7f085..36c343d 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/AcpiMcfgLib.inf
@@ -8,7 +8,7 @@
[Defines]
INF_VERSION = 0x00010019
- BASE_NAME = AcpiMcfgLibArm
+ BASE_NAME = AcpiMcfgLib
FILE_GUID = 8C9BDCB2-72D4-4F30-A12D-1145C3807FF7
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
@@ -27,10 +27,3 @@
[LibraryClasses]
BaseLib
-
-[Pcd]
-
-[Protocols]
-
-[Guids]
-
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c
index 004b794..79a2f59 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiMcfgLib/McfgGenerator.c
@@ -27,7 +27,7 @@
Requirements:
The following Configuration Manager Object(s) are required by
this Generator:
- - EArmObjPciConfigSpaceInfo
+ - EArchCommonObjPciConfigSpaceInfo
*/
#pragma pack(1)
@@ -51,9 +51,9 @@ typedef
/** Retrieve the PCI Configuration Space Information.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPciConfigSpaceInfo,
- CM_ARM_PCI_CONFIG_SPACE_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPciConfigSpaceInfo,
+ CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO
);
/** Add the PCI Enhanced Configuration Space Information to the MCFG Table.
@@ -68,10 +68,10 @@ GET_OBJECT_LIST (
STATIC
VOID
AddPciConfigurationSpaceList (
- IN MCFG_TABLE *CONST Mcfg,
- IN CONST UINT32 PciCfgSpaceOffset,
- IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciCfgSpaceInfoList,
- IN UINT32 PciCfgSpaceCount
+ IN MCFG_TABLE *CONST Mcfg,
+ IN CONST UINT32 PciCfgSpaceOffset,
+ IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciCfgSpaceInfoList,
+ IN UINT32 PciCfgSpaceCount
)
{
MCFG_CFG_SPACE_ADDR *PciCfgSpace;
@@ -126,11 +126,11 @@ BuildMcfgTable (
OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
)
{
- EFI_STATUS Status;
- UINT32 TableSize;
- UINT32 ConfigurationSpaceCount;
- CM_ARM_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfoList;
- MCFG_TABLE *Mcfg;
+ EFI_STATUS Status;
+ UINT32 TableSize;
+ UINT32 ConfigurationSpaceCount;
+ CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfoList;
+ MCFG_TABLE *Mcfg;
ASSERT (This != NULL);
ASSERT (AcpiTableInfo != NULL);
@@ -154,7 +154,7 @@ BuildMcfgTable (
}
*Table = NULL;
- Status = GetEArmObjPciConfigSpaceInfo (
+ Status = GetEArchCommonObjPciConfigSpaceInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&PciConfigSpaceInfoList,
@@ -261,6 +261,7 @@ error_handler:
**/
STATIC
EFI_STATUS
+EFIAPI
FreeMcfgTableResources (
IN CONST ACPI_TABLE_GENERATOR *CONST This,
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
@@ -305,7 +306,7 @@ ACPI_TABLE_GENERATOR McfgGenerator = {
// Minimum supported ACPI Table Revision
EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,
// Creator ID
- TABLE_GENERATOR_CREATOR_ID_ARM,
+ TABLE_GENERATOR_CREATOR_ID,
// Creator Revision
MCFG_GENERATOR_REVISION,
// Build Table function
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf
index da54585..666bdca 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/AcpiPcctLib.inf
@@ -8,7 +8,7 @@
[Defines]
INF_VERSION = 0x0001001B
- BASE_NAME = AcpiPcctLibArm
+ BASE_NAME = AcpiPcctLib
FILE_GUID = 38FE945C-D6ED-4CD6-8D20-FCEF3260D15A
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c
index 36caf4a..e362254 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.c
@@ -29,66 +29,66 @@
Requirements:
The following Configuration Manager Object(s) are required by
this Generator:
- - EArmObjPccSubspaceType0Info
- - EArmObjPccSubspaceType1Info
- - EArmObjPccSubspaceType2Info
- - EArmObjPccSubspaceType3Info
- - EArmObjPccSubspaceType4Info
- - EArmObjPccSubspaceType5Info
+ - EArchCommonObjPccSubspaceType0Info
+ - EArchCommonObjPccSubspaceType1Info
+ - EArchCommonObjPccSubspaceType2Info
+ - EArchCommonObjPccSubspaceType3Info
+ - EArchCommonObjPccSubspaceType4Info
+ - EArchCommonObjPccSubspaceType5Info
*/
/** This macro expands to a function that retrieves the PCC
Subspace of Type 0 Information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPccSubspaceType0Info,
- CM_ARM_PCC_SUBSPACE_TYPE0_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPccSubspaceType0Info,
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO
);
/** This macro expands to a function that retrieves the PCC
Subspace of Type 1 Information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPccSubspaceType1Info,
- CM_ARM_PCC_SUBSPACE_TYPE1_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPccSubspaceType1Info,
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO
);
/** This macro expands to a function that retrieves the PCC
Subspace of Type 2 Information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPccSubspaceType2Info,
- CM_ARM_PCC_SUBSPACE_TYPE2_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPccSubspaceType2Info,
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO
);
/** This macro expands to a function that retrieves the PCC
Subspace of Type 3 Information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPccSubspaceType3Info,
- CM_ARM_PCC_SUBSPACE_TYPE3_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPccSubspaceType3Info,
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO
);
/** This macro expands to a function that retrieves the PCC
Subspace of Type 4 Information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPccSubspaceType4Info,
- CM_ARM_PCC_SUBSPACE_TYPE4_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPccSubspaceType4Info,
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO
);
/** This macro expands to a function that retrieves the PCC
Subspace of Type 5 Information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPccSubspaceType5Info,
- CM_ARM_PCC_SUBSPACE_TYPE5_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPccSubspaceType5Info,
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO
);
/** The Platform is capable of generating an interrupt
@@ -164,11 +164,12 @@ MappingTableFree (
}
}
-/** Add a new entry for CmArmPccSubspace at Index.
+/** Add a new entry for PccSubspace at Index.
@param [in] MappingTable The mapping table structure.
- @param [in] CmArmPccSubspace Pointer to a CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO.
- @param [in] Index Index at which CmArmPccSubspace must be added.
+ @param [in] PccSubspace A pointer to
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO.
+ @param [in] Index Index at which PccSubspace must be added.
This is the Subspace Id.
@retval EFI_SUCCESS Success.
@@ -180,13 +181,13 @@ EFI_STATUS
EFIAPI
MappingTableAdd (
IN MAPPING_TABLE *MappingTable,
- IN VOID *CmArmPccSubspace,
+ IN VOID *PccSubspace,
IN UINT32 Index
)
{
if ((MappingTable == NULL) ||
(MappingTable->Table == NULL) ||
- (CmArmPccSubspace == NULL))
+ (PccSubspace == NULL))
{
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
return EFI_INVALID_PARAMETER;
@@ -200,14 +201,15 @@ MappingTableAdd (
}
// Just map the Pcc Subspace in the Table.
- MappingTable->Table[Index] = CmArmPccSubspace;
+ MappingTable->Table[Index] = PccSubspace;
return EFI_SUCCESS;
}
/** Parse the CmPccArray objects and add them to the MappingTable.
@param [in] MappingTable The mapping table structure.
- @param [in] CmPccArray Pointer to an array of CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO.
+ @param [in] CmPccArray Pointer to an array of
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO.
@param [in] CmPccCount Count of objects in CmPccArray.
@retval EFI_SUCCESS Success.
@@ -242,27 +244,27 @@ MapPccSubspaceId (
switch (GenericPcc->Type) {
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC:
- CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE0_INFO);
+ CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO);
break;
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
- CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE1_INFO);
+ CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO);
break;
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
- CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE2_INFO);
+ CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO);
break;
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
- CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE3_INFO);
+ CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO);
break;
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
- CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE4_INFO);
+ CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO);
break;
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS:
- CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE5_INFO);
+ CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO);
break;
default:
@@ -304,8 +306,8 @@ STATIC
EFI_STATUS
EFIAPI
AddSubspaceStructType0 (
- IN CM_ARM_PCC_SUBSPACE_TYPE0_INFO *PccCmObj,
- IN EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *PccAcpi
+ IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *PccCmObj,
+ IN EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *PccAcpi
)
{
PCC_MAILBOX_REGISTER_INFO *Doorbell;
@@ -356,15 +358,15 @@ STATIC
EFI_STATUS
EFIAPI
AddSubspaceStructType1 (
- IN CM_ARM_PCC_SUBSPACE_TYPE1_INFO *PccCmObj,
+ IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *PccCmObj,
IN EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *PccAcpi
)
{
- CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
- PCC_MAILBOX_REGISTER_INFO *Doorbell;
- PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
+ PCC_MAILBOX_REGISTER_INFO *Doorbell;
+ PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
- GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
+ GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
if ((PccCmObj == NULL) ||
(GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS) ||
@@ -377,10 +379,12 @@ AddSubspaceStructType1 (
Doorbell = &GenericPccCmObj->DoorbellReg;
ChannelTiming = &GenericPccCmObj->ChannelTiming;
+ ASSERT ((PccCmObj->PlatIrq.Flags & ~MAX_UINT8) == 0);
+
PccAcpi->Type = GenericPccCmObj->Type;
PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS);
PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt;
- PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags;
+ PccAcpi->PlatformInterruptFlags = (UINT8)PccCmObj->PlatIrq.Flags;
PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE;
PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
PccAcpi->AddressLength = GenericPccCmObj->AddressLength;
@@ -416,16 +420,16 @@ STATIC
EFI_STATUS
EFIAPI
AddSubspaceStructType2 (
- IN CM_ARM_PCC_SUBSPACE_TYPE2_INFO *PccCmObj,
+ IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *PccCmObj,
IN EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *PccAcpi
)
{
- CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
- PCC_MAILBOX_REGISTER_INFO *Doorbell;
- PCC_MAILBOX_REGISTER_INFO *PlatIrqAck;
- PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
+ PCC_MAILBOX_REGISTER_INFO *Doorbell;
+ PCC_MAILBOX_REGISTER_INFO *PlatIrqAck;
+ PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
- GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
+ GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
if ((PccCmObj == NULL) ||
(GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS) ||
@@ -439,10 +443,12 @@ AddSubspaceStructType2 (
PlatIrqAck = &PccCmObj->PlatIrqAckReg;
ChannelTiming = &GenericPccCmObj->ChannelTiming;
+ ASSERT ((PccCmObj->PlatIrq.Flags & ~MAX_UINT8) == 0);
+
PccAcpi->Type = GenericPccCmObj->Type;
PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS);
PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt;
- PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags;
+ PccAcpi->PlatformInterruptFlags = (UINT8)PccCmObj->PlatIrq.Flags;
PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE;
PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
@@ -487,19 +493,19 @@ STATIC
EFI_STATUS
EFIAPI
AddSubspaceStructType34 (
- IN CM_ARM_PCC_SUBSPACE_TYPE3_INFO *PccCmObj,
+ IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *PccCmObj,
IN EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *PccAcpi
)
{
- CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
- PCC_MAILBOX_REGISTER_INFO *Doorbell;
- PCC_MAILBOX_REGISTER_INFO *PlatIrqAck;
- PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck;
- PCC_MAILBOX_REGISTER_INFO *CmdCompleteUpdate;
- PCC_MAILBOX_REGISTER_INFO *ErrorStatus;
- PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
+ PCC_MAILBOX_REGISTER_INFO *Doorbell;
+ PCC_MAILBOX_REGISTER_INFO *PlatIrqAck;
+ PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck;
+ PCC_MAILBOX_REGISTER_INFO *CmdCompleteUpdate;
+ PCC_MAILBOX_REGISTER_INFO *ErrorStatus;
+ PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
- GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
+ GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
if ((PccCmObj == NULL) ||
((GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC) &&
@@ -517,13 +523,16 @@ AddSubspaceStructType34 (
ErrorStatus = &PccCmObj->ErrorStatusReg;
ChannelTiming = &GenericPccCmObj->ChannelTiming;
+ ASSERT ((PccCmObj->PlatIrq.Flags & ~MAX_UINT8) == 0);
+ ASSERT ((GenericPccCmObj->AddressLength & ~MAX_UINT32) == 0);
+
PccAcpi->Type = GenericPccCmObj->Type;
PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC);
PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt;
- PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags;
+ PccAcpi->PlatformInterruptFlags = (UINT8)PccCmObj->PlatIrq.Flags;
PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE;
PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
- PccAcpi->AddressLength = GenericPccCmObj->AddressLength;
+ PccAcpi->AddressLength = (UINT32)GenericPccCmObj->AddressLength;
CopyMem (
&PccAcpi->DoorbellRegister,
@@ -599,17 +608,17 @@ STATIC
EFI_STATUS
EFIAPI
AddSubspaceStructType5 (
- IN CM_ARM_PCC_SUBSPACE_TYPE5_INFO *PccCmObj,
+ IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *PccCmObj,
IN EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *PccAcpi
)
{
- CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
- PCC_MAILBOX_REGISTER_INFO *Doorbell;
- PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck;
- PCC_MAILBOX_REGISTER_INFO *ErrorStatus;
- PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
+ PCC_MAILBOX_REGISTER_INFO *Doorbell;
+ PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck;
+ PCC_MAILBOX_REGISTER_INFO *ErrorStatus;
+ PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
- GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
+ GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
if ((PccCmObj == NULL) ||
(GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS) ||
@@ -705,7 +714,7 @@ PopulatePcctTable (
switch (((PCC_SUBSPACE_GENERIC_INFO *)CurrentPccSubspace)->Type) {
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC:
Status = AddSubspaceStructType0 (
- (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)CurrentPccSubspace,
+ (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)CurrentPccSubspace,
(EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *)PccBuffer
);
@@ -714,7 +723,7 @@ PopulatePcctTable (
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
Status = AddSubspaceStructType1 (
- (CM_ARM_PCC_SUBSPACE_TYPE1_INFO *)CurrentPccSubspace,
+ (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *)CurrentPccSubspace,
(EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *)PccBuffer
);
@@ -723,7 +732,7 @@ PopulatePcctTable (
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
Status = AddSubspaceStructType2 (
- (CM_ARM_PCC_SUBSPACE_TYPE2_INFO *)CurrentPccSubspace,
+ (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *)CurrentPccSubspace,
(EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *)PccBuffer
);
@@ -732,7 +741,7 @@ PopulatePcctTable (
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
Status = AddSubspaceStructType34 (
- (CM_ARM_PCC_SUBSPACE_TYPE3_INFO *)CurrentPccSubspace,
+ (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *)CurrentPccSubspace,
(EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *)PccBuffer
);
@@ -741,7 +750,7 @@ PopulatePcctTable (
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
Status = AddSubspaceStructType34 (
- (CM_ARM_PCC_SUBSPACE_TYPE4_INFO *)CurrentPccSubspace,
+ (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO *)CurrentPccSubspace,
(EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC *)PccBuffer
);
@@ -750,7 +759,7 @@ PopulatePcctTable (
case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS:
Status = AddSubspaceStructType5 (
- (CM_ARM_PCC_SUBSPACE_TYPE5_INFO *)CurrentPccSubspace,
+ (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *)CurrentPccSubspace,
(EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *)PccBuffer
);
@@ -822,18 +831,18 @@ BuildPcctTable (
MAPPING_TABLE *MappingTable;
UINT32 MappingTableCount;
- CM_ARM_PCC_SUBSPACE_TYPE0_INFO *PccType0;
- UINT32 PccType0Count;
- CM_ARM_PCC_SUBSPACE_TYPE1_INFO *PccType1;
- UINT32 PccType1Count;
- CM_ARM_PCC_SUBSPACE_TYPE2_INFO *PccType2;
- UINT32 PccType2Count;
- CM_ARM_PCC_SUBSPACE_TYPE3_INFO *PccType3;
- UINT32 PccType3Count;
- CM_ARM_PCC_SUBSPACE_TYPE4_INFO *PccType4;
- UINT32 PccType4Count;
- CM_ARM_PCC_SUBSPACE_TYPE5_INFO *PccType5;
- UINT32 PccType5Count;
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *PccType0;
+ UINT32 PccType0Count;
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *PccType1;
+ UINT32 PccType1Count;
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *PccType2;
+ UINT32 PccType2Count;
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *PccType3;
+ UINT32 PccType3Count;
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO *PccType4;
+ UINT32 PccType4Count;
+ CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *PccType5;
+ UINT32 PccType5Count;
ASSERT (This != NULL);
ASSERT (AcpiTableInfo != NULL);
@@ -863,7 +872,7 @@ BuildPcctTable (
// First get all the Pcc Subpace CmObj of type X.
- Status = GetEArmObjPccSubspaceType0Info (
+ Status = GetEArchCommonObjPccSubspaceType0Info (
CfgMgrProtocol,
CM_NULL_TOKEN,
&PccType0,
@@ -874,7 +883,7 @@ BuildPcctTable (
goto error_handler;
}
- Status = GetEArmObjPccSubspaceType1Info (
+ Status = GetEArchCommonObjPccSubspaceType1Info (
CfgMgrProtocol,
CM_NULL_TOKEN,
&PccType1,
@@ -885,7 +894,7 @@ BuildPcctTable (
goto error_handler;
}
- Status = GetEArmObjPccSubspaceType2Info (
+ Status = GetEArchCommonObjPccSubspaceType2Info (
CfgMgrProtocol,
CM_NULL_TOKEN,
&PccType2,
@@ -896,7 +905,7 @@ BuildPcctTable (
goto error_handler;
}
- Status = GetEArmObjPccSubspaceType3Info (
+ Status = GetEArchCommonObjPccSubspaceType3Info (
CfgMgrProtocol,
CM_NULL_TOKEN,
&PccType3,
@@ -907,7 +916,7 @@ BuildPcctTable (
goto error_handler;
}
- Status = GetEArmObjPccSubspaceType4Info (
+ Status = GetEArchCommonObjPccSubspaceType4Info (
CfgMgrProtocol,
CM_NULL_TOKEN,
&PccType4,
@@ -918,7 +927,7 @@ BuildPcctTable (
goto error_handler;
}
- Status = GetEArmObjPccSubspaceType5Info (
+ Status = GetEArchCommonObjPccSubspaceType5Info (
CfgMgrProtocol,
CM_NULL_TOKEN,
&PccType5,
@@ -1066,6 +1075,7 @@ error_handler:
**/
STATIC
EFI_STATUS
+EFIAPI
FreePcctTableResources (
IN CONST ACPI_TABLE_GENERATOR *CONST This,
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
@@ -1111,7 +1121,7 @@ ACPI_PCCT_GENERATOR PcctGenerator = {
// Minimum ACPI Table Revision supported by this Generator
EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION,
// Creator ID
- TABLE_GENERATOR_CREATOR_ID_ARM,
+ TABLE_GENERATOR_CREATOR_ID,
// Creator Revision
PCCT_GENERATOR_REVISION,
// Build Table function
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.h
index 0631a1f..b99bf91 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPcctLib/PcctGenerator.h
@@ -19,7 +19,7 @@
*/
typedef struct MappingTable {
/// Mapping table for Subspace Ids.
- /// Subspace ID/Index <-> CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO pointer
+ /// Subspace ID/Index <-> CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO pointer
VOID **Table;
/// Number of entries in the Table.
@@ -34,7 +34,8 @@ typedef struct AcpiPcctGenerator {
// Private fields are defined from here.
- /// Table to map: Subspace ID/Index <-> CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO pointer
+ /// Table to map:
+ /// Subspace ID/Index <-> CM_ARCH_COMMON_PCC_SUBSPACE_TYPE[X]_INFO pointer
MAPPING_TABLE MappingTable;
} ACPI_PCCT_GENERATOR;
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf
index 2c7d195..a1c91a6 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf
@@ -8,7 +8,7 @@
[Defines]
INF_VERSION = 0x0001001B
- BASE_NAME = AcpiPpttLibArm
+ BASE_NAME = AcpiPpttLib
FILE_GUID = FA102D52-5A92-4F95-A097-1D53F9CF5959
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c
index 78fa63f..8e2e1f6 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.c
@@ -32,9 +32,9 @@
Requirements:
The following Configuration Manager Object(s) are used by this Generator:
- - EArmObjProcHierarchyInfo (REQUIRED)
- - EArmObjCacheInfo
- - EArmObjCmRef
+ - EArchCommonObjProcHierarchyInfo (REQUIRED)
+ - EArchCommonObjCacheInfo
+ - EArchCommonObjCmRef
- EArmObjGicCInfo (REQUIRED)
*/
@@ -43,9 +43,9 @@
information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjProcHierarchyInfo,
- CM_ARM_PROC_HIERARCHY_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjProcHierarchyInfo,
+ CM_ARCH_COMMON_PROC_HIERARCHY_INFO
);
/**
@@ -53,9 +53,9 @@ GET_OBJECT_LIST (
from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjCacheInfo,
- CM_ARM_CACHE_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjCacheInfo,
+ CM_ARCH_COMMON_CACHE_INFO
);
/**
@@ -63,9 +63,9 @@ GET_OBJECT_LIST (
reference information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjCmRef,
- CM_ARM_OBJ_REF
+ EObjNameSpaceArchCommon,
+ EArchCommonObjCmRef,
+ CM_ARCH_COMMON_OBJ_REF
);
/**
@@ -90,7 +90,7 @@ GET_OBJECT_LIST (
STATIC
UINT32
GetProcHierarchyNodeSize (
- IN CONST CM_ARM_PROC_HIERARCHY_INFO *Node
+ IN CONST CM_ARCH_COMMON_PROC_HIERARCHY_INFO *Node
)
{
ASSERT (Node != NULL);
@@ -107,7 +107,7 @@ GetProcHierarchyNodeSize (
GET_SIZE_OF_PPTT_STRUCTS (
ProcHierarchyNodes,
GetProcHierarchyNodeSize (NodesToIndex),
- CM_ARM_PROC_HIERARCHY_INFO
+ CM_ARCH_COMMON_PROC_HIERARCHY_INFO
);
/**
@@ -117,7 +117,7 @@ GET_SIZE_OF_PPTT_STRUCTS (
GET_SIZE_OF_PPTT_STRUCTS (
CacheTypeStructs,
sizeof (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE),
- CM_ARM_CACHE_INFO
+ CM_ARCH_COMMON_CACHE_INFO
);
/**
@@ -264,7 +264,7 @@ DetectCyclesInTopology (
Protocol Interface.
@param [in] PrivResArray Pointer to the array of private resources.
@param [in] PrivResCount Number of private resources.
- @param [in] PrivResArrayToken Reference Token for the CM_ARM_OBJ_REF
+ @param [in] PrivResArrayToken Reference Token for the CM_ARCH_COMMON_OBJ_REF
array describing node's private resources.
@retval EFI_SUCCESS Array updated successfully.
@@ -281,10 +281,10 @@ AddPrivateResources (
IN CONST CM_OBJECT_TOKEN PrivResArrayToken
)
{
- EFI_STATUS Status;
- CM_ARM_OBJ_REF *CmObjRefs;
- UINT32 CmObjRefCount;
- PPTT_NODE_INDEXER *PpttNodeFound;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_OBJ_REF *CmObjRefs;
+ UINT32 CmObjRefCount;
+ PPTT_NODE_INDEXER *PpttNodeFound;
ASSERT (
(Generator != NULL) &&
@@ -308,7 +308,7 @@ AddPrivateResources (
CmObjRefCount = 0;
// Get the CM Object References
- Status = GetEArmObjCmRef (
+ Status = GetEArchCommonObjCmRef (
CfgMgrProtocol,
PrivResArrayToken,
&CmObjRefs,
@@ -397,22 +397,24 @@ AddPrivateResources (
@param [in] Index2 Index of Object2 to be displayed for debugging
purposes.
- @retval TRUE Object1 and Object2 have the same GicCToken.
- @retval FALSE Object1 and Object2 have different GicCTokens.
+ @retval TRUE Object1 and Object2 have the same
+ AcpiIdObjectToken.
+ @retval FALSE Object1 and Object2 have different
+ AcpiIdObjectTokens.
**/
BOOLEAN
EFIAPI
-IsGicCTokenEqual (
+IsAcpiIdObjectTokenEqual (
IN CONST VOID *Object1,
IN CONST VOID *Object2,
IN UINTN Index1,
IN UINTN Index2
)
{
- PPTT_NODE_INDEXER *IndexedObject1;
- PPTT_NODE_INDEXER *IndexedObject2;
- CM_ARM_PROC_HIERARCHY_INFO *ProcNode1;
- CM_ARM_PROC_HIERARCHY_INFO *ProcNode2;
+ PPTT_NODE_INDEXER *IndexedObject1;
+ PPTT_NODE_INDEXER *IndexedObject2;
+ CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNode1;
+ CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNode2;
ASSERT (
(Object1 != NULL) &&
@@ -421,23 +423,23 @@ IsGicCTokenEqual (
IndexedObject1 = (PPTT_NODE_INDEXER *)Object1;
IndexedObject2 = (PPTT_NODE_INDEXER *)Object2;
- ProcNode1 = (CM_ARM_PROC_HIERARCHY_INFO *)IndexedObject1->Object;
- ProcNode2 = (CM_ARM_PROC_HIERARCHY_INFO *)IndexedObject2->Object;
+ ProcNode1 = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)IndexedObject1->Object;
+ ProcNode2 = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)IndexedObject2->Object;
if (IS_ACPI_PROC_ID_VALID (ProcNode1) &&
IS_ACPI_PROC_ID_VALID (ProcNode2) &&
- (ProcNode1->GicCToken != CM_NULL_TOKEN) &&
- (ProcNode2->GicCToken != CM_NULL_TOKEN) &&
- (ProcNode1->GicCToken == ProcNode2->GicCToken))
+ (ProcNode1->AcpiIdObjectToken != CM_NULL_TOKEN) &&
+ (ProcNode2->AcpiIdObjectToken != CM_NULL_TOKEN) &&
+ (ProcNode1->AcpiIdObjectToken == ProcNode2->AcpiIdObjectToken))
{
DEBUG ((
DEBUG_ERROR,
"ERROR: PPTT: Two Processor Hierarchy Info objects (%d and %d) map to " \
- "the same GICC Info object. ACPI Processor IDs are not unique. " \
- "GicCToken = %p.\n",
+ "the same ACPI ID reference object. ACPI Processor IDs are not unique. " \
+ "AcpiIdObjectToken = %p.\n",
Index1,
Index2,
- ProcNode1->GicCToken
+ ProcNode1->AcpiIdObjectToken
));
return TRUE;
}
@@ -474,14 +476,14 @@ AddProcHierarchyNodes (
EFI_STATUS Status;
EFI_ACPI_6_4_PPTT_STRUCTURE_PROCESSOR *ProcStruct;
UINT32 *PrivateResources;
- BOOLEAN IsGicCTokenDuplicated;
+ BOOLEAN IsAcpiIdObjectTokenDuplicated;
CM_ARM_GICC_INFO *GicCInfoList;
UINT32 GicCInfoCount;
UINT32 UniqueGicCRefCount;
- PPTT_NODE_INDEXER *PpttNodeFound;
- CM_ARM_PROC_HIERARCHY_INFO *ProcInfoNode;
+ PPTT_NODE_INDEXER *PpttNodeFound;
+ CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcInfoNode;
PPTT_NODE_INDEXER *ProcNodeIterator;
UINT32 NodeCount;
@@ -500,22 +502,22 @@ AddProcHierarchyNodes (
NodeCount = Generator->ProcHierarchyNodeCount;
// Check if every GICC Object is referenced by onlu one Proc Node
- IsGicCTokenDuplicated = FindDuplicateValue (
- ProcNodeIterator,
- NodeCount,
- sizeof (PPTT_NODE_INDEXER),
- IsGicCTokenEqual
- );
+ IsAcpiIdObjectTokenDuplicated = FindDuplicateValue (
+ ProcNodeIterator,
+ NodeCount,
+ sizeof (PPTT_NODE_INDEXER),
+ IsAcpiIdObjectTokenEqual
+ );
// Duplicate GIC CPU Interface Token was found so two PPTT Processor Hierarchy
// Nodes map to the same MADT GICC structure
- if (IsGicCTokenDuplicated) {
+ if (IsAcpiIdObjectTokenDuplicated) {
return EFI_INVALID_PARAMETER;
}
UniqueGicCRefCount = 0;
while (NodeCount-- != 0) {
- ProcInfoNode = (CM_ARM_PROC_HIERARCHY_INFO *)ProcNodeIterator->Object;
+ ProcInfoNode = (CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)ProcNodeIterator->Object;
// Check if the private resource count is within the size limit
// imposed on the Processor Hierarchy node by the specification.
@@ -575,7 +577,7 @@ AddProcHierarchyNodes (
// Test if the reference is to a 'leaf' node
if (IS_PROC_NODE_LEAF (
- ((CM_ARM_PROC_HIERARCHY_INFO *)PpttNodeFound->Object)
+ ((CM_ARCH_COMMON_PROC_HIERARCHY_INFO *)PpttNodeFound->Object)
))
{
Status = EFI_INVALID_PARAMETER;
@@ -602,14 +604,14 @@ AddProcHierarchyNodes (
if (!IS_ACPI_PROC_ID_VALID (ProcInfoNode)) {
// Default invalid ACPI Processor ID to 0
ProcStruct->AcpiProcessorId = 0;
- } else if (ProcInfoNode->GicCToken == CM_NULL_TOKEN) {
+ } else if (ProcInfoNode->AcpiIdObjectToken == CM_NULL_TOKEN) {
Status = EFI_INVALID_PARAMETER;
DEBUG ((
DEBUG_ERROR,
- "ERROR: PPTT: The 'ACPI Processor ID valid' flag is set but no GICC " \
- "structure token was provided. GicCToken = %p. RequestorToken = %p. " \
- "Status = %r\n",
- ProcInfoNode->GicCToken,
+ "ERROR: PPTT: The 'ACPI Processor ID valid' flag is set but no " \
+ "ACPI ID Reference object token was provided. " \
+ "AcpiIdObjectToken = %p. RequestorToken = %p. Status = %r\n",
+ ProcInfoNode->AcpiIdObjectToken,
ProcInfoNode->Token,
Status
));
@@ -617,17 +619,17 @@ AddProcHierarchyNodes (
} else {
Status = GetEArmObjGicCInfo (
CfgMgrProtocol,
- ProcInfoNode->GicCToken,
+ ProcInfoNode->AcpiIdObjectToken,
&GicCInfoList,
&GicCInfoCount
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
- "ERROR: PPTT: Failed to get GICC structure. ACPI Processor ID " \
- "can't be populated. GicCToken = %p. RequestorToken = %p. " \
- "Status = %r\n",
- ProcInfoNode->GicCToken,
+ "ERROR: PPTT: Failed to get ACPI ID Reference object token. " \
+ "ACPI Processor ID can't be populated. " \
+ "AcpiIdObjectToken = %p. RequestorToken = %p. Status = %r\n",
+ ProcInfoNode->AcpiIdObjectToken,
ProcInfoNode->Token,
Status
));
@@ -640,10 +642,10 @@ AddProcHierarchyNodes (
DEBUG_ERROR,
"ERROR: PPTT: Failed to find a unique GICC structure. " \
"ACPI Processor ID can't be populated. " \
- "GICC Structure Count = %d. GicCToken = %p. RequestorToken = %p " \
+ "GICC Structure Count = %d. AcpiIdObjectToken = %p. RequestorToken = %p " \
"Status = %r\n",
GicCInfoCount,
- ProcInfoNode->GicCToken,
+ ProcInfoNode->AcpiIdObjectToken,
ProcInfoNode->Token,
Status
));
@@ -786,7 +788,7 @@ AddCacheTypeStructures (
EFI_STATUS Status;
EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE *CacheStruct;
PPTT_NODE_INDEXER *PpttNodeFound;
- CM_ARM_CACHE_INFO *CacheInfoNode;
+ CM_ARCH_COMMON_CACHE_INFO *CacheInfoNode;
PPTT_NODE_INDEXER *CacheNodeIterator;
UINT32 NodeCount;
BOOLEAN CacheIdUnique;
@@ -812,7 +814,7 @@ AddCacheTypeStructures (
}
for (NodeIndex = 0; NodeIndex < NodeCount; NodeIndex++) {
- CacheInfoNode = (CM_ARM_CACHE_INFO *)CacheNodeIterator->Object;
+ CacheInfoNode = (CM_ARCH_COMMON_CACHE_INFO *)CacheNodeIterator->Object;
// Populate the node header
CacheStruct->Type = EFI_ACPI_6_4_PPTT_TYPE_CACHE;
@@ -1072,8 +1074,8 @@ BuildPpttTable (
UINT32 ProcHierarchyNodeOffset;
UINT32 CacheStructOffset;
- CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeList;
- CM_ARM_CACHE_INFO *CacheStructList;
+ CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeList;
+ CM_ARCH_COMMON_CACHE_INFO *CacheStructList;
ACPI_PPTT_GENERATOR *Generator;
@@ -1110,7 +1112,7 @@ BuildPpttTable (
// Get the processor hierarchy info and update the processor topology
// structure count with Processor Hierarchy Nodes (Type 0)
- Status = GetEArmObjProcHierarchyInfo (
+ Status = GetEArchCommonObjProcHierarchyInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&ProcHierarchyNodeList,
@@ -1130,7 +1132,7 @@ BuildPpttTable (
// Get the cache info and update the processor topology structure count with
// Cache Type Structures (Type 1)
- Status = GetEArmObjCacheInfo (
+ Status = GetEArchCommonObjCacheInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&CacheStructList,
@@ -1340,6 +1342,7 @@ error_handler:
**/
STATIC
EFI_STATUS
+EFIAPI
FreePpttTableResources (
IN CONST ACPI_TABLE_GENERATOR *CONST This,
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
@@ -1400,7 +1403,7 @@ ACPI_PPTT_GENERATOR PpttGenerator = {
// Minimum supported ACPI Table Revision
EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION,
// Creator ID
- TABLE_GENERATOR_CREATOR_ID_ARM,
+ TABLE_GENERATOR_CREATOR_ID,
// Creator Revision
PPTT_GENERATOR_REVISION,
// Build Table function
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.h
index 15b0a98..15b0a98 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/PpttGenerator.h
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/PpttGenerator.h
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf
index f2ab1b7..8b461ea 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf
@@ -8,7 +8,7 @@
[Defines]
INF_VERSION = 0x00010019
- BASE_NAME = AcpiRawLibArm
+ BASE_NAME = AcpiRawLib
FILE_GUID = 20F31568-D687-49BA-B326-CCD9D38EDE16
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
@@ -27,10 +27,3 @@
[LibraryClasses]
BaseLib
-
-[Pcd]
-
-[Protocols]
-
-[Guids]
-
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/RawGenerator.c
index a8323ad..a4f1cfb 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/RawGenerator.c
@@ -81,7 +81,7 @@ ACPI_TABLE_GENERATOR RawGenerator = {
// Minimum ACPI Table Revision - Unused
0,
// Creator ID
- TABLE_GENERATOR_CREATOR_ID_ARM,
+ TABLE_GENERATOR_CREATOR_ID,
// Creator Revision
RAW_GENERATOR_REVISION,
// Build Table function
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf
index e11f878..80a6102 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf
@@ -8,7 +8,7 @@
[Defines]
INF_VERSION = 0x00010019
- BASE_NAME = AcpiSpcrLibArm
+ BASE_NAME = AcpiSpcrLib
FILE_GUID = 55088136-7B78-4974-B1EE-F630150D0DE7
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
@@ -28,10 +28,3 @@
[LibraryClasses]
BaseLib
SsdtSerialPortFixupLib
-
-[Pcd]
-
-[Protocols]
-
-[Guids]
-
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c
index 59cbacb..ddd8262 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/SpcrGenerator.c
@@ -26,14 +26,14 @@
#include <Library/TableHelperLib.h>
#include <Protocol/ConfigurationManagerProtocol.h>
-/** ARM standard SPCR Table Generator
+/** Standard SPCR Table Generator
Constructs the SPCR table for PL011 or SBSA UART peripherals.
Requirements:
The following Configuration Manager Object(s) are required by
this Generator:
- - EArmObjSerialConsolePortInfo
+ - EArchCommonObjConsolePortInfo
NOTE: This implementation ignores the possibility that the Serial settings may
be modified from the UEFI Shell. A more complex handler would be needed
@@ -98,9 +98,9 @@ EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE AcpiSpcr = {
Port Information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjSerialConsolePortInfo,
- CM_ARM_SERIAL_PORT_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjConsolePortInfo,
+ CM_ARCH_COMMON_SERIAL_PORT_INFO
)
/** Free any resources allocated for constructing the tables.
@@ -200,10 +200,10 @@ BuildSpcrTableEx (
OUT UINTN *CONST TableCount
)
{
- EFI_STATUS Status;
- CM_ARM_SERIAL_PORT_INFO *SerialPortInfo;
- UINT32 SerialPortCount;
- EFI_ACPI_DESCRIPTION_HEADER **TableList;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo;
+ UINT32 SerialPortCount;
+ EFI_ACPI_DESCRIPTION_HEADER **TableList;
ASSERT (This != NULL);
ASSERT (AcpiTableInfo != NULL);
@@ -229,7 +229,7 @@ BuildSpcrTableEx (
*Table = NULL;
- Status = GetEArmObjSerialConsolePortInfo (
+ Status = GetEArchCommonObjConsolePortInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&SerialPortInfo,
@@ -419,7 +419,7 @@ ACPI_TABLE_GENERATOR SpcrGenerator = {
// Minimum supported ACPI Table Revision
EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION,
// Creator ID
- TABLE_GENERATOR_CREATOR_ID_ARM,
+ TABLE_GENERATOR_CREATOR_ID,
// Creator Revision
SPCR_GENERATOR_REVISION,
// Build table function. Use the extended version instead.
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf
index 5891dc4..14e435e 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf
@@ -8,7 +8,7 @@
[Defines]
INF_VERSION = 0x0001001B
- BASE_NAME = AcpiSratLibArm
+ BASE_NAME = AcpiSratLib
FILE_GUID = 2CE21E0A-A39C-4B26-BC0E-526178036ACD
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
@@ -18,6 +18,13 @@
[Sources]
SratGenerator.c
+ SratGenerator.h
+
+[Sources.ARM, Sources.AARCH64]
+ Arm/ArmSratGenerator.c
+
+[Sources.IA32, Sources.X64]
+ SratGeneratorNull.c
[Packages]
EmbeddedPkg/EmbeddedPkg.dec
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/Arm/ArmSratGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/Arm/ArmSratGenerator.c
new file mode 100644
index 0000000..3d36b25
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/Arm/ArmSratGenerator.c
@@ -0,0 +1,262 @@
+/** @file
+ Arm SRAT Table Generator
+
+ Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.3 Specification, January 2019
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#include "SratGenerator.h"
+
+/**
+ ARM standard SRAT Generator
+
+ Requirements:
+ The following Configuration Manager Object(s) are used by this Generator:
+ - EArmObjGicCInfo (REQUIRED)
+ - EArmObjGicItsInfo (OPTIONAL)
+*/
+
+/** This macro expands to a function that retrieves the GIC
+ CPU interface Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGicCInfo,
+ CM_ARM_GICC_INFO
+ );
+
+/** This macro expands to a function that retrieves the GIC
+ Interrupt Translation Service Information from the
+ Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGicItsInfo,
+ CM_ARM_GIC_ITS_INFO
+ );
+
+/** Enum of the Arm specific CM objects required to
+ build the arch specific information of the SRAT table.
+*/
+typedef enum ArmSratSubTableType {
+ EArmGicCSubTableType,
+ EArmGicItsSubTableType,
+ EArmSubTableTypeMax,
+} EARM_SRAT_SUB_TABLE_TYPE;
+
+typedef struct SratSubTable {
+ /// Start offset of the arch specific sub-table.
+ UINT32 Offset;
+
+ /// Count
+ UINT32 Count;
+
+ /// Array of CmInfo objects of the relevant type.
+ VOID *CmInfo;
+} SRAT_SUB_TABLE;
+
+STATIC SRAT_SUB_TABLE mSratSubTable[EArmSubTableTypeMax];
+
+/** Reserve arch sub-tables space.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ @param [in, out] ArchOffset On input, contains the offset where arch specific
+ sub-tables can be written. It is expected that
+ there enough space to write all the arch specific
+ sub-tables from this offset onward.
+ On ouput, contains the ending offset of the arch
+ specific sub-tables.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+EFI_STATUS
+EFIAPI
+ArchReserveOffsets (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT UINT32 *ArchOffset
+ )
+{
+ EFI_STATUS Status;
+
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (ArchOffset != NULL);
+
+ Status = GetEArmObjGicCInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ (CM_ARM_GICC_INFO **)&mSratSubTable[EArmGicCSubTableType].CmInfo,
+ &mSratSubTable[EArmGicCSubTableType].Count
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SRAT: Failed to get GICC Info. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ if (mSratSubTable[EArmGicCSubTableType].Count == 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SRAT: GIC CPU Interface information not provided.\n"
+ ));
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetEArmObjGicItsInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ (CM_ARM_GIC_ITS_INFO **)&mSratSubTable[EArmGicItsSubTableType].CmInfo,
+ &mSratSubTable[EArmGicItsSubTableType].Count
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SRAT: Failed to get GIC ITS Info. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ mSratSubTable[EArmGicCSubTableType].Offset = *ArchOffset;
+ *ArchOffset += (sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE) *
+ mSratSubTable[EArmGicCSubTableType].Count);
+
+ if (mSratSubTable[EArmGicItsSubTableType].Count != 0) {
+ mSratSubTable[EArmGicItsSubTableType].Offset = *ArchOffset;
+ *ArchOffset += (sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE) *
+ mSratSubTable[EArmGicItsSubTableType].Count);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Add the GICC Affinity Structures in the SRAT Table.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Srat Pointer to the SRAT Table.
+**/
+STATIC
+VOID
+EFIAPI
+AddGICCAffinity (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat
+ )
+{
+ EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *GicCAff;
+ CM_ARM_GICC_INFO *GicCInfo;
+
+ GicCInfo = mSratSubTable[EArmGicCSubTableType].CmInfo;
+ GicCAff = (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *)((UINT8 *)Srat +
+ mSratSubTable[EArmGicCSubTableType].Offset);
+
+ while (mSratSubTable[EArmGicCSubTableType].Count-- != 0) {
+ DEBUG ((DEBUG_INFO, "SRAT: GicCAff = 0x%p\n", GicCAff));
+
+ GicCAff->Type = EFI_ACPI_6_3_GICC_AFFINITY;
+ GicCAff->Length = sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE);
+ GicCAff->ProximityDomain = GicCInfo->ProximityDomain;
+ GicCAff->AcpiProcessorUid = GicCInfo->AcpiProcessorUid;
+ GicCAff->Flags = GicCInfo->AffinityFlags;
+ GicCAff->ClockDomain = GicCInfo->ClockDomain;
+
+ // Next
+ GicCAff++;
+ GicCInfo++;
+ }// while
+}
+
+/** Add the GIC ITS Affinity Structures in the SRAT Table.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Srat Pointer to the SRAT Table.
+**/
+STATIC
+VOID
+EFIAPI
+AddGICItsAffinity (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat
+ )
+{
+ EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *GicItsAff;
+ CM_ARM_GIC_ITS_INFO *GicItsInfo;
+
+ GicItsInfo = mSratSubTable[EArmGicItsSubTableType].CmInfo;
+ GicItsAff = (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *)((UINT8 *)Srat +
+ mSratSubTable[EArmGicItsSubTableType].Offset);
+
+ while (mSratSubTable[EArmGicItsSubTableType].Count-- != 0) {
+ DEBUG ((DEBUG_INFO, "SRAT: GicItsAff = 0x%p\n", GicItsAff));
+
+ GicItsAff->Type = EFI_ACPI_6_3_GIC_ITS_AFFINITY;
+ GicItsAff->Length = sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE);
+ GicItsAff->ProximityDomain = GicItsInfo->ProximityDomain;
+ GicItsAff->Reserved[0] = EFI_ACPI_RESERVED_BYTE;
+ GicItsAff->Reserved[1] = EFI_ACPI_RESERVED_BYTE;
+ GicItsAff->ItsId = GicItsInfo->GicItsId;
+
+ // Next
+ GicItsAff++;
+ GicItsInfo++;
+ }// while
+}
+
+/** Add the arch specific sub-tables to the SRAT table.
+
+ These sub-tables are written in the space reserved beforehand.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Srat Pointer to the SRAT Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+**/
+EFI_STATUS
+EFIAPI
+AddArchObjects (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat
+ )
+{
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Srat != NULL);
+
+ AddGICCAffinity (CfgMgrProtocol, Srat);
+
+ if (mSratSubTable[EArmGicCSubTableType].Count != 0) {
+ AddGICItsAffinity (CfgMgrProtocol, Srat);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c
index 431995e..20e1a4b 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/SratGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.c
@@ -25,46 +25,27 @@
#include <Library/TableHelperLib.h>
#include <Protocol/ConfigurationManagerProtocol.h>
+#include "SratGenerator.h"
+
/**
- ARM standard SRAT Generator
+ Standard SRAT Generator
Requirements:
The following Configuration Manager Object(s) are used by this Generator:
- - EArmObjGicCInfo (REQUIRED)
- - EArmObjGicItsInfo (OPTIONAL)
- - EArmObjMemoryAffinityInfo (OPTIONAL)
- - EArmObjGenericInitiatorAffinityInfo (OPTIONAL)
- - EArmObjDeviceHandleAcpi (OPTIONAL)
- - EArmObjDeviceHandlePci (OPTIONAL)
-*/
-
-/** This macro expands to a function that retrieves the GIC
- CPU interface Information from the Configuration Manager.
+ - EArchCommonObjMemoryAffinityInfo (OPTIONAL)
+ - EArchCommonObjGenericInitiatorAffinityInfo (OPTIONAL)
+ - EArchCommonObjDeviceHandleAcpi (OPTIONAL)
+ - EArchCommonObjDeviceHandlePci (OPTIONAL)
*/
-GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjGicCInfo,
- CM_ARM_GICC_INFO
- );
-
-/** This macro expands to a function that retrieves the GIC
- Interrupt Translation Service Information from the
- Configuration Manager.
-*/
-GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjGicItsInfo,
- CM_ARM_GIC_ITS_INFO
- );
/**
This macro expands to a function that retrieves the Memory Affinity
information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjMemoryAffinityInfo,
- CM_ARM_MEMORY_AFFINITY_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjMemoryAffinityInfo,
+ CM_ARCH_COMMON_MEMORY_AFFINITY_INFO
);
/**
@@ -72,9 +53,9 @@ GET_OBJECT_LIST (
information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjGenericInitiatorAffinityInfo,
- CM_ARM_GENERIC_INITIATOR_AFFINITY_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjGenericInitiatorAffinityInfo,
+ CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO
);
/**
@@ -82,9 +63,9 @@ GET_OBJECT_LIST (
information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjDeviceHandleAcpi,
- CM_ARM_DEVICE_HANDLE_ACPI
+ EObjNameSpaceArchCommon,
+ EArchCommonObjDeviceHandleAcpi,
+ CM_ARCH_COMMON_DEVICE_HANDLE_ACPI
);
/**
@@ -92,9 +73,9 @@ GET_OBJECT_LIST (
information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjDeviceHandlePci,
- CM_ARM_DEVICE_HANDLE_PCI
+ EObjNameSpaceArchCommon,
+ EArchCommonObjDeviceHandlePci,
+ CM_ARCH_COMMON_DEVICE_HANDLE_PCI
);
/** Return the PCI Device information in BDF format
@@ -110,7 +91,7 @@ GET_OBJECT_LIST (
STATIC
UINT16
GetBdf (
- IN CONST CM_ARM_DEVICE_HANDLE_PCI *DeviceHandlePci
+ IN CONST CM_ARCH_COMMON_DEVICE_HANDLE_PCI *DeviceHandlePci
)
{
UINT16 Bdf;
@@ -121,102 +102,6 @@ GetBdf (
return Bdf;
}
-/** Add the GICC Affinity Structures in the SRAT Table.
-
- @param [in] CfgMgrProtocol Pointer to the Configuration Manager
- Protocol Interface.
- @param [in] Srat Pointer to the SRAT Table.
- @param [in] GicCAffOffset Offset of the GICC Affinity
- information in the SRAT Table.
- @param [in] GicCInfo Pointer to the GIC CPU Information list.
- @param [in] GicCCount Count of GIC CPU Interfaces.
-
- @retval EFI_SUCCESS Table generated successfully.
-**/
-STATIC
-EFI_STATUS
-AddGICCAffinity (
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat,
- IN CONST UINT32 GicCAffOffset,
- IN CONST CM_ARM_GICC_INFO *GicCInfo,
- IN UINT32 GicCCount
- )
-{
- EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *GicCAff;
-
- ASSERT (Srat != NULL);
- ASSERT (GicCInfo != NULL);
-
- GicCAff = (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *)((UINT8 *)Srat +
- GicCAffOffset);
-
- while (GicCCount-- != 0) {
- DEBUG ((DEBUG_INFO, "SRAT: GicCAff = 0x%p\n", GicCAff));
-
- GicCAff->Type = EFI_ACPI_6_3_GICC_AFFINITY;
- GicCAff->Length = sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE);
- GicCAff->ProximityDomain = GicCInfo->ProximityDomain;
- GicCAff->AcpiProcessorUid = GicCInfo->AcpiProcessorUid;
- GicCAff->Flags = GicCInfo->AffinityFlags;
- GicCAff->ClockDomain = GicCInfo->ClockDomain;
-
- // Next
- GicCAff++;
- GicCInfo++;
- }// while
-
- return EFI_SUCCESS;
-}
-
-/** Add the GIC ITS Affinity Structures in the SRAT Table.
-
- @param [in] CfgMgrProtocol Pointer to the Configuration Manager
- Protocol Interface.
- @param [in] Srat Pointer to the SRAT Table.
- @param [in] GicItsAffOffset Offset of the GIC ITS Affinity
- information in the SRAT Table.
- @param [in] GicItsInfo Pointer to the GIC ITS Information list.
- @param [in] GicItsCount Count of GIC ITS.
-
- @retval EFI_SUCCESS Table generated successfully.
-**/
-STATIC
-EFI_STATUS
-AddGICItsAffinity (
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat,
- IN CONST UINT32 GicItsAffOffset,
- IN CONST CM_ARM_GIC_ITS_INFO *GicItsInfo,
- IN UINT32 GicItsCount
- )
-{
- EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *GicItsAff;
-
- ASSERT (Srat != NULL);
- ASSERT (GicItsInfo != NULL);
-
- GicItsAff = (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *)((UINT8 *)Srat +
- GicItsAffOffset);
-
- while (GicItsCount-- != 0) {
- DEBUG ((DEBUG_INFO, "SRAT: GicItsAff = 0x%p\n", GicItsAff));
-
- GicItsAff->Type = EFI_ACPI_6_3_GIC_ITS_AFFINITY;
- GicItsAff->Length = sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE);
- GicItsAff->ProximityDomain = GicItsInfo->ProximityDomain;
- GicItsAff->Reserved[0] = EFI_ACPI_RESERVED_BYTE;
- GicItsAff->Reserved[1] = EFI_ACPI_RESERVED_BYTE;
- GicItsAff->ItsId = GicItsInfo->GicItsId;
-
- // Next
- GicItsAff++;
- GicItsInfo++;
- }// while
-
- return EFI_SUCCESS;
-}
-
/** Add the Memory Affinity Structures in the SRAT Table.
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
@@ -235,7 +120,7 @@ AddMemoryAffinity (
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat,
IN CONST UINT32 MemAffOffset,
- IN CONST CM_ARM_MEMORY_AFFINITY_INFO *MemAffInfo,
+ IN CONST CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo,
IN UINT32 MemAffCount
)
{
@@ -295,14 +180,14 @@ AddGenericInitiatorAffinity (
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat,
IN CONST UINT32 GenInitAffOff,
- IN CONST CM_ARM_GENERIC_INITIATOR_AFFINITY_INFO *GenInitAffInfo,
+ IN CONST CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO *GenInitAffInfo,
IN UINT32 GenInitAffCount
)
{
EFI_STATUS Status;
EFI_ACPI_6_3_GENERIC_INITIATOR_AFFINITY_STRUCTURE *GenInitAff;
- CM_ARM_DEVICE_HANDLE_ACPI *DeviceHandleAcpi;
- CM_ARM_DEVICE_HANDLE_PCI *DeviceHandlePci;
+ CM_ARCH_COMMON_DEVICE_HANDLE_ACPI *DeviceHandleAcpi;
+ CM_ARCH_COMMON_DEVICE_HANDLE_PCI *DeviceHandlePci;
UINT32 DeviceHandleCount;
ASSERT (Srat != NULL);
@@ -331,7 +216,7 @@ AddGenericInitiatorAffinity (
}
if (GenInitAffInfo->DeviceHandleType == EFI_ACPI_6_3_ACPI_DEVICE_HANDLE) {
- Status = GetEArmObjDeviceHandleAcpi (
+ Status = GetEArchCommonObjDeviceHandleAcpi (
CfgMgrProtocol,
GenInitAffInfo->DeviceHandleToken,
&DeviceHandleAcpi,
@@ -362,7 +247,7 @@ AddGenericInitiatorAffinity (
} else if (GenInitAffInfo->DeviceHandleType ==
EFI_ACPI_6_3_PCI_DEVICE_HANDLE)
{
- Status = GetEArmObjDeviceHandlePci (
+ Status = GetEArchCommonObjDeviceHandlePci (
CfgMgrProtocol,
GenInitAffInfo->DeviceHandleToken,
&DeviceHandlePci,
@@ -455,20 +340,14 @@ BuildSratTable (
{
EFI_STATUS Status;
UINT32 TableSize;
- UINT32 GicCCount;
- UINT32 GicItsCount;
UINT32 MemAffCount;
UINT32 GenInitiatorAffCount;
- UINT32 GicCAffOffset;
- UINT32 GicItsAffOffset;
UINT32 MemAffOffset;
UINT32 GenInitiatorAffOffset;
- CM_ARM_GICC_INFO *GicCInfo;
- CM_ARM_GIC_ITS_INFO *GicItsInfo;
- CM_ARM_MEMORY_AFFINITY_INFO *MemAffInfo;
- CM_ARM_GENERIC_INITIATOR_AFFINITY_INFO *GenInitiatorAffInfo;
+ CM_ARCH_COMMON_MEMORY_AFFINITY_INFO *MemAffInfo;
+ CM_ARCH_COMMON_GENERIC_INITIATOR_AFFINITY_INFO *GenInitiatorAffInfo;
EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *Srat;
@@ -497,47 +376,7 @@ BuildSratTable (
*Table = NULL;
- Status = GetEArmObjGicCInfo (
- CfgMgrProtocol,
- CM_NULL_TOKEN,
- &GicCInfo,
- &GicCCount
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: SRAT: Failed to get GICC Info. Status = %r\n",
- Status
- ));
- goto error_handler;
- }
-
- if (GicCCount == 0) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: SRAT: GIC CPU Interface information not provided.\n"
- ));
- ASSERT (0);
- Status = EFI_INVALID_PARAMETER;
- goto error_handler;
- }
-
- Status = GetEArmObjGicItsInfo (
- CfgMgrProtocol,
- CM_NULL_TOKEN,
- &GicItsInfo,
- &GicItsCount
- );
- if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: SRAT: Failed to get GIC ITS Info. Status = %r\n",
- Status
- ));
- goto error_handler;
- }
-
- Status = GetEArmObjMemoryAffinityInfo (
+ Status = GetEArchCommonObjMemoryAffinityInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&MemAffInfo,
@@ -552,7 +391,7 @@ BuildSratTable (
goto error_handler;
}
- Status = GetEArmObjGenericInitiatorAffinityInfo (
+ Status = GetEArchCommonObjGenericInitiatorAffinityInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&GenInitiatorAffInfo,
@@ -571,13 +410,18 @@ BuildSratTable (
// Calculate the size of the SRAT table
TableSize = sizeof (EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER);
- GicCAffOffset = TableSize;
- TableSize += (sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE) * GicCCount);
-
- if (GicItsCount != 0) {
- GicItsAffOffset = TableSize;
- TableSize += (sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE) *
- GicItsCount);
+ // Place the Arch specific subtables/structures first and
+ // reserve the offsets. The common subtables/structures
+ // are placed next.
+ Status = ArchReserveOffsets (CfgMgrProtocol, &TableSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SRAT: Failed to reserve arch offsets."
+ " Status = %r\n",
+ Status
+ ));
+ goto error_handler;
}
if (MemAffCount != 0) {
@@ -636,40 +480,16 @@ BuildSratTable (
Srat->Reserved1 = 1;
Srat->Reserved2 = EFI_ACPI_RESERVED_QWORD;
- Status = AddGICCAffinity (
- CfgMgrProtocol,
- Srat,
- GicCAffOffset,
- GicCInfo,
- GicCCount
- );
+ Status = AddArchObjects (CfgMgrProtocol, Srat);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
- "ERROR: SRAT: Failed to add GICC Affinity structures. Status = %r\n",
+ "ERROR: SRAT: Failed to add arch objects header. Status = %r\n",
Status
));
goto error_handler;
}
- if (GicItsCount != 0) {
- Status = AddGICItsAffinity (
- CfgMgrProtocol,
- Srat,
- GicItsAffOffset,
- GicItsInfo,
- GicItsCount
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "ERROR: SRAT: Failed to add GIC ITS Affinity structures. Status = %r\n",
- Status
- ));
- goto error_handler;
- }
- }
-
if (MemAffCount != 0) {
Status = AddMemoryAffinity (
CfgMgrProtocol,
@@ -732,6 +552,7 @@ error_handler:
**/
STATIC
EFI_STATUS
+EFIAPI
FreeSratTableResources (
IN CONST ACPI_TABLE_GENERATOR *CONST This,
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
@@ -778,7 +599,7 @@ ACPI_TABLE_GENERATOR SratGenerator = {
// Minimum supported ACPI Table Revision
EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION,
// Creator ID
- TABLE_GENERATOR_CREATOR_ID_ARM,
+ TABLE_GENERATOR_CREATOR_ID,
// Creator Revision
SRAT_GENERATOR_REVISION,
// Build Table function
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.h
new file mode 100644
index 0000000..106d008
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGenerator.h
@@ -0,0 +1,59 @@
+/** @file
+ SRAT Table Generator
+
+ Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.3 Specification, January 2019
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#ifndef SRAT_GENERATOR_H_
+#define SRAT_GENERATOR_H_
+
+/** Reserve arch sub-tables space.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ @param [in, out] ArchOffset On input, contains the offset where arch specific
+ sub-tables can be written. It is expected that
+ there enough space to write all the arch specific
+ sub-tables from this offset onward.
+ On ouput, contains the ending offset of the arch
+ specific sub-tables.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+EFI_STATUS
+EFIAPI
+ArchReserveOffsets (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT UINT32 *ArchOffset
+ );
+
+/** Add the arch specific sub-tables to the SRAT table.
+
+ These sub-tables are written in the space reserved beforehand.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Srat Pointer to the SRAT Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+**/
+EFI_STATUS
+EFIAPI
+AddArchObjects (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat
+ );
+
+#endif // SRAT_GENERATOR_H_
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGeneratorNull.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGeneratorNull.c
new file mode 100644
index 0000000..4ebdf97
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/SratGeneratorNull.c
@@ -0,0 +1,79 @@
+/** @file
+ Common SRAT Table Generator
+
+ Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.3 Specification, January 2019
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#include "SratGenerator.h"
+
+/** Reserve arch sub-tables space.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ @param [in, out] ArchOffset On input, contains the offset where arch specific
+ sub-tables can be written. It is expected that
+ there enough space to write all the arch specific
+ sub-tables from this offset onward.
+ On ouput, contains the ending offset of the arch
+ specific sub-tables.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_UNSUPPORTED Not supported.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+EFI_STATUS
+EFIAPI
+ArchReserveOffsets (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT UINT32 *ArchOffset
+ )
+{
+ // Not implemented.
+ return EFI_UNSUPPORTED;
+}
+
+/** Add the arch specific sub-tables to the SRAT table.
+
+ These sub-tables are written in the space reserved beforehand.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Srat Pointer to the SRAT Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_UNSUPPORTED Not supported.
+**/
+EFI_STATUS
+EFIAPI
+AddArchObjects (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *CONST Srat
+ )
+{
+ // Not implemented.
+ return EFI_UNSUPPORTED;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c
new file mode 100644
index 0000000..140a2e4
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/Arm/ArmSsdtCpuTopologyGenerator.c
@@ -0,0 +1,408 @@
+/** @file
+ ARM SSDT Cpu Topology Table Generator Helpers.
+
+ Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.3 Specification - January 2019 - s8.4 Declaring Processors
+ - ACPI for CoreSight version 1.2 Platform Design Document
+ (https://developer.arm.com/documentation/den0067/a/?lang=en)
+
+ @par Glossary:
+ - ETE - Embedded Trace Extension.
+ - ETM - Embedded Trace Macrocell.
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/TableHelperLib.h>
+#include <Library/AmlLib/AmlLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#include "SsdtCpuTopologyGenerator.h"
+
+/** ARM SSDT Cpu Topology Table Generator.
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArmObjGicCInfo
+ - EArmObjEtInfo (OPTIONAL)
+*/
+
+/** This macro expands to a function that retrieves the GIC
+ CPU interface Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGicCInfo,
+ CM_ARM_GICC_INFO
+ );
+
+/**
+ This macro expands to a function that retrieves the ET device
+ information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjEtInfo,
+ CM_ARM_ET_INFO
+ );
+
+/** Create an embedded trace device and add it to the Cpu Node in the
+ AML namespace.
+
+ This generates the following ASL code:
+ Device (E002)
+ {
+ Name (_UID, 2)
+ Name (_HID, "ARMHC500")
+ }
+
+ Note: Currently we only support generating ETE nodes. Unlike ETM,
+ ETE has a system register interface and therefore does not need
+ the MMIO range to be described.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] ParentNode Parent node to attach the Cpu node to.
+ @param [in] AcpiProcessorUid ACPI Processor UID of the CPU.
+ @param [in] CpuName Value used to generate the node name.
+ @param [out] EtNodePtr If not NULL, return the created Cpu node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CreateAmlEtd (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN AML_NODE_HANDLE ParentNode,
+ IN UINT32 AcpiProcessorUid,
+ IN UINT32 CpuName,
+ OUT AML_OBJECT_NODE_HANDLE *EtNodePtr OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE EtNode;
+ CHAR8 AslName[AML_NAME_SEG_SIZE + 1];
+
+ ASSERT (Generator != NULL);
+ ASSERT (ParentNode != NULL);
+
+ Status = WriteAslName ('E', CpuName, AslName);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ Status = AmlCodeGenDevice (AslName, ParentNode, &EtNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ Status = AmlCodeGenNameInteger (
+ "_UID",
+ AcpiProcessorUid,
+ EtNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ Status = AmlCodeGenNameString (
+ "_HID",
+ ACPI_HID_ET_DEVICE,
+ EtNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // If requested, return the handle to the EtNode.
+ if (EtNodePtr != NULL) {
+ *EtNodePtr = EtNode;
+ }
+
+ return Status;
+}
+
+/** Create and add an Embedded trace device to the Cpu Node.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] AcpiProcessorUid ACPI processor Uid of the local intc (gicc, other)
+ describing the Cpu.
+ @param [in] EtToken Embedded Trace Token of the CPU.
+ @param [in] CpuName Value used to generate the CPU node name.
+ @param [in] CpuNode CPU Node to which the ET device node is
+ attached.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_UNSUPPORTED Feature Unsupported.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CreateAmlEtNode (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN UINT32 AcpiProcessorUid,
+ IN CM_OBJECT_TOKEN EtToken,
+ IN UINT32 CpuName,
+ IN AML_OBJECT_NODE_HANDLE *CpuNode
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_ET_INFO *EtInfo;
+
+ Status = GetEArmObjEtInfo (
+ CfgMgrProtocol,
+ EtToken,
+ &EtInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // Currently we only support creation of a ETE Node.
+ if (EtInfo->EtType != ArmEtTypeEte) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = CreateAmlEtd (
+ Generator,
+ CpuNode,
+ AcpiProcessorUid,
+ CpuName,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Create the processor hierarchy AML tree from arch specific CM objects.
+
+ The Arm architecture will use the CM_ARM_GICC_INFO CM objects for instance.
+ A processor container is by extension any non-leave device in the cpu topology.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] ScopeNode Scope node handle ('\_SB' scope).
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+CreateTopologyFromIntC (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN AML_OBJECT_NODE_HANDLE ScopeNode
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_GICC_INFO *GicCInfo;
+ UINT32 GicCInfoCount;
+ UINT32 Index;
+ AML_OBJECT_NODE_HANDLE CpuNode;
+
+ ASSERT (Generator != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (ScopeNode != NULL);
+
+ Status = GetEArmObjGicCInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &GicCInfo,
+ &GicCInfoCount
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ // For each CM_ARM_GICC_INFO object, create an AML node.
+ for (Index = 0; Index < GicCInfoCount; Index++) {
+ Status = CreateAmlCpu (
+ Generator,
+ ScopeNode,
+ GicCInfo[Index].AcpiProcessorUid,
+ Index,
+ &CpuNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ break;
+ }
+
+ // If a CPC info is associated with the
+ // GicCinfo, create an _CPC method returning them.
+ if (GicCInfo[Index].CpcToken != CM_NULL_TOKEN) {
+ Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, GicCInfo[Index].CpcToken, CpuNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ break;
+ }
+ }
+
+ if (GicCInfo[Index].EtToken != CM_NULL_TOKEN) {
+ Status = CreateAmlEtNode (
+ Generator,
+ CfgMgrProtocol,
+ GicCInfo[Index].AcpiProcessorUid,
+ GicCInfo[Index].EtToken,
+ Index,
+ CpuNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
+ } // for
+
+ return Status;
+}
+
+/** Get generic interrupt information from arch specific CM objects.
+
+ The AcpiProcessorUid, CpcToken, etc. are held in arch specific CM objects,
+ in the CM_ARM_GICC_INFO CM object for Arm for instance.
+ This wrapper allows to get this information from each arch object.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] AcpiIdObjectToken AcpiIdObjectToken identifying the CPU to fetch the
+ other fields from.
+ @param [out] AcpiProcessorUid AcpiProcessorUid of the CPU identified by
+ the AcpiIdObjectToken.
+ @param [out] CpcToken CpcToken of the CPU identified by
+ the AcpiIdObjectToken.
+ @param [out] PsdToken PsdToken of the CPU identified by
+ the AcpiIdObjectToken.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+**/
+EFI_STATUS
+EFIAPI
+GetIntCInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CM_OBJECT_TOKEN AcpiIdObjectToken,
+ OUT UINT32 *AcpiProcessorUid,
+ OUT CM_OBJECT_TOKEN *CpcToken,
+ OUT CM_OBJECT_TOKEN *PsdToken
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_GICC_INFO *GicCInfo;
+
+ Status = GetEArmObjGicCInfo (
+ CfgMgrProtocol,
+ AcpiIdObjectToken,
+ &GicCInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (AcpiProcessorUid != NULL) {
+ *AcpiProcessorUid = GicCInfo->AcpiProcessorUid;
+ }
+
+ if (CpcToken != NULL) {
+ *CpcToken = GicCInfo->CpcToken;
+ }
+
+ if (PsdToken != NULL) {
+ *PsdToken = GicCInfo->PsdToken;
+ }
+
+ return Status;
+}
+
+/** Add arch specific information to a CPU node in the asl description.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] AcpiIdObjectToken AcpiIdObjectToken identifying the CPU to fetch the
+ other fields from.
+ @param [in] CpuName Value used to generate the CPU node name.
+ @param [out] CpuNode CPU Node to which the ET device node is
+ attached.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+ @retval EFI_UNSUPPORTED Feature Unsupported.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AddArchAmlCpuInfo (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CM_OBJECT_TOKEN AcpiIdObjectToken,
+ IN UINT32 CpuName,
+ OUT AML_OBJECT_NODE_HANDLE *CpuNode
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_GICC_INFO *GicCInfo;
+
+ Status = GetEArmObjGicCInfo (
+ CfgMgrProtocol,
+ AcpiIdObjectToken,
+ &GicCInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Add an Embedded Trace node if present.
+ if (GicCInfo->EtToken != CM_NULL_TOKEN) {
+ Status = CreateAmlEtNode (
+ Generator,
+ CfgMgrProtocol,
+ GicCInfo->AcpiProcessorUid,
+ GicCInfo->EtToken,
+ CpuName,
+ CpuNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
+
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c
index 40ed10e..3bb0c2f 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.c
@@ -32,36 +32,25 @@
#include "SsdtCpuTopologyGenerator.h"
-/** ARM standard SSDT Cpu Topology Table Generator.
+/** SSDT Cpu Topology Table Generator.
Requirements:
The following Configuration Manager Object(s) are required by
this Generator:
- - EArmObjGicCInfo
- - EArmObjProcHierarchyInfo (OPTIONAL) along with
- - EArmObjCmRef (OPTIONAL)
- - EArmObjLpiInfo (OPTIONAL)
- - GetEArmObjEtInfo (OPTIONAL)
- - EArmObjPsdInfo (OPTIONAL)
+ - EArchCommonObjProcHierarchyInfo (OPTIONAL) along with
+ - EArchCommonObjCmRef (OPTIONAL)
+ - EArchCommonObjLpiInfo (OPTIONAL)
+ - EArchCommonObjPsdInfo (OPTIONAL)
*/
-/** This macro expands to a function that retrieves the GIC
- CPU interface Information from the Configuration Manager.
-*/
-GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjGicCInfo,
- CM_ARM_GICC_INFO
- );
-
/**
This macro expands to a function that retrieves the Processor Hierarchy
information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjProcHierarchyInfo,
- CM_ARM_PROC_HIERARCHY_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjProcHierarchyInfo,
+ CM_ARCH_COMMON_PROC_HIERARCHY_INFO
);
/**
@@ -69,9 +58,9 @@ GET_OBJECT_LIST (
reference information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjCmRef,
- CM_ARM_OBJ_REF
+ EObjNameSpaceArchCommon,
+ EArchCommonObjCmRef,
+ CM_ARCH_COMMON_OBJ_REF
);
/**
@@ -79,9 +68,9 @@ GET_OBJECT_LIST (
information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjLpiInfo,
- CM_ARM_LPI_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjLpiInfo,
+ CM_ARCH_COMMON_LPI_INFO
);
/**
@@ -89,19 +78,9 @@ GET_OBJECT_LIST (
information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjCpcInfo,
- CM_ARM_CPC_INFO
- );
-
-/**
- This macro expands to a function that retrieves the ET device
- information from the Configuration Manager.
-*/
-GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjEtInfo,
- CM_ARM_ET_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjCpcInfo,
+ CM_ARCH_COMMON_CPC_INFO
);
/**
@@ -109,19 +88,19 @@ GET_OBJECT_LIST (
information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPsdInfo,
- CM_ARM_PSD_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPsdInfo,
+ CM_ARCH_COMMON_PSD_INFO
);
/** Initialize the TokenTable.
- One entry should be allocated for each CM_ARM_PROC_HIERARCHY_INFO
+ One entry should be allocated for each CM_ARCH_COMMON_PROC_HIERARCHY_INFO
structure of the platform. The TokenTable allows to have a mapping:
- Index <-> CM_OBJECT_TOKEN (to CM_ARM_LPI_INFO structures).
+ Index <-> CM_OBJECT_TOKEN (to CM_ARCH_COMMON_LPI_INFO structures).
- There will always be less sets of Lpi states (CM_ARM_OBJ_REF)
- than the number of cpus/clusters (CM_ARM_PROC_HIERARCHY_INFO).
+ There will always be less sets of Lpi states (CM_ARCH_COMMON_OBJ_REF)
+ than the number of cpus/clusters (CM_ARCH_COMMON_PROC_HIERARCHY_INFO).
@param [in] Generator The SSDT Cpu Topology generator.
@param [in] Count Number of entries to allocate in the TokenTable.
@@ -238,7 +217,6 @@ TokenTableAdd (
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER Invalid parameter.
**/
-STATIC
EFI_STATUS
EFIAPI
WriteAslName (
@@ -294,8 +272,7 @@ WriteAslName (
@param [in] Generator The SSDT Cpu Topology generator.
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
Protocol Interface.
- @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object
- describing the Cpu.
+ @param [in] PsdToken Token to identify the Psd information.
@param [in] Node CPU Node to which the _CPC node is
attached.
@@ -309,16 +286,16 @@ EFIAPI
CreateAmlPsdNode (
IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CM_ARM_GICC_INFO *GicCInfo,
+ IN CM_OBJECT_TOKEN PsdToken,
IN AML_OBJECT_NODE_HANDLE *Node
)
{
- EFI_STATUS Status;
- CM_ARM_PSD_INFO *PsdInfo;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_PSD_INFO *PsdInfo;
- Status = GetEArmObjPsdInfo (
+ Status = GetEArchCommonObjPsdInfo (
CfgMgrProtocol,
- GicCInfo->PsdToken,
+ PsdToken,
&PsdInfo,
NULL
);
@@ -381,7 +358,7 @@ CreateAmlPsdNode (
@param [in] Generator The SSDT Cpu Topology generator.
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
Protocol Interface.
- @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object
+ @param [in] CpcToken CPC token of the INTC info
describing the Cpu.
@param [in] Node CPU Node to which the _CPC node is
attached.
@@ -390,22 +367,21 @@ CreateAmlPsdNode (
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
**/
-STATIC
EFI_STATUS
EFIAPI
CreateAmlCpcNode (
IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CM_ARM_GICC_INFO *GicCInfo,
+ IN CM_OBJECT_TOKEN CpcToken,
IN AML_OBJECT_NODE_HANDLE *Node
)
{
- EFI_STATUS Status;
- CM_ARM_CPC_INFO *CpcInfo;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_CPC_INFO *CpcInfo;
- Status = GetEArmObjCpcInfo (
+ Status = GetEArchCommonObjCpcInfo (
CfgMgrProtocol,
- GicCInfo->CpcToken,
+ CpcToken,
&CpcInfo,
NULL
);
@@ -423,147 +399,6 @@ CreateAmlCpcNode (
return Status;
}
-/** Create an embedded trace device and add it to the Cpu Node in the
- AML namespace.
-
- This generates the following ASL code:
- Device (E002)
- {
- Name (_UID, 2)
- Name (_HID, "ARMHC500")
- }
-
- Note: Currently we only support generating ETE nodes. Unlike ETM,
- ETE has a system register interface and therefore does not need
- the MMIO range to be described.
-
- @param [in] Generator The SSDT Cpu Topology generator.
- @param [in] ParentNode Parent node to attach the Cpu node to.
- @param [in] GicCInfo CM_ARM_GICC_INFO object used to create the node.
- @param [in] CpuName Value used to generate the node name.
- @param [out] EtNodePtr If not NULL, return the created Cpu node.
-
- @retval EFI_SUCCESS Success.
- @retval EFI_INVALID_PARAMETER Invalid parameter.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-CreateAmlEtd (
- IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
- IN AML_NODE_HANDLE ParentNode,
- IN CM_ARM_GICC_INFO *GicCInfo,
- IN UINT32 CpuName,
- OUT AML_OBJECT_NODE_HANDLE *EtNodePtr OPTIONAL
- )
-{
- EFI_STATUS Status;
- AML_OBJECT_NODE_HANDLE EtNode;
- CHAR8 AslName[AML_NAME_SEG_SIZE + 1];
-
- ASSERT (Generator != NULL);
- ASSERT (ParentNode != NULL);
-
- Status = WriteAslName ('E', CpuName, AslName);
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- Status = AmlCodeGenDevice (AslName, ParentNode, &EtNode);
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- Status = AmlCodeGenNameInteger (
- "_UID",
- GicCInfo->AcpiProcessorUid,
- EtNode,
- NULL
- );
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- Status = AmlCodeGenNameString (
- "_HID",
- ACPI_HID_ET_DEVICE,
- EtNode,
- NULL
- );
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- // If requested, return the handle to the EtNode.
- if (EtNodePtr != NULL) {
- *EtNodePtr = EtNode;
- }
-
- return Status;
-}
-
-/** Create and add an Embedded trace device to the Cpu Node.
-
- @param [in] Generator The SSDT Cpu Topology generator.
- @param [in] CfgMgrProtocol Pointer to the Configuration Manager
- Protocol Interface.
- @param [in] GicCInfo Pointer to the CM_ARM_GICC_INFO object
- describing the Cpu.
- @param [in] CpuName Value used to generate the CPU node name.
- @param [in] Node CPU Node to which the ET device node is
- attached.
-
- @retval EFI_SUCCESS The function completed successfully.
- @retval EFI_UNSUPPORTED Feature Unsupported.
- @retval EFI_INVALID_PARAMETER Invalid parameter.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-CreateAmlEtNode (
- IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CM_ARM_GICC_INFO *GicCInfo,
- IN UINT32 CpuName,
- IN AML_OBJECT_NODE_HANDLE *Node
- )
-{
- EFI_STATUS Status;
- CM_ARM_ET_INFO *EtInfo;
-
- Status = GetEArmObjEtInfo (
- CfgMgrProtocol,
- GicCInfo->EtToken,
- &EtInfo,
- NULL
- );
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- // Currently we only support creation of a ETE Node.
- if (EtInfo->EtType != ArmEtTypeEte) {
- return EFI_UNSUPPORTED;
- }
-
- Status = CreateAmlEtd (
- Generator,
- Node,
- GicCInfo,
- CpuName,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
- return Status;
-}
-
/** Create and add an _LPI method to Cpu/Cluster Node.
For instance, transform an AML node from:
@@ -585,8 +420,8 @@ CreateAmlEtNode (
}
@param [in] Generator The SSDT Cpu Topology generator.
- @param [in] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_INFO describing
- the Cpu.
+ @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO
+ describing the Cpu.
@param [in] Node Node to which the _LPI method is
attached. Can represent a Cpu or a
Cluster.
@@ -599,9 +434,9 @@ STATIC
EFI_STATUS
EFIAPI
CreateAmlLpiMethod (
- IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
- IN CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo,
- IN AML_OBJECT_NODE_HANDLE *Node
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo,
+ IN AML_OBJECT_NODE_HANDLE *Node
)
{
EFI_STATUS Status;
@@ -696,12 +531,12 @@ GenerateLpiStates (
UINT32 Index;
UINT32 LastIndex;
- AML_OBJECT_NODE_HANDLE LpiNode;
- CM_ARM_OBJ_REF *LpiRefInfo;
- UINT32 LpiRefInfoCount;
- UINT32 LpiRefIndex;
- CM_ARM_LPI_INFO *LpiInfo;
- CHAR8 AslName[AML_NAME_SEG_SIZE + 1];
+ AML_OBJECT_NODE_HANDLE LpiNode;
+ CM_ARCH_COMMON_OBJ_REF *LpiRefInfo;
+ UINT32 LpiRefInfoCount;
+ UINT32 LpiRefIndex;
+ CM_ARCH_COMMON_LPI_INFO *LpiInfo;
+ CHAR8 AslName[AML_NAME_SEG_SIZE + 1];
ASSERT (Generator != NULL);
ASSERT (Generator->TokenTable.Table != NULL);
@@ -727,7 +562,7 @@ GenerateLpiStates (
}
// Fetch the LPI objects referenced by the token.
- Status = GetEArmObjCmRef (
+ Status = GetEArchCommonObjCmRef (
CfgMgrProtocol,
Generator->TokenTable.Table[Index],
&LpiRefInfo,
@@ -739,8 +574,9 @@ GenerateLpiStates (
}
for (LpiRefIndex = 0; LpiRefIndex < LpiRefInfoCount; LpiRefIndex++) {
- // For each CM_ARM_LPI_INFO referenced by the token, add an Lpi state.
- Status = GetEArmObjLpiInfo (
+ // For each CM_ARCH_COMMON_LPI_INFO referenced by the token,
+ // add an Lpi state.
+ Status = GetEArchCommonObjLpiInfo (
CfgMgrProtocol,
LpiRefInfo[LpiRefIndex].ReferenceToken,
&LpiInfo,
@@ -788,23 +624,22 @@ GenerateLpiStates (
Name (_HID, "ACPI0007")
}
- @param [in] Generator The SSDT Cpu Topology generator.
- @param [in] ParentNode Parent node to attach the Cpu node to.
- @param [in] GicCInfo CM_ARM_GICC_INFO object used to create the node.
- @param [in] CpuName Value used to generate the node name.
- @param [out] CpuNodePtr If not NULL, return the created Cpu node.
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] ParentNode Parent node to attach the Cpu node to.
+ @param [in] AcpiProcessorUid ACPI processor UID of the CPU.
+ @param [in] CpuName Value used to generate the node name.
+ @param [out] CpuNodePtr If not NULL, return the created Cpu node.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
**/
-STATIC
EFI_STATUS
EFIAPI
CreateAmlCpu (
IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
IN AML_NODE_HANDLE ParentNode,
- IN CM_ARM_GICC_INFO *GicCInfo,
+ IN UINT32 AcpiProcessorUid,
IN UINT32 CpuName,
OUT AML_OBJECT_NODE_HANDLE *CpuNodePtr OPTIONAL
)
@@ -815,7 +650,6 @@ CreateAmlCpu (
ASSERT (Generator != NULL);
ASSERT (ParentNode != NULL);
- ASSERT (GicCInfo != NULL);
Status = WriteAslName ('C', CpuName, AslName);
if (EFI_ERROR (Status)) {
@@ -831,7 +665,7 @@ CreateAmlCpu (
Status = AmlCodeGenNameInteger (
"_UID",
- GicCInfo->AcpiProcessorUid,
+ AcpiProcessorUid,
CpuNode,
NULL
);
@@ -859,7 +693,7 @@ CreateAmlCpu (
return Status;
}
-/** Create a Cpu in the AML namespace from a CM_ARM_PROC_HIERARCHY_INFO
+/** Create a Cpu in the AML namespace from a CM_ARCH_COMMON_PROC_HIERARCHY_INFO
CM object.
@param [in] Generator The SSDT Cpu Topology generator.
@@ -867,8 +701,8 @@ CreateAmlCpu (
Protocol Interface.
@param [in] ParentNode Parent node to attach the Cpu node to.
@param [in] CpuName Value used to generate the node name.
- @param [in] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_INFO describing
- the Cpu.
+ @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO
+ describing the Cpu.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@@ -882,38 +716,41 @@ CreateAmlCpuFromProcHierarchy (
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
IN AML_NODE_HANDLE ParentNode,
IN UINT32 CpuName,
- IN CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo
+ IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo
)
{
EFI_STATUS Status;
- CM_ARM_GICC_INFO *GicCInfo;
AML_OBJECT_NODE_HANDLE CpuNode;
+ UINT32 AcpiProcessorUid;
+ CM_OBJECT_TOKEN CpcToken;
+ CM_OBJECT_TOKEN PsdToken;
ASSERT (Generator != NULL);
ASSERT (CfgMgrProtocol != NULL);
ASSERT (ParentNode != NULL);
ASSERT (ProcHierarchyNodeInfo != NULL);
- ASSERT (ProcHierarchyNodeInfo->GicCToken != CM_NULL_TOKEN);
+ ASSERT (ProcHierarchyNodeInfo->AcpiIdObjectToken != CM_NULL_TOKEN);
- Status = GetEArmObjGicCInfo (
+ Status = GetIntCInfo (
CfgMgrProtocol,
- ProcHierarchyNodeInfo->GicCToken,
- &GicCInfo,
- NULL
+ ProcHierarchyNodeInfo->AcpiIdObjectToken,
+ &AcpiProcessorUid,
+ &CpcToken,
+ &PsdToken
);
if (EFI_ERROR (Status)) {
ASSERT (0);
return Status;
}
- Status = CreateAmlCpu (Generator, ParentNode, GicCInfo, CpuName, &CpuNode);
+ Status = CreateAmlCpu (Generator, ParentNode, AcpiProcessorUid, CpuName, &CpuNode);
if (EFI_ERROR (Status)) {
ASSERT (0);
return Status;
}
// If a set of Lpi states is associated with the
- // CM_ARM_PROC_HIERARCHY_INFO, create an _LPI method returning them.
+ // CM_ARCH_COMMON_PROC_HIERARCHY_INFO, create an _LPI method returning them.
if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) {
Status = CreateAmlLpiMethod (Generator, ProcHierarchyNodeInfo, CpuNode);
if (EFI_ERROR (Status)) {
@@ -922,8 +759,8 @@ CreateAmlCpuFromProcHierarchy (
}
}
- if (GicCInfo->PsdToken != CM_NULL_TOKEN) {
- Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode);
+ if (PsdToken != CM_NULL_TOKEN) {
+ Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, PsdToken, CpuNode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
@@ -931,28 +768,26 @@ CreateAmlCpuFromProcHierarchy (
}
// If a CPC info is associated with the
- // GicCinfo, create an _CPC method returning them.
- if (GicCInfo->CpcToken != CM_NULL_TOKEN) {
- Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode);
+ // IntcInfo, create an _CPC method returning them.
+ if (CpcToken != CM_NULL_TOKEN) {
+ Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, CpcToken, CpuNode);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
}
- // Add an Embedded Trace node if present.
- if (GicCInfo->EtToken != CM_NULL_TOKEN) {
- Status = CreateAmlEtNode (
- Generator,
- CfgMgrProtocol,
- GicCInfo,
- CpuName,
- CpuNode
- );
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
+ // Add arch specific information if necessary.
+ Status = AddArchAmlCpuInfo (
+ Generator,
+ CfgMgrProtocol,
+ ProcHierarchyNodeInfo->AcpiIdObjectToken,
+ CpuName,
+ CpuNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
}
return Status;
@@ -960,7 +795,7 @@ CreateAmlCpuFromProcHierarchy (
/** Create a Processor Container in the AML namespace.
- Any CM_ARM_PROC_HIERARCHY_INFO object with the following flags is
+ Any CM_ARCH_COMMON_PROC_HIERARCHY_INFO object with the following flags is
assumed to be a processor container:
- EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL
- EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID
@@ -978,9 +813,10 @@ CreateAmlCpuFromProcHierarchy (
Protocol Interface.
@param [in] ParentNode Parent node to attach the processor
container node to.
- @param [in] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_INFO object used
- to create the node.
- @param [in] ProcContainerIndex Index used to generate the node name.
+ @param [in] ProcHierarchyNodeInfo CM_ARCH_COMMON_PROC_HIERARCHY_INFO object
+ used to create the node.
+ @param [in] ProcContainerName Name of the processor container.
+ @param [in] ProcContainerUid Uid of the processor container.
@param [out] ProcContainerNodePtr If success, contains the created processor
container node.
@@ -995,7 +831,7 @@ CreateAmlProcessorContainer (
IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
IN AML_NODE_HANDLE ParentNode,
- IN CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo,
+ IN CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeInfo,
IN UINT16 ProcContainerName,
IN UINT32 ProcContainerUid,
OUT AML_OBJECT_NODE_HANDLE *ProcContainerNodePtr
@@ -1048,7 +884,7 @@ CreateAmlProcessorContainer (
}
// If a set of Lpi states are associated with the
- // CM_ARM_PROC_HIERARCHY_INFO, create an _LPI method returning them.
+ // CM_ARCH_COMMON_PROC_HIERARCHY_INFO, create an _LPI method returning them.
if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) {
Status = CreateAmlLpiMethod (
Generator,
@@ -1126,8 +962,7 @@ CheckProcNode (
@param [in] Generator The SSDT Cpu Topology generator.
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
Protocol Interface.
- @param [in] NodeToken Token of the CM_ARM_PROC_HIERARCHY_INFO
- currently handled.
+ @param [in] NodeToken Token of the CM_ARCH_COMMON_PROC_HIERARCHY_INFO currently handled.
@param [in] ParentNode Parent node to attach the created
node to.
@param [in,out] ProcContainerIndex Pointer to the current processor container
@@ -1170,12 +1005,12 @@ CreateAmlCpuTopologyTree (
ProcContainerName = 0;
for (Index = 0; Index < Generator->ProcNodeCount; Index++) {
- // Find the children of the CM_ARM_PROC_HIERARCHY_INFO
+ // Find the children of the CM_ARCH_COMMON_PROC_HIERARCHY_INFO
// currently being handled (i.e. ParentToken == NodeToken).
if (Generator->ProcNodeList[Index].ParentToken == NodeToken) {
- // Only Cpus (leaf nodes in this tree) have a GicCToken.
+ // Only Cpus (leaf nodes in this tree) have a AcpiIdObjectToken.
// Create a Cpu node.
- if (Generator->ProcNodeList[Index].GicCToken != CM_NULL_TOKEN) {
+ if (Generator->ProcNodeList[Index].AcpiIdObjectToken != CM_NULL_TOKEN) {
Status = CheckProcNode (
Generator->ProcNodeList[Index].Flags,
TRUE,
@@ -1191,7 +1026,8 @@ CreateAmlCpuTopologyTree (
if (Generator->ProcNodeList[Index].OverrideNameUidEnabled) {
Name = Generator->ProcNodeList[Index].OverrideName;
} else {
- Name = CpuIndex;
+ ASSERT ((CpuIndex & ~MAX_UINT16) == 0);
+ Name = (UINT16)CpuIndex;
}
Status = CreateAmlCpuFromProcHierarchy (
@@ -1226,7 +1062,8 @@ CreateAmlCpuTopologyTree (
Name = Generator->ProcNodeList[Index].OverrideName;
Uid = Generator->ProcNodeList[Index].OverrideUid;
} else {
- Name = ProcContainerName;
+ ASSERT ((ProcContainerName & ~MAX_UINT16) == 0);
+ Name = (UINT16)ProcContainerName;
Uid = *ProcContainerIndex;
}
@@ -1279,8 +1116,8 @@ CreateAmlCpuTopologyTree (
return EFI_SUCCESS;
}
-/** Create the processor hierarchy AML tree from CM_ARM_PROC_HIERARCHY_INFO
- CM objects.
+/** Create the processor hierarchy AML tree from
+ CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects.
@param [in] Generator The SSDT Cpu Topology generator.
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
@@ -1341,100 +1178,6 @@ exit_handler:
return Status;
}
-/** Create the processor hierarchy AML tree from CM_ARM_GICC_INFO
- CM objects.
-
- A processor container is by extension any non-leave device in the cpu topology.
-
- @param [in] Generator The SSDT Cpu Topology generator.
- @param [in] CfgMgrProtocol Pointer to the Configuration Manager
- Protocol Interface.
- @param [in] ScopeNode Scope node handle ('\_SB' scope).
-
- @retval EFI_SUCCESS Success.
- @retval EFI_INVALID_PARAMETER Invalid parameter.
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-CreateTopologyFromGicC (
- IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
- IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN AML_OBJECT_NODE_HANDLE ScopeNode
- )
-{
- EFI_STATUS Status;
- CM_ARM_GICC_INFO *GicCInfo;
- UINT32 GicCInfoCount;
- UINT32 Index;
- AML_OBJECT_NODE_HANDLE CpuNode;
-
- ASSERT (Generator != NULL);
- ASSERT (CfgMgrProtocol != NULL);
- ASSERT (ScopeNode != NULL);
-
- Status = GetEArmObjGicCInfo (
- CfgMgrProtocol,
- CM_NULL_TOKEN,
- &GicCInfo,
- &GicCInfoCount
- );
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
- // For each CM_ARM_GICC_INFO object, create an AML node.
- for (Index = 0; Index < GicCInfoCount; Index++) {
- Status = CreateAmlCpu (
- Generator,
- ScopeNode,
- &GicCInfo[Index],
- Index,
- &CpuNode
- );
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- break;
- }
-
- if (GicCInfo->PsdToken != CM_NULL_TOKEN) {
- Status = CreateAmlPsdNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- }
-
- // If a CPC info is associated with the
- // GicCinfo, create an _CPC method returning them.
- if (GicCInfo[Index].CpcToken != CM_NULL_TOKEN) {
- Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, &GicCInfo[Index], CpuNode);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- break;
- }
- }
-
- if (GicCInfo[Index].EtToken != CM_NULL_TOKEN) {
- Status = CreateAmlEtNode (
- Generator,
- CfgMgrProtocol,
- &GicCInfo[Index],
- Index,
- CpuNode
- );
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- }
- } // for
-
- return Status;
-}
-
/** Construct the SSDT Cpu Topology ACPI table.
This function invokes the Configuration Manager protocol interface
@@ -1467,12 +1210,12 @@ BuildSsdtCpuTopologyTable (
OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
)
{
- EFI_STATUS Status;
- AML_ROOT_NODE_HANDLE RootNode;
- AML_OBJECT_NODE_HANDLE ScopeNode;
- CM_ARM_PROC_HIERARCHY_INFO *ProcHierarchyNodeList;
- UINT32 ProcHierarchyNodeCount;
- ACPI_CPU_TOPOLOGY_GENERATOR *Generator;
+ EFI_STATUS Status;
+ AML_ROOT_NODE_HANDLE RootNode;
+ AML_OBJECT_NODE_HANDLE ScopeNode;
+ CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcHierarchyNodeList;
+ UINT32 ProcHierarchyNodeCount;
+ ACPI_CPU_TOPOLOGY_GENERATOR *Generator;
ASSERT (This != NULL);
ASSERT (AcpiTableInfo != NULL);
@@ -1500,7 +1243,7 @@ BuildSsdtCpuTopologyTable (
// Get the processor hierarchy info and update the processor topology
// structure count with Processor Hierarchy Nodes (Type 0)
- Status = GetEArmObjProcHierarchyInfo (
+ Status = GetEArchCommonObjProcHierarchyInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&ProcHierarchyNodeList,
@@ -1513,9 +1256,8 @@ BuildSsdtCpuTopologyTable (
}
if (Status == EFI_NOT_FOUND) {
- // If hierarchy information is not found generate a flat topology
- // using CM_ARM_GICC_INFO objects.
- Status = CreateTopologyFromGicC (
+ // If hierarchy information is not found generate a flat topology.
+ Status = CreateTopologyFromIntC (
Generator,
CfgMgrProtocol,
ScopeNode
@@ -1524,7 +1266,7 @@ BuildSsdtCpuTopologyTable (
goto exit_handler;
}
} else {
- // Generate the topology from CM_ARM_PROC_HIERARCHY_INFO objects.
+ // Generate the topology from CM_ARCH_COMMON_PROC_HIERARCHY_INFO objects.
Generator->ProcNodeList = ProcHierarchyNodeList;
Generator->ProcNodeCount = ProcHierarchyNodeCount;
@@ -1571,6 +1313,7 @@ exit_handler:
**/
STATIC
EFI_STATUS
+EFIAPI
FreeSsdtCpuTopologyTableResources (
IN CONST ACPI_TABLE_GENERATOR *CONST This,
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
@@ -1616,7 +1359,7 @@ ACPI_CPU_TOPOLOGY_GENERATOR SsdtCpuTopologyGenerator = {
// Minimum ACPI Table Revision - Unused
0,
// Creator ID
- TABLE_GENERATOR_CREATOR_ID_ARM,
+ TABLE_GENERATOR_CREATOR_ID,
// Creator Revision
SSDT_CPU_TOPOLOGY_GENERATOR_REVISION,
// Build Table function
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h
new file mode 100644
index 0000000..a5d8017
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyGenerator.h
@@ -0,0 +1,343 @@
+/** @file
+ SSDT Cpu Topology Table Generator.
+
+ Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.3 Specification - January 2019 - s8.4 Declaring Processors
+ - ACPI for CoreSight version 1.2 Platform Design Document
+ (https://developer.arm.com/documentation/den0067/a/?lang=en)
+
+ @par Glossary:
+ - ETE - Embedded Trace Extension.
+ - ETM - Embedded Trace Macrocell.
+**/
+
+#ifndef SSDT_CPU_TOPOLOGY_GENERATOR_H_
+#define SSDT_CPU_TOPOLOGY_GENERATOR_H_
+
+#pragma pack(1)
+
+// Mask for the flags that need to be checked.
+#define PPTT_PROCESSOR_MASK ( \
+ (EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL) | \
+ (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \
+ (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3))
+
+// Mask for the cpu flags.
+#define PPTT_CPU_PROCESSOR_MASK ( \
+ (EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL) | \
+ (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \
+ (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3))
+
+// Mask for the cluster flags.
+// Even though a _UID is generated for clusters, it is simpler to use
+// EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID and to not match the cluster id of
+// the PPTT table (not sure the PPTT table is generated).
+#define PPTT_CLUSTER_PROCESSOR_MASK ( \
+ (EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL) | \
+ (EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID << 1) | \
+ (EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF << 3))
+
+// Leaf nodes specific mask.
+#define PPTT_LEAF_MASK ((EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID << 1) | \
+ (EFI_ACPI_6_3_PPTT_NODE_IS_LEAF << 3))
+
+/** LPI states are stored in the ASL namespace at '\_SB_.Lxxx',
+ with xxx being the node index of the LPI state.
+*/
+#define SB_SCOPE "\\_SB_"
+#define SB_SCOPE_PREFIX SB_SCOPE "."
+/// Size of the SB_SCOPE_PREFIX string.
+#define SB_SCOPE_PREFIX_SIZE sizeof (SB_SCOPE_PREFIX)
+
+/// HID for a processor device.
+#define ACPI_HID_PROCESSOR_DEVICE "ACPI0007"
+
+/// HID for a ETM/ETE device.
+#define ACPI_HID_ET_DEVICE "ARMHC500"
+
+/// HID for a processor container device.
+#define ACPI_HID_PROCESSOR_CONTAINER_DEVICE "ACPI0010"
+
+/** Node names of Cpus and Clusters are 'Cxxx', and 'Lxxx' for LPI states.
+ The 'xxx' is an index on 12 bits is given to node name,
+ thus the limitation in the number of nodes.
+*/
+#define MAX_NODE_COUNT (1 << 12)
+
+/** A structure used to handle the Lpi structures referencing.
+
+ A CM_ARCH_COMMON_PROC_HIERARCHY_INFO structure references a CM_ARCH_COMMON_OBJ_REF.
+ This CM_ARCH_COMMON_OBJ_REF references CM_ARCH_COMMON_LPI_INFO structures.
+
+ Example:
+ (Cpu0) (Cpu1)
+ CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM_ARCH_COMMON_PROC_HIERARCHY_INFO
+ | |
+ +----------------------------------------
+ |
+ v
+ (List of references to Lpi states)
+ CM_ARCH_COMMON_OBJ_REF
+ |
+ +----------------------------------------
+ | |
+ v v
+ (A first Lpi state) (A second Lpi state)
+ CM_ARCH_COMMON_LPI_INFO[0] CM_ARCH_COMMON_LPI_INFO[1]
+
+ Here, Cpu0 and Cpu1 have the same Lpi states. Both CM_ARCH_COMMON_PROC_HIERARCHY_INFO
+ structures reference the same CM_ARCH_COMMON_OBJ_REF. An entry is created in the
+ TokenTable such as:
+ 0 <-> CM_ARCH_COMMON_OBJ_REF
+
+ This will lead to the creation of this pseudo-ASL code where Cpu0 and Cpu1
+ return the same object at \_SB.L000:
+ Scope (\_SB) {
+ Device (C000) {
+ [...]
+ Method (_LPI) {
+ Return (\_SB.L000)
+ }
+ } // C000
+
+ Device (C001) {
+ [...]
+ Method (_LPI) {
+ Return (\_SB.L000)
+ }
+ } // C001
+
+ // Lpi states
+ Name (L000, Package (0x05) {
+ [...]
+ }
+ }
+*/
+typedef struct TokenTable {
+ /// TokenTable, a table allowing to map:
+ /// Index <-> CM_OBJECT_TOKEN (to CM_ARCH_COMMON_LPI_INFO structures).
+ CM_OBJECT_TOKEN *Table;
+
+ /// Last used index of the TokenTable.
+ /// LastIndex is bound by ProcNodeCount.
+ UINT32 LastIndex;
+} TOKEN_TABLE;
+
+/** A structure holding the Cpu topology generator and additional private data.
+*/
+typedef struct AcpiCpuTopologyGenerator {
+ /// ACPI Table generator header
+ ACPI_TABLE_GENERATOR Header;
+
+ // Private fields are defined from here.
+
+ /// Private object used to handle token referencing.
+ TOKEN_TABLE TokenTable;
+ /// List of CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects.
+ CM_ARCH_COMMON_PROC_HIERARCHY_INFO *ProcNodeList;
+ /// Count of CM_ARCH_COMMON_PROC_HIERARCHY_INFO CM objects.
+ UINT32 ProcNodeCount;
+} ACPI_CPU_TOPOLOGY_GENERATOR;
+
+#pragma pack()
+
+/** Write a string 'Xxxx\0' in AslName (5 bytes long),
+ with 'X' being the leading char of the name, and
+ with 'xxx' being Value in hexadecimal.
+
+ As 'xxx' in hexadecimal represents a number on 12 bits,
+ we have Value < (1 << 12).
+
+ @param [in] LeadChar Leading char of the name.
+ @param [in] Value Hex value of the name.
+ Must be lower than (2 << 12).
+ @param [in, out] AslName Pointer to write the 'Xxxx' string to.
+ Must be at least 5 bytes long.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+WriteAslName (
+ IN CHAR8 LeadChar,
+ IN UINT32 Value,
+ IN OUT CHAR8 *AslName
+ );
+
+/** Get generic interrupt information from arch specific CM objects.
+
+ The AcpiProcessorUid, CpcToken, etc. are held in arch specific CM objects,
+ in the CM_ARM_GICC_INFO CM object for Arm for instance.
+ This wrapper allows to get this information from each arch object.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] AcpiProcessorUid ACPI processor Uid of the local intc (gicc, other)
+ other fields from.
+ @param [out] AcpiProcessorUid AcpiProcessorUid of the CPU identified by
+ the AcpiIdObjectToken.
+ @param [out] CpcToken CpcToken of the CPU identified by
+ the AcpiIdObjectToken.
+ @param [out] PsdToken PsdToken of the CPU identified by
+ the AcpiIdObjectToken.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+**/
+EFI_STATUS
+EFIAPI
+GetIntCInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CM_OBJECT_TOKEN AcpiIdObjectToken,
+ OUT UINT32 *AcpiProcessorUid,
+ OUT CM_OBJECT_TOKEN *CpcToken,
+ OUT CM_OBJECT_TOKEN *PsdToken
+ );
+
+/** Create and add an _CPC Node to Cpu Node.
+
+ For instance, transform an AML node from:
+ Device (C002)
+ {
+ Name (_UID, 2)
+ Name (_HID, "ACPI0007")
+ }
+
+ To:
+ Device (C002)
+ {
+ Name (_UID, 2)
+ Name (_HID, "ACPI0007")
+ Name(_CPC, Package()
+ {
+ NumEntries, // Integer
+ Revision, // Integer
+ HighestPerformance, // Integer or Buffer (Resource Descriptor)
+ NominalPerformance, // Integer or Buffer (Resource Descriptor)
+ LowestNonlinearPerformance, // Integer or Buffer (Resource Descriptor)
+ LowestPerformance, // Integer or Buffer (Resource Descriptor)
+ GuaranteedPerformanceRegister, // Buffer (Resource Descriptor)
+ DesiredPerformanceRegister , // Buffer (Resource Descriptor)
+ MinimumPerformanceRegister , // Buffer (Resource Descriptor)
+ MaximumPerformanceRegister , // Buffer (Resource Descriptor)
+ PerformanceReductionToleranceRegister, // Buffer (Resource Descriptor)
+ TimeWindowRegister, // Buffer (Resource Descriptor)
+ CounterWraparoundTime, // Integer or Buffer (Resource Descriptor)
+ ReferencePerformanceCounterRegister, // Buffer (Resource Descriptor)
+ DeliveredPerformanceCounterRegister, // Buffer (Resource Descriptor)
+ PerformanceLimitedRegister, // Buffer (Resource Descriptor)
+ CPPCEnableRegister // Buffer (Resource Descriptor)
+ AutonomousSelectionEnable, // Integer or Buffer (Resource Descriptor)
+ AutonomousActivityWindowRegister, // Buffer (Resource Descriptor)
+ EnergyPerformancePreferenceRegister, // Buffer (Resource Descriptor)
+ ReferencePerformance // Integer or Buffer (Resource Descriptor)
+ LowestFrequency, // Integer or Buffer (Resource Descriptor)
+ NominalFrequency // Integer or Buffer (Resource Descriptor)
+ })
+ }
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] CpcToken CPC token of the INTC info
+ describing the Cpu.
+ @param [in] Node CPU Node to which the _CPC node is
+ attached.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+CreateAmlCpcNode (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CM_OBJECT_TOKEN CpcToken,
+ IN AML_OBJECT_NODE_HANDLE *Node
+ );
+
+/** Create a Cpu in the AML namespace.
+
+ This generates the following ASL code:
+ Device (C002)
+ {
+ Name (_UID, 2)
+ Name (_HID, "ACPI0007")
+ }
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] ParentNode Parent node to attach the Cpu node to.
+ @param [in] AcpiProcessorUid ACPI processor UID of the CPU.
+ @param [in] CpuName Value used to generate the node name.
+ @param [out] CpuNodePtr If not NULL, return the created Cpu node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+CreateAmlCpu (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN AML_NODE_HANDLE ParentNode,
+ IN UINT32 AcpiProcessorUid,
+ IN UINT32 CpuName,
+ OUT AML_OBJECT_NODE_HANDLE *CpuNodePtr OPTIONAL
+ );
+
+/** Create the processor hierarchy AML tree from arch specific CM objects.
+
+ The Arm architecture will use the CM_ARM_GICC_INFO CM objects for instance.
+ A processor container is by extension any non-leave device in the cpu topology.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] ScopeNode Scope node handle ('\_SB' scope).
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+CreateTopologyFromIntC (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN AML_OBJECT_NODE_HANDLE ScopeNode
+ );
+
+/** Add arch specific information to a CPU node in the asl description.
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] AcpiIdObjectToken AcpiIdObjectToken identifying the CPU to fetch the
+ other fields from.
+ @param [in] CpuName Value used to generate the CPU node name.
+ @param [out] CpuNode CPU Node to which the ET device node is
+ attached.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+ @retval EFI_UNSUPPORTED Feature Unsupported.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AddArchAmlCpuInfo (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CM_OBJECT_TOKEN AcpiIdObjectToken,
+ IN UINT32 CpuName,
+ OUT AML_OBJECT_NODE_HANDLE *CpuNode
+ );
+
+#endif // SSDT_CPU_TOPOLOGY_GENERATOR_H_
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf
index 3e2d154..93ede69 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyLibArm.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtCpuTopologyLib/SsdtCpuTopologyLib.inf
@@ -8,7 +8,7 @@
[Defines]
INF_VERSION = 0x0001001B
- BASE_NAME = SsdtCpuTopologyLibArm
+ BASE_NAME = SsdtCpuTopologyLib
FILE_GUID = F2835EB6-4B05-48D4-A475-147DA0F3755C
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
@@ -20,11 +20,16 @@
SsdtCpuTopologyGenerator.c
SsdtCpuTopologyGenerator.h
+[Sources.ARM, Sources.AARCH64]
+ Arm/ArmSsdtCpuTopologyGenerator.c
+
+[Packages.ARM, Packages.AARCH64]
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
DynamicTablesPkg/DynamicTablesPkg.dec
[LibraryClasses]
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c
index 7287370..7fe780d 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.c
@@ -42,46 +42,46 @@
Requirements:
The following Configuration Manager Object(s) are required by
this Generator:
- - EArmObjCmRef
- - EArmObjPciConfigSpaceInfo
- - EArmObjPciAddressMapInfo
- - EArmObjPciInterruptMapInfo
+ - EArchCommonObjCmRef
+ - EArchCommonObjPciConfigSpaceInfo
+ - EArchCommonObjPciAddressMapInfo
+ - EArchCommonObjPciInterruptMapInfo
*/
/** This macro expands to a function that retrieves the cross-CM-object-
reference information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjCmRef,
- CM_ARM_OBJ_REF
+ EObjNameSpaceArchCommon,
+ EArchCommonObjCmRef,
+ CM_ARCH_COMMON_OBJ_REF
);
/** This macro expands to a function that retrieves the Pci
Configuration Space Information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPciConfigSpaceInfo,
- CM_ARM_PCI_CONFIG_SPACE_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPciConfigSpaceInfo,
+ CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO
);
/** This macro expands to a function that retrieves the Pci
Address Mapping Information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPciAddressMapInfo,
- CM_ARM_PCI_ADDRESS_MAP_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPciAddressMapInfo,
+ CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO
);
/** This macro expands to a function that retrieves the Pci
Interrupt Mapping Information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjPciInterruptMapInfo,
- CM_ARM_PCI_INTERRUPT_MAP_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjPciInterruptMapInfo,
+ CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO
);
/** Initialize the MappingTable.
@@ -208,9 +208,9 @@ STATIC
EFI_STATUS
EFIAPI
GeneratePciDeviceInfo (
- IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,
- IN UINT32 Uid,
- IN OUT AML_OBJECT_NODE_HANDLE PciNode
+ IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo,
+ IN UINT32 Uid,
+ IN OUT AML_OBJECT_NODE_HANDLE PciNode
)
{
EFI_STATUS Status;
@@ -305,17 +305,17 @@ EFIAPI
GeneratePrt (
IN ACPI_PCI_GENERATOR *Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,
+ IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo,
IN UINT32 Uid,
IN OUT AML_OBJECT_NODE_HANDLE PciNode
)
{
- EFI_STATUS Status;
- INT32 Index;
- AML_OBJECT_NODE_HANDLE PrtNode;
- CM_ARM_OBJ_REF *RefInfo;
- UINT32 RefCount;
- CM_ARM_PCI_INTERRUPT_MAP_INFO *IrqMapInfo;
+ EFI_STATUS Status;
+ UINT32 Index;
+ AML_OBJECT_NODE_HANDLE PrtNode;
+ CM_ARCH_COMMON_OBJ_REF *RefInfo;
+ UINT32 RefCount;
+ CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO *IrqMapInfo;
ASSERT (Generator != NULL);
ASSERT (CfgMgrProtocol != NULL);
@@ -324,9 +324,9 @@ GeneratePrt (
PrtNode = NULL;
- // Get the array of CM_ARM_OBJ_REF referencing the
- // CM_ARM_PCI_INTERRUPT_MAP_INFO objects.
- Status = GetEArmObjCmRef (
+ // Get the array of CM_ARCH_COMMON_OBJ_REF referencing the
+ // CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO objects.
+ Status = GetEArchCommonObjCmRef (
CfgMgrProtocol,
PciInfo->InterruptMapToken,
&RefInfo,
@@ -352,8 +352,8 @@ GeneratePrt (
}
for (Index = 0; Index < RefCount; Index++) {
- // Get CM_ARM_PCI_INTERRUPT_MAP_INFO structures one by one.
- Status = GetEArmObjPciInterruptMapInfo (
+ // Get CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO structures one by one.
+ Status = GetEArchCommonObjPciInterruptMapInfo (
CfgMgrProtocol,
RefInfo[Index].ReferenceToken,
&IrqMapInfo,
@@ -451,18 +451,18 @@ EFIAPI
GeneratePciCrs (
IN ACPI_PCI_GENERATOR *Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,
+ IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo,
IN OUT AML_OBJECT_NODE_HANDLE PciNode
)
{
- EFI_STATUS Status;
- BOOLEAN Translation;
- UINT32 Index;
- CM_ARM_OBJ_REF *RefInfo;
- UINT32 RefCount;
- CM_ARM_PCI_ADDRESS_MAP_INFO *AddrMapInfo;
- AML_OBJECT_NODE_HANDLE CrsNode;
- BOOLEAN IsPosDecode;
+ EFI_STATUS Status;
+ BOOLEAN Translation;
+ UINT32 Index;
+ CM_ARCH_COMMON_OBJ_REF *RefInfo;
+ UINT32 RefCount;
+ CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO *AddrMapInfo;
+ AML_OBJECT_NODE_HANDLE CrsNode;
+ BOOLEAN IsPosDecode;
ASSERT (Generator != NULL);
ASSERT (CfgMgrProtocol != NULL);
@@ -505,9 +505,9 @@ GeneratePciCrs (
return Status;
}
- // Get the array of CM_ARM_OBJ_REF referencing the
- // CM_ARM_PCI_ADDRESS_MAP_INFO objects.
- Status = GetEArmObjCmRef (
+ // Get the array of CM_ARCH_COMMON_OBJ_REF referencing the
+ // CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO objects.
+ Status = GetEArchCommonObjCmRef (
CfgMgrProtocol,
PciInfo->AddressMapToken,
&RefInfo,
@@ -519,8 +519,8 @@ GeneratePciCrs (
}
for (Index = 0; Index < RefCount; Index++) {
- // Get CM_ARM_PCI_ADDRESS_MAP_INFO structures one by one.
- Status = GetEArmObjPciAddressMapInfo (
+ // Get CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO structures one by one.
+ Status = GetEArchCommonObjPciAddressMapInfo (
CfgMgrProtocol,
RefInfo[Index].ReferenceToken,
&AddrMapInfo,
@@ -561,6 +561,11 @@ GeneratePciCrs (
break;
case PCI_SS_M32:
+ ASSERT ((AddrMapInfo->PciAddress & ~MAX_UINT32) == 0);
+ ASSERT (((AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1) & ~MAX_UINT32) == 0);
+ ASSERT (((Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0) & ~MAX_UINT32) == 0);
+ ASSERT ((AddrMapInfo->AddressSize & ~MAX_UINT32) == 0);
+
Status = AmlCodeGenRdDWordMemory (
FALSE,
IsPosDecode,
@@ -569,10 +574,10 @@ GeneratePciCrs (
AmlMemoryCacheable,
TRUE,
0,
- AddrMapInfo->PciAddress,
- AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1,
- Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0,
- AddrMapInfo->AddressSize,
+ (UINT32)(AddrMapInfo->PciAddress),
+ (UINT32)(AddrMapInfo->PciAddress + AddrMapInfo->AddressSize - 1),
+ (UINT32)(Translation ? AddrMapInfo->CpuAddress - AddrMapInfo->PciAddress : 0),
+ (UINT32)(AddrMapInfo->AddressSize),
0,
NULL,
AmlAddressRangeMemory,
@@ -693,7 +698,7 @@ EFIAPI
ReserveEcamSpace (
IN ACPI_PCI_GENERATOR *Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,
+ IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo,
IN OUT AML_OBJECT_NODE_HANDLE PciNode
)
{
@@ -760,7 +765,7 @@ EFIAPI
GeneratePciDevice (
IN ACPI_PCI_GENERATOR *Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
- IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,
+ IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo,
IN UINT32 Uid,
IN OUT AML_ROOT_NODE_HANDLE *RootNode
)
@@ -863,7 +868,7 @@ BuildSsdtPciTable (
IN ACPI_PCI_GENERATOR *Generator,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
- IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,
+ IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo,
IN UINT32 Uid,
OUT EFI_ACPI_DESCRIPTION_HEADER **Table
)
@@ -971,13 +976,13 @@ BuildSsdtPciTableEx (
OUT UINTN *CONST TableCount
)
{
- EFI_STATUS Status;
- CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo;
- UINT32 PciCount;
- UINTN Index;
- EFI_ACPI_DESCRIPTION_HEADER **TableList;
- ACPI_PCI_GENERATOR *Generator;
- UINT32 Uid;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo;
+ UINT32 PciCount;
+ UINT32 Index;
+ EFI_ACPI_DESCRIPTION_HEADER **TableList;
+ ACPI_PCI_GENERATOR *Generator;
+ UINT32 Uid;
ASSERT (This != NULL);
ASSERT (AcpiTableInfo != NULL);
@@ -990,7 +995,7 @@ BuildSsdtPciTableEx (
*TableCount = 0;
Generator = (ACPI_PCI_GENERATOR *)This;
- Status = GetEArmObjPciConfigSpaceInfo (
+ Status = GetEArchCommonObjPciConfigSpaceInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&PciInfo,
@@ -1163,7 +1168,7 @@ ACPI_PCI_GENERATOR SsdtPcieGenerator = {
// Minimum ACPI Table Revision - Unused
0,
// Creator ID
- TABLE_GENERATOR_CREATOR_ID_ARM,
+ TABLE_GENERATOR_CREATOR_ID,
// Creator Revision
SSDT_PCI_GENERATOR_REVISION,
// Build table function. Use the extended version instead.
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.h
index 7410f9f..7410f9f 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieGenerator.h
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieGenerator.h
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf
index c2a1acb..440b0d7 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtPcieLibArm/SsdtPcieLibArm.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtPcieLib/SsdtPcieLib.inf
@@ -8,7 +8,7 @@
[Defines]
INF_VERSION = 0x0001001B
- BASE_NAME = SsdtPcieLibArm
+ BASE_NAME = SsdtPcieLib
FILE_GUID = E431D7FD-26BF-4E3D-9064-5B13B0439057
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c
index b850320..bbd8b65 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortGenerator.c
@@ -29,16 +29,16 @@
Requirements:
The following Configuration Manager Object(s) are required by
this Generator:
- - EArmObjSerialPortInfo
+ - EArchCommonObjSerialPortInfo
*/
/** This macro expands to a function that retrieves the Serial-port
information from the Configuration Manager.
*/
GET_OBJECT_LIST (
- EObjNameSpaceArm,
- EArmObjSerialPortInfo,
- CM_ARM_SERIAL_PORT_INFO
+ EObjNameSpaceArchCommon,
+ EArchCommonObjSerialPortInfo,
+ CM_ARCH_COMMON_SERIAL_PORT_INFO
);
/** Starting value for the UID to represent the serial ports.
@@ -167,13 +167,13 @@ BuildSsdtSerialPortTableEx (
OUT UINTN *CONST TableCount
)
{
- EFI_STATUS Status;
- CM_ARM_SERIAL_PORT_INFO *SerialPortInfo;
- UINT32 SerialPortCount;
- UINTN Index;
- CHAR8 NewName[AML_NAME_SEG_SIZE + 1];
- UINT64 Uid;
- EFI_ACPI_DESCRIPTION_HEADER **TableList;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo;
+ UINT32 SerialPortCount;
+ UINTN Index;
+ CHAR8 NewName[AML_NAME_SEG_SIZE + 1];
+ UINT64 Uid;
+ EFI_ACPI_DESCRIPTION_HEADER **TableList;
ASSERT (This != NULL);
ASSERT (AcpiTableInfo != NULL);
@@ -185,7 +185,7 @@ BuildSsdtSerialPortTableEx (
*Table = NULL;
- Status = GetEArmObjSerialPortInfo (
+ Status = GetEArchCommonObjSerialPortInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&SerialPortInfo,
@@ -301,7 +301,7 @@ ACPI_TABLE_GENERATOR SsdtSerialPortGenerator = {
// Minimum ACPI Table Revision - Unused
0,
// Creator ID
- TABLE_GENERATOR_CREATOR_ID_ARM,
+ TABLE_GENERATOR_CREATOR_ID,
// Creator Revision
SSDT_SERIAL_GENERATOR_REVISION,
// Build table function. Use the extended version instead.
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf
index 36e61ea..24d7db5 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf
@@ -8,7 +8,7 @@
[Defines]
INF_VERSION = 0x0001001B
- BASE_NAME = SsdtSerialPortLibArm
+ BASE_NAME = SsdtSerialPortLib
FILE_GUID = D1F92325-2DFB-435C-9B4C-A6B864F19230
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
@@ -19,11 +19,13 @@
[Sources]
SsdtSerialPortGenerator.c
+[Packages.ARM, Packages.AARCH64]
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
DynamicTablesPkg/DynamicTablesPkg.dec
[LibraryClasses]
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf
new file mode 100644
index 0000000..ee50fc6
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf
@@ -0,0 +1,29 @@
+## @file
+# TPM2 Table Generator
+#
+# Copyright (c) 2022, ARM Limited. All rights reserved.
+# Copyright (c) 2023 - 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = AcpiTpm2Lib
+ FILE_GUID = 968fa07a-9076-11ed-8041-9bd740d3d45d
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = NULL|DXE_DRIVER
+ CONSTRUCTOR = AcpiTpm2LibConstructor
+ DESTRUCTOR = AcpiTpm2LibDestructor
+
+[Sources]
+ Tpm2Generator.c
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ DynamicTablesPkg/DynamicTablesPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c
new file mode 100644
index 0000000..7255c93
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c
@@ -0,0 +1,405 @@
+/** @file
+ TPM2 Table Generator
+
+ Copyright (c) 2022, ARM Limited. All rights reserved.
+ Copyright (c) 2023 - 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - TCG ACPI Specification Family for TPM 1.2 and 2.0 Version 1.3 Revision 8'
+ (https://trustedcomputinggroup.org/wp-content/uploads/TCG_ACPIGeneralSpec_v1p3_r8_pub.pdf)
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#include <IndustryStandard/Tpm2Acpi.h>
+
+#define START_METHOD_ACPI_PARAM_SIZE_MIN 4
+#define START_METHOD_CRB_WITH_SMC_PARAM_SIZE 12
+
+/**
+ ARM standard TPM2 Generator
+
+ Requirements:
+ The following Configuration Manager Object(s) are used by this Generator:
+ - EArchCommonObjTpm2InterfaceInfo
+*/
+
+/**
+ This macro expands to a function that retrieves the Processor Hierarchy
+ information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArchCommon,
+ EArchCommonObjTpm2InterfaceInfo,
+ CM_ARCH_COMMON_TPM2_INTERFACE_INFO
+ );
+
+/**
+ Sanity check Start Method Specific Parameters field
+
+ @param [in] TpmInfo Pointer to the CM TPM2 object
+
+ @retval EFI_SUCCESS No failure
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+AcpiTpm2CheckStartMethodParameters (
+ CM_ARCH_COMMON_TPM2_INTERFACE_INFO *TpmInfo
+ )
+{
+ ASSERT (TpmInfo != NULL);
+
+ if (sizeof (TpmInfo->StartMethodParameters) < TpmInfo->StartMethodParametersSize) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // LAML and LASA are either both set or both zeros
+ if (((TpmInfo->Laml > 0) && (TpmInfo->Lasa == 0)) ||
+ ((TpmInfo->Laml == 0) && (TpmInfo->Lasa != 0)))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Verify StartMethodParametersSize based on StartMethod
+ switch (TpmInfo->StartMethod) {
+ case EFI_TPM2_ACPI_TABLE_START_METHOD_ACPI:
+ // If the Start Method value is 2, then this field is at least four
+ // bytes in size and the first four bytes must be all zero.
+ if (TpmInfo->StartMethodParametersSize < START_METHOD_ACPI_PARAM_SIZE_MIN) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((UINT32 *)TpmInfo->StartMethodParameters)[0] != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ break;
+
+ case EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_SMC:
+ // If the Start Method value is 11 then this field is 12 bytes in size
+ if (TpmInfo->StartMethodParametersSize != START_METHOD_CRB_WITH_SMC_PARAM_SIZE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ break;
+
+ case EFI_TPM2_ACPI_TABLE_START_METHOD_TIS:
+ case EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE:
+ case EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_ACPI:
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Construct the TPM2 ACPI table.
+
+ Called by the Dynamic Table Manager, this function invokes the
+ Configuration Manager protocol interface to get the required hardware
+ information for generating the ACPI table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeTpm2TableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildTpm2Table (
+ IN CONST ACPI_TABLE_GENERATOR *CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TableSize;
+ CM_ARCH_COMMON_TPM2_INTERFACE_INFO *TpmInfo;
+ EFI_TPM2_ACPI_TABLE *Tpm2;
+ UINT32 *Laml;
+ UINT64 *Lasa;
+
+ *Table = NULL;
+
+ ASSERT (
+ (This != NULL) &&
+ (AcpiTableInfo != NULL) &&
+ (CfgMgrProtocol != NULL) &&
+ (Table != NULL) &&
+ (AcpiTableInfo->TableGeneratorId == This->GeneratorID) &&
+ (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature)
+ );
+
+ if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||
+ (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: TPM2: Requested table revision = %d is not supported. "
+ "Supported table revisions: Minimum = %d. Maximum = %d\n",
+ AcpiTableInfo->AcpiTableRevision,
+ This->MinAcpiTableRevision,
+ This->AcpiTableRevision
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetEArchCommonObjTpm2InterfaceInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &TpmInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Failed to get TPM interface CM Object %r\n",
+ __func__,
+ Status
+ ));
+ return Status;
+ }
+
+ // Sanity check Start Method Specific Parameters field
+ Status = AcpiTpm2CheckStartMethodParameters (TpmInfo);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: TPM2: Unexpected StartMethod %u with parameters size %u\n",
+ TpmInfo->StartMethod,
+ TpmInfo->StartMethodParametersSize
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Calculate the size of the TPM2 table
+ TableSize = sizeof (EFI_TPM2_ACPI_TABLE);
+ if (TpmInfo->Laml == 0) {
+ TableSize += TpmInfo->StartMethodParametersSize;
+ } else {
+ // If LAML and LASA are present, then StartMethodParameters field would get
+ // max size regardless of StartMethod value
+ TableSize += EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4;
+ TableSize += sizeof (TpmInfo->Laml) + sizeof (TpmInfo->Lasa);
+ }
+
+ // Allocate the Buffer for TPM2 table
+ *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize);
+ if (*Table == NULL) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: TPM2: Failed to allocate memory for TPM2 Table, Size = %d," \
+ " Status = %r\n",
+ TableSize,
+ Status
+ ));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Tpm2 = (EFI_TPM2_ACPI_TABLE *)*Table;
+
+ Status = AddAcpiHeader (
+ CfgMgrProtocol,
+ This,
+ &Tpm2->Header,
+ AcpiTableInfo,
+ TableSize
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: TPM2: Failed to add ACPI header. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ Tpm2->Flags = TpmInfo->PlatformClass;
+ Tpm2->AddressOfControlArea = TpmInfo->AddressOfControlArea;
+ Tpm2->StartMethod = TpmInfo->StartMethod;
+
+ CopyMem (
+ Tpm2 + 1,
+ TpmInfo->StartMethodParameters,
+ TpmInfo->StartMethodParametersSize
+ );
+
+ if (TpmInfo->Laml > 0) {
+ Laml = (UINT32 *)((UINT8 *)Tpm2 + sizeof (EFI_TPM2_ACPI_TABLE) +
+ EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4);
+ Lasa = (UINT64 *)((UINT8 *)Laml + sizeof (TpmInfo->Laml));
+ *Laml = TpmInfo->Laml;
+ *Lasa = TpmInfo->Lasa;
+ }
+
+ return EFI_SUCCESS;
+
+error_handler:
+
+ if (*Table != NULL) {
+ FreePool (*Table);
+ *Table = NULL;
+ }
+
+ return Status;
+}
+
+/** Free any resources allocated for constructing the TPM2.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] Table Pointer to the ACPI Table.
+
+ @retval EFI_SUCCESS The resources were freed successfully.
+ @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FreeTpm2TableResources (
+ IN CONST ACPI_TABLE_GENERATOR *CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
+ )
+{
+ ASSERT (
+ (This != NULL) &&
+ (AcpiTableInfo != NULL) &&
+ (CfgMgrProtocol != NULL) &&
+ (AcpiTableInfo->TableGeneratorId == This->GeneratorID) &&
+ (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature)
+ );
+
+ if ((Table == NULL) || (*Table == NULL)) {
+ DEBUG ((DEBUG_ERROR, "ERROR: TPM2: Invalid Table Pointer\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FreePool (*Table);
+ *Table = NULL;
+
+ return EFI_SUCCESS;
+}
+
+/** The TPM2 Table Generator revision.
+*/
+#define TPM2_GENERATOR_REVISION CREATE_REVISION (1, 0)
+
+/** The interface for the TPM2 Table Generator.
+*/
+STATIC
+CONST
+ACPI_TABLE_GENERATOR Tpm2Generator = {
+ // Generator ID
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdTpm2),
+ // Generator Description
+ L"ACPI.STD.TPM2.GENERATOR",
+ // ACPI Table Signature
+ EFI_ACPI_6_4_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE,
+ // ACPI Table Revision supported by this Generator
+ EFI_TPM2_ACPI_TABLE_REVISION_4,
+ // Minimum supported ACPI Table Revision
+ EFI_TPM2_ACPI_TABLE_REVISION_4,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID,
+ // Creator Revision
+ TPM2_GENERATOR_REVISION,
+ // Build Table function
+ BuildTpm2Table,
+ // Free Resource function
+ FreeTpm2TableResources,
+ // Extended build function not needed
+ NULL,
+ // Extended build function not implemented by the generator.
+ // Hence extended free resource function is not required.
+ NULL
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiTpm2LibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = RegisterAcpiTableGenerator (&Tpm2Generator);
+ DEBUG ((DEBUG_INFO, "TPM2: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiTpm2LibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = DeregisterAcpiTableGenerator (&Tpm2Generator);
+ DEBUG ((DEBUG_INFO, "TPM2: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/X64/AcpiHpetLib/AcpiHpetLib.c b/DynamicTablesPkg/Library/Acpi/X64/AcpiHpetLib/AcpiHpetLib.c
new file mode 100644
index 0000000..b53518d
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/X64/AcpiHpetLib/AcpiHpetLib.c
@@ -0,0 +1,327 @@
+/** @file
+
+ Generate ACPI HPET table for AMD platforms.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+ SPDX-License-Identifier BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerHelper.h>
+#include <ConfigurationManagerObject.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <X64NameSpaceObjects.h>
+#include <Library/IoLib.h>
+
+/** This macro defines supported HPET page protection flags
+*/
+#define HPET_VALID_PAGE_PROTECTION \
+ (EFI_ACPI_NO_PAGE_PROTECTION | \
+ EFI_ACPI_4KB_PAGE_PROTECTION | \
+ EFI_ACPI_64KB_PAGE_PROTECTION)
+
+/** This macro expands to a function that retrieves the
+ HPET device information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjHpetInfo,
+ CM_X64_HPET_INFO
+ );
+
+/** The ACPI HPET Table.
+*/
+STATIC
+EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER AcpiHpet = {
+ ACPI_HEADER (
+ EFI_ACPI_6_5_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE,
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER,
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_REVISION
+ ),
+ // EventTimerBlockId,
+ 0,
+ // BaseAddressLower32Bit
+ { EFI_ACPI_6_5_SYSTEM_MEMORY, 64,0, EFI_ACPI_RESERVED_BYTE, 0 },
+ // HpetNumber
+ 0,
+ // MainCounterMinimumClockTickInPeriodicMode
+ 0,
+ // PageProtectionAndOemAttribute
+ EFI_ACPI_NO_PAGE_PROTECTION
+};
+
+/** Update HPET table information.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found or
+ the HPET is not enabled.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+ @retval EFI_UNSUPPORTED If invalid protection and oem flags provided.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+HpetUpdateTableInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol
+ )
+{
+ CM_X64_HPET_INFO *HpetInfo;
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_BLOCK_ID HpetBlockId;
+ EFI_STATUS Status;
+
+ ASSERT (CfgMgrProtocol != NULL);
+
+ // Get the HPET information from the Platform Configuration Manager
+ Status = GetEX64ObjHpetInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &HpetInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: HPET: Failed to get HPET information." \
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "HPET: Device base address = 0x%x\n"
+ " : Minimum clock tick in periodic mode = 0x%x\n"
+ " : Page protection and Oem flags = 0x%x\n",
+ HpetInfo->BaseAddressLower32Bit,
+ HpetInfo->MainCounterMinimumClockTickInPeriodicMode,
+ HpetInfo->PageProtectionAndOemAttribute
+ ));
+
+ // Validate the page protection flags bit0 to bit3
+ if (((HpetInfo->PageProtectionAndOemAttribute & 0xF) & ~HPET_VALID_PAGE_PROTECTION) != 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: HPET: unsupported page protection flags = 0x%x\n",
+ HpetInfo->PageProtectionAndOemAttribute
+ ));
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ return EFI_UNSUPPORTED;
+ }
+
+ // Get HPET Capabilities ID register value and test if HPET is enabled
+ HpetBlockId.Uint32 = MmioRead32 (HpetInfo->BaseAddressLower32Bit);
+
+ // If mmio address is not mapped
+ if ((HpetBlockId.Uint32 == MAX_UINT32) || (HpetBlockId.Uint32 == 0)) {
+ DEBUG ((DEBUG_ERROR, "HPET Capabilities register read failed.\n"));
+ ASSERT_EFI_ERROR (EFI_NOT_FOUND);
+ return EFI_NOT_FOUND;
+ }
+
+ // Validate Reserved and Revision ID
+ if (HpetBlockId.Bits.Reserved != 0) {
+ DEBUG ((DEBUG_ERROR, "HPET Reserved bit is set.\n"));
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ return EFI_UNSUPPORTED;
+ }
+
+ if (HpetBlockId.Bits.Revision == 0) {
+ DEBUG ((DEBUG_ERROR, "HPET Revision is not set.\n"));
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ return EFI_UNSUPPORTED;
+ }
+
+ // Fill the Event Timer Block ID
+ AcpiHpet.EventTimerBlockId = HpetBlockId.Uint32;
+
+ // Fill the Base Address
+ AcpiHpet.BaseAddressLower32Bit.Address = HpetInfo->BaseAddressLower32Bit;
+
+ // Minimum clock tick in periodic mode
+ AcpiHpet.MainCounterMinimumClockTickInPeriodicMode = HpetInfo->MainCounterMinimumClockTickInPeriodicMode;
+
+ // Page protection and OEM attribute
+ AcpiHpet.PageProtectionAndOemAttribute = HpetInfo->PageProtectionAndOemAttribute;
+
+ return Status;
+}
+
+/** Construct the HPET table.
+
+ This function invokes the Configuration Manager protocol interface
+ to get the required information for generating the ACPI table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildHpetTable (
+ IN CONST ACPI_TABLE_GENERATOR *CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
+ )
+{
+ EFI_STATUS Status;
+
+ ASSERT (This != NULL);
+ ASSERT (AcpiTableInfo != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Table != NULL);
+ ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+ ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+ if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||
+ (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: HPET: Requested table revision = %d, is not supported."
+ "Supported table revision: Minimum = %d, Maximum = %d\n",
+ AcpiTableInfo->AcpiTableRevision,
+ This->MinAcpiTableRevision,
+ This->AcpiTableRevision
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Table = NULL;
+
+ Status = AddAcpiHeader (
+ CfgMgrProtocol,
+ This,
+ (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiHpet,
+ AcpiTableInfo,
+ sizeof (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER)
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: HPET: Failed to add ACPI header. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ // Update HPET table info
+ Status = HpetUpdateTableInfo (CfgMgrProtocol);
+ if (EFI_ERROR (Status)) {
+ goto error_handler;
+ }
+
+ *Table = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiHpet;
+error_handler:
+ return Status;
+}
+
+/** This macro defines the HPET Table Generator revision.
+*/
+#define HPET_GENERATOR_REVISION CREATE_REVISION (1, 0)
+
+/** The interface for the HPET Table Generator.
+*/
+STATIC
+CONST
+ACPI_TABLE_GENERATOR HpetGenerator = {
+ // Generator ID
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdHpet),
+ // Generator Description
+ L"ACPI.STD.HPET.GENERATOR",
+ // ACPI Table Signature
+ EFI_ACPI_6_5_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE,
+ // ACPI Table Revision supported by this Generator
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_REVISION,
+ // Minimum supported ACPI Table Revision
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_REVISION,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID,
+ // Creator Revision
+ HPET_GENERATOR_REVISION,
+ // Build Table function
+ BuildHpetTable,
+ // No additional resources are allocated by the generator.
+ // Hence the Free Resource function is not required.
+ NULL,
+ // Extended build function not needed
+ NULL,
+ // Extended build function not implemented by the generator.
+ // Hence extended free resource function is not required.
+ NULL
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiHpetLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = RegisterAcpiTableGenerator (&HpetGenerator);
+ DEBUG ((DEBUG_INFO, "HPET: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiHpetLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = DeregisterAcpiTableGenerator (&HpetGenerator);
+ DEBUG ((DEBUG_INFO, "HPET: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/X64/AcpiHpetLib/AcpiHpetLib.inf b/DynamicTablesPkg/Library/Acpi/X64/AcpiHpetLib/AcpiHpetLib.inf
new file mode 100644
index 0000000..3afc104
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/X64/AcpiHpetLib/AcpiHpetLib.inf
@@ -0,0 +1,31 @@
+## @file
+# Creates ACPI HPET tables for AMD platforms.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 1.30
+ BASE_NAME = AcpiHpetLib
+ FILE_GUID = 858FA64F-8C39-4D4F-A5F1-5DCD61CB79D4
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL|DXE_DRIVER
+ CONSTRUCTOR = AcpiHpetLibConstructor
+ DESTRUCTOR = AcpiHpetLibDestructor
+
+[Sources]
+ AcpiHpetLib.c
+
+[Packages]
+ DynamicTablesPkg/DynamicTablesPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
diff --git a/DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.c b/DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.c
new file mode 100644
index 0000000..8d4bed1
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.c
@@ -0,0 +1,428 @@
+/** @file
+
+ Generate ACPI HPET table for AMD platforms.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+ SPDX-License-Identifier BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/TableHelperLib.h>
+#include <Library/AmlLib/AmlLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Library/IoLib.h>
+
+/** This macro defines supported HPET page protection flags
+*/
+#define HPET_VALID_PAGE_PROTECTION \
+ (EFI_ACPI_NO_PAGE_PROTECTION | \
+ EFI_ACPI_4KB_PAGE_PROTECTION | \
+ EFI_ACPI_64KB_PAGE_PROTECTION)
+
+/** This macro expands to a function that retrieves the
+ HPET device information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjHpetInfo,
+ CM_X64_HPET_INFO
+ );
+
+/** Update HPET table information.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] ScopeNode The Scope Node for the HPET table.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found or
+ the HPET is not enabled.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+ @retval EFI_UNSUPPORTED If invalid protection and oem flags provided.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SsdtHpetUpdateTableInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT AML_OBJECT_NODE_HANDLE ScopeNode
+ )
+{
+ CM_X64_HPET_INFO *HpetInfo;
+ EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_BLOCK_ID HpetBlockId;
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE CrsNode;
+ AML_OBJECT_NODE_HANDLE HpetNode;
+ UINT32 EisaId;
+
+ ASSERT (CfgMgrProtocol != NULL);
+
+ // Get the HPET information from the Platform Configuration Manager
+ Status = GetEX64ObjHpetInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &HpetInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: HPET: Failed to get HPET information." \
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "HPET: Device base address = 0x%x\n"
+ " : Minimum clock tick in periodic mode = 0x%x\n"
+ " : Page protection and Oem flags = 0x%x\n",
+ HpetInfo->BaseAddressLower32Bit,
+ HpetInfo->MainCounterMinimumClockTickInPeriodicMode,
+ HpetInfo->PageProtectionAndOemAttribute
+ ));
+
+ // Validate the page protection flags bit0 to bit3
+ if (((HpetInfo->PageProtectionAndOemAttribute & 0xF) & ~HPET_VALID_PAGE_PROTECTION) != 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: HPET: unsupported page protection flags = 0x%x\n",
+ HpetInfo->PageProtectionAndOemAttribute
+ ));
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ return EFI_UNSUPPORTED;
+ }
+
+ // Get HPET Capabilities ID register value and test if HPET is enabled
+ HpetBlockId.Uint32 = MmioRead32 (HpetInfo->BaseAddressLower32Bit);
+
+ // If mmio address is not mapped
+ if ((HpetBlockId.Uint32 == MAX_UINT32) || (HpetBlockId.Uint32 == 0)) {
+ DEBUG ((DEBUG_ERROR, "HPET Capabilities register read failed.\n"));
+ ASSERT_EFI_ERROR (EFI_NOT_FOUND);
+ return EFI_NOT_FOUND;
+ }
+
+ // Validate Reserved and Revision ID
+ if (HpetBlockId.Bits.Reserved != 0) {
+ DEBUG ((DEBUG_ERROR, "HPET Reserved bit is set.\n"));
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ return EFI_UNSUPPORTED;
+ }
+
+ if (HpetBlockId.Bits.Revision == 0) {
+ DEBUG ((DEBUG_ERROR, "HPET Revision is not set.\n"));
+ ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = AmlCodeGenDevice ("HPET", ScopeNode, &HpetNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ Status = AmlGetEisaIdFromString ("PNP0103", &EisaId);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ Status = AmlCodeGenNameInteger ("_HID", EisaId, HpetNode, NULL);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ Status = AmlCodeGenNameInteger ("_UID", 0x00, HpetNode, NULL);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ Status = AmlCodeGenNameResourceTemplate ("_CRS", HpetNode, &CrsNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ Status = AmlCodeGenRdMemory32Fixed (
+ FALSE,
+ HpetInfo->BaseAddressLower32Bit,
+ SIZE_1KB,
+ CrsNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ if ((HpetInfo->PageProtectionAndOemAttribute & 0xF) != 0) {
+ Status = AmlCodeGenNameInteger (
+ "PAGE",
+ (HpetInfo->PageProtectionAndOemAttribute & 0xF),
+ HpetNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
+
+ if ((HpetInfo->PageProtectionAndOemAttribute >> 4) != 0) {
+ Status = AmlCodeGenNameInteger (
+ "ATTR",
+ (HpetInfo->PageProtectionAndOemAttribute >> 4),
+ HpetNode,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
+
+ return Status;
+}
+
+/** Construct the SSDT HPET table.
+
+ This function invokes the Configuration Manager protocol interface
+ to get the required information for generating the ACPI table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildSsdtHpetTable (
+ IN CONST ACPI_TABLE_GENERATOR *CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
+ )
+{
+ EFI_STATUS Status;
+ AML_ROOT_NODE_HANDLE RootNode;
+ AML_OBJECT_NODE_HANDLE ScopeNode;
+
+ ASSERT (This != NULL);
+ ASSERT (AcpiTableInfo != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Table != NULL);
+ ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+ ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+ if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||
+ (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: HPET: Requested table revision = %d, is not supported."
+ "Supported table revision: Minimum = %d, Maximum = %d\n",
+ AcpiTableInfo->AcpiTableRevision,
+ This->MinAcpiTableRevision,
+ This->AcpiTableRevision
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Table = NULL;
+
+ Status = AddSsdtAcpiHeader (
+ CfgMgrProtocol,
+ This,
+ AcpiTableInfo,
+ &RootNode
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = AmlCodeGenScope ("\\_SB_", RootNode, &ScopeNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto exit_handler;
+ }
+
+ // Update HPET table info
+ Status = SsdtHpetUpdateTableInfo (CfgMgrProtocol, ScopeNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto exit_handler;
+ }
+
+ Status = AmlSerializeDefinitionBlock (
+ RootNode,
+ Table
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SSDT-HPET: Failed to Serialize SSDT Table Data."
+ " Status = %r\n",
+ Status
+ ));
+ }
+
+exit_handler:
+ // Delete the RootNode and its attached children.
+ AmlDeleteTree (RootNode);
+ return Status;
+}
+
+/** Free any resources allocated for constructing the
+ SSDT HPET ACPI table.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] Table Pointer to the ACPI Table.
+
+ @retval EFI_SUCCESS The resources were freed successfully.
+ @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FreeSsdtHpetTableResources (
+ IN CONST ACPI_TABLE_GENERATOR *CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
+ )
+{
+ ASSERT (This != NULL);
+ ASSERT (AcpiTableInfo != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+ ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+ if ((Table == NULL) || (*Table == NULL)) {
+ DEBUG ((DEBUG_ERROR, "ERROR: SSDT-HPET: Invalid Table Pointer\n"));
+ ASSERT ((Table != NULL) && (*Table != NULL));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FreePool (*Table);
+ *Table = NULL;
+ return EFI_SUCCESS;
+}
+
+/** This macro defines the HPET Table Generator revision.
+*/
+#define HPET_GENERATOR_REVISION CREATE_REVISION (1, 0)
+
+/** The interface for the HPET Table Generator.
+*/
+STATIC
+CONST
+ACPI_TABLE_GENERATOR SsdtHpetGenerator = {
+ // Generator ID
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtHpet),
+ // Generator Description
+ L"ACPI.STD.SSDT.HPET.GENERATOR",
+ // ACPI Table Signature
+ EFI_ACPI_6_5_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+ // ACPI Table Revision supported by this Generator
+ 0,
+ // Minimum supported ACPI Table Revision
+ 0,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID,
+ // Creator Revision
+ HPET_GENERATOR_REVISION,
+ // Build Table function
+ BuildSsdtHpetTable,
+ // Free Resource function
+ FreeSsdtHpetTableResources,
+ // Extended build function not needed
+ NULL,
+ // Extended build function not implemented by the generator.
+ // Hence extended free resource function is not required.
+ NULL
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiSsdtHpetLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = RegisterAcpiTableGenerator (&SsdtHpetGenerator);
+ DEBUG ((DEBUG_INFO, "HPET: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiSsdtHpetLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = DeregisterAcpiTableGenerator (&SsdtHpetGenerator);
+ DEBUG ((DEBUG_INFO, "HPET: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.inf b/DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.inf
new file mode 100644
index 0000000..a47e67e
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.inf
@@ -0,0 +1,31 @@
+## @file
+# Creates ACPI SSDT HPET device for AMD platforms.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 1.30
+ BASE_NAME = AcpiSsdtHpetLib
+ FILE_GUID = CEC214FF-A9F1-4C3F-B084-BC8AFBEE7EA2
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL|DXE_DRIVER
+ CONSTRUCTOR = AcpiSsdtHpetLibConstructor
+ DESTRUCTOR = AcpiSsdtHpetLibDestructor
+
+[Sources]
+ AcpiSsdtHpetLib.c
+
+[Packages]
+ DynamicTablesPkg/DynamicTablesPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
diff --git a/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf
new file mode 100644
index 0000000..06e8f8c
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf
@@ -0,0 +1,35 @@
+## @file
+# WSMT Table Generator
+#
+# Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.30
+ BASE_NAME = AcpiWsmtLib
+ FILE_GUID = FA6B175A-0AAF-4BFA-843A-1D885206C070
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = NULL|DXE_DRIVER
+ CONSTRUCTOR = AcpiWsmtLibConstructor
+ DESTRUCTOR = AcpiWsmtLibDestructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.IA32, Sources.X64]
+ WsmtGenerator.c
+
+[Packages]
+ DynamicTablesPkg/DynamicTablesPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
diff --git a/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c
new file mode 100644
index 0000000..9762294
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/WsmtGenerator.c
@@ -0,0 +1,288 @@
+/** @file
+ WSMT Table Generator Implementation.
+
+ This file implements the WSMT Table Generator.
+ The WSMT table is used to specify the security mitigation
+ that are enabled in the Windows OS.
+
+ Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerHelper.h>
+#include <ConfigurationManagerObject.h>
+#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <X64NameSpaceObjects.h>
+
+#define WSMT_PROTECTION_VALID_FLAGS \
+ (EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS | \
+ EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION | \
+ EFI_WSMT_PROTECTION_FLAGS_SYSTEM_RESOURCE_PROTECTION)
+
+/** This macro expands to a function that retrieves the
+ WSMT protection flags information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceX64,
+ EX64ObjWsmtFlagsInfo,
+ CM_X64_WSMT_FLAGS_INFO
+ );
+
+/** The ACPI WSMT Table.
+*/
+STATIC
+EFI_ACPI_WSMT_TABLE AcpiWsmt = {
+ ACPI_HEADER (
+ EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE,
+ EFI_ACPI_WSMT_TABLE,
+ EFI_WSMT_TABLE_REVISION
+ ),
+ // ProtectionFlags
+ 0
+};
+
+/** Update the protection flags information in the WSMT Table.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+ @retval EFI_UNSUPPORTED If invalid protection flags provided.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+WsmtAddProtectionFlagsInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol
+ )
+{
+ EFI_STATUS Status;
+ CM_X64_WSMT_FLAGS_INFO *WsmtFlagInfo;
+
+ ASSERT (CfgMgrProtocol != NULL);
+
+ // Get the WSMT protection flag from the Platform Configuration Manager
+ Status = GetEX64ObjWsmtFlagsInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &WsmtFlagInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: WSMT: Failed to get WSMT protection flag information." \
+ " Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "WSMT: Protection flags = 0x%x\n",
+ WsmtFlagInfo->ProtectionFlags
+ ));
+
+ // Validate the protection flags
+ if ((WsmtFlagInfo->ProtectionFlags & ~WSMT_PROTECTION_VALID_FLAGS) != 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: WSMT: Invalid protection flags = 0x%x\n",
+ WsmtFlagInfo->ProtectionFlags
+ ));
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((WsmtFlagInfo->ProtectionFlags & EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION) != 0) {
+ if ((WsmtFlagInfo->ProtectionFlags & EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS) == 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: WSMT: Invalid protection flags. EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS not set.\n"
+ ));
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ AcpiWsmt.ProtectionFlags = WsmtFlagInfo->ProtectionFlags;
+ return Status;
+}
+
+/** Construct the WSMT table.
+
+ This function invokes the Configuration Manager protocol interface
+ to get the required information for generating the ACPI table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildWsmtTable (
+ IN CONST ACPI_TABLE_GENERATOR *CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
+ )
+{
+ EFI_STATUS Status;
+
+ ASSERT (This != NULL);
+ ASSERT (AcpiTableInfo != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Table != NULL);
+ ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+ ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+ if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||
+ (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: WSMT: Requested table revision = %d, is not supported."
+ "Supported table revision: Minimum = %d, Maximum = %d\n",
+ AcpiTableInfo->AcpiTableRevision,
+ This->MinAcpiTableRevision,
+ This->AcpiTableRevision
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Table = NULL;
+
+ Status = AddAcpiHeader (
+ CfgMgrProtocol,
+ This,
+ (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiWsmt,
+ AcpiTableInfo,
+ sizeof (EFI_ACPI_6_5_FIXED_ACPI_DESCRIPTION_TABLE)
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: WSMT: Failed to add ACPI header. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ // Update protection flags Info
+ Status = WsmtAddProtectionFlagsInfo (CfgMgrProtocol);
+ if (EFI_ERROR (Status)) {
+ goto error_handler;
+ }
+
+ *Table = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiWsmt;
+error_handler:
+ return Status;
+}
+
+/** This macro defines the WSMT Table Generator revision.
+*/
+#define WSMT_GENERATOR_REVISION CREATE_REVISION (1, 0)
+
+/** The interface for the WSMT Table Generator.
+*/
+STATIC
+CONST
+ACPI_TABLE_GENERATOR WsmtGenerator = {
+ // Generator ID
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdWsmt),
+ // Generator Description
+ L"ACPI.STD.WSMT.GENERATOR",
+ // ACPI Table Signature
+ EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE,
+ // ACPI Table Revision supported by this Generator
+ EFI_WSMT_TABLE_REVISION,
+ // Minimum supported ACPI Table Revision
+ EFI_WSMT_TABLE_REVISION,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID_ARM,
+ // Creator Revision
+ WSMT_GENERATOR_REVISION,
+ // Build Table function
+ BuildWsmtTable,
+ // No additional resources are allocated by the generator.
+ // Hence the Free Resource function is not required.
+ NULL,
+ // Extended build function not needed
+ NULL,
+ // Extended build function not implemented by the generator.
+ // Hence extended free resource function is not required.
+ NULL
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiWsmtLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = RegisterAcpiTableGenerator (&WsmtGenerator);
+ DEBUG ((DEBUG_INFO, "WSMT: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiWsmtLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = DeregisterAcpiTableGenerator (&WsmtGenerator);
+ DEBUG ((DEBUG_INFO, "WSMT: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index f433a46..35ec2aa 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -116,7 +116,7 @@ AmlCodeGenDefinitionBlock (
CopyMem (&AcpiHeader.OemId, OemId, 6);
CopyMem (&AcpiHeader.OemTableId, OemTableId, 8);
AcpiHeader.OemRevision = OemRevision;
- AcpiHeader.CreatorId = TABLE_GENERATOR_CREATOR_ID_ARM;
+ AcpiHeader.CreatorId = TABLE_GENERATOR_CREATOR_ID;
AcpiHeader.CreatorRevision = CREATE_REVISION (1, 0);
Status = AmlCreateRootNode (&AcpiHeader, NewRootNode);
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
index 46243f9..3db536d 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
@@ -1475,6 +1475,89 @@ AmlCodeGenRdRegister (
return LinkRdNode (RdNode, NameOpNode, NewRdNode);
}
+/** Code generation for the "IO ()" ASL function.
+
+ The Resource Data effectively created is a IO Resource
+ Data. Cf ACPI 6.5:
+ - s19.6.65 IO (IO Resource Descriptor Macro)
+ - s6.4.2.5 I/O Port Descriptor
+
+ The created resource data node can be:
+ - appended to the list of resource data elements of the NameOpNode.
+ In such case NameOpNode must be defined by a the "Name ()" ASL statement
+ and initially contain a "ResourceTemplate ()".
+ - returned through the NewRdNode parameter.
+
+ @param [in] IsDecoder16 Decoder parameter.
+ TRUE if 16-bit decoder.
+ FALSE if 10-bit decoder.
+ @param [in] AddressMinimum Minimum address.
+ @param [in] AddressMaximum Maximum address.
+ @param [in] Alignment Alignment.
+ @param [in] RangeLength Range length.
+ @param [in] NameOpNode NameOp object node defining a named object.
+ If provided, append the new resource data
+ node to the list of resource data elements
+ of this node.
+ @param [out] NewRdNode If provided and success,
+ contain the created node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenRdIo (
+ IN BOOLEAN IsDecoder16,
+ IN UINT16 AddressMinimum,
+ IN UINT16 AddressMaximum,
+ IN UINT8 Alignment,
+ IN UINT8 RangeLength,
+ IN AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
+ OUT AML_DATA_NODE_HANDLE *NewRdNode OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_IO_PORT_DESCRIPTOR IoDesc;
+ AML_DATA_NODE *IoNode;
+
+ if (AddressMinimum > AddressMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Alignment != 0) {
+ /// check the alignment
+ if ((AddressMinimum % Alignment) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((AddressMaximum % Alignment) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ IoDesc.Header.Byte = ACPI_IO_PORT_DESCRIPTOR;
+ IoDesc.Information = IsDecoder16 ? BIT0 : 0;
+
+ IoDesc.BaseAddressMin = AddressMinimum;
+ IoDesc.BaseAddressMax = AddressMaximum;
+ IoDesc.Alignment = Alignment;
+ IoDesc.Length = RangeLength;
+
+ Status = AmlCreateDataNode (
+ EAmlNodeDataTypeResourceData,
+ (UINT8 *)&IoDesc,
+ sizeof (IoDesc),
+ &IoNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ return LinkRdNode (IoNode, NameOpNode, NewRdNode);
+}
+
/** Code generation for the EndTag resource data.
The EndTag resource data is automatically generated by the ASL compiler
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlParser.c b/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlParser.c
index d3a51a9..3762441 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlParser.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Parser/AmlParser.c
@@ -330,7 +330,7 @@ AmlParseString (
StrSize = 0;
// AML String is NULL terminated.
do {
- // Reading the stream moves the stream forward aswell.
+ // Reading the stream moves the stream forward as well.
Status = AmlStreamReadByte (FStream, &Byte);
if (EFI_ERROR (Status)) {
ASSERT (0);
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c
index 1404a21..0a744f1 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlNode.c
@@ -573,7 +573,7 @@ AmlIsMethodDefinitionNode (
{
AML_DATA_NODE *ObjectType;
- // Node is checked to be an object node aswell.
+ // Node is checked to be an object node as well.
if (AmlNodeCompareOpCode (Node, AML_METHOD_OP, 0)) {
return TRUE;
} else if (AmlNodeCompareOpCode (Node, AML_EXTERNAL_OP, 0)) {
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c
index 345acab..5325b20 100644
--- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/CmObjectTokenFixer.c
@@ -145,44 +145,28 @@ CONST
CM_OBJECT_TOKEN_FIXER TokenFixer[EArmObjMax] = {
NULL, ///< 0 - Reserved
NULL, ///< 1 - Boot Architecture Info
- NULL, ///< 2 - CPU Info
- NULL, ///< 3 - Power Management Profile Info
- NULL, ///< 4 - GIC CPU Interface Info
- NULL, ///< 5 - GIC Distributor Info
- NULL, ///< 6 - GIC MSI Frame Info
- NULL, ///< 7 - GIC Redistributor Info
- NULL, ///< 8 - GIC ITS Info
- NULL, ///< 9 - Serial Console Port Info
- NULL, ///< 10 - Serial Debug Port Info
- NULL, ///< 11 - Generic Timer Info
- NULL, ///< 12 - Platform GT Block Info
- NULL, ///< 13 - Generic Timer Block Frame Info
- NULL, ///< 14 - Platform Generic Watchdog
- NULL, ///< 15 - PCI Configuration Space Info
- NULL, ///< 16 - Hypervisor Vendor Id
- NULL, ///< 17 - Fixed feature flags for FADT
- TokenFixerItsGroup, ///< 18 - ITS Group
- TokenFixerNamedComponentNode, ///< 19 - Named Component
- TokenFixerRootComplexNode, ///< 20 - Root Complex
- TokenFixerNotImplemented, ///< 21 - SMMUv1 or SMMUv2
- TokenFixerSmmuV3Node, ///< 22 - SMMUv3
- TokenFixerNotImplemented, ///< 23 - PMCG
- NULL, ///< 24 - GIC ITS Identifier Array
- NULL, ///< 25 - ID Mapping Array
- NULL, ///< 26 - SMMU Interrupt Array
- TokenFixerNotImplemented, ///< 27 - Processor Hierarchy Info
- TokenFixerNotImplemented, ///< 28 - Cache Info
- TokenFixerNotImplemented, ///< 29 - Processor Node ID Info
- NULL, ///< 30 - CM Object Reference
- NULL, ///< 31 - Memory Affinity Info
- NULL, ///< 32 - Device Handle Acpi
- NULL, ///< 33 - Device Handle Pci
- NULL, ///< 34 - Generic Initiator Affinity
- NULL, ///< 35 - Generic Serial Port Info
- NULL, ///< 36 - CMN-600 Info
- NULL, ///< 37 - Lpi Info
- NULL, ///< 38 - Pci Address Map Info
- NULL, ///< 39 - Pci Interrupt Map Info
+ NULL, ///< 2 - GIC CPU Interface Info
+ NULL, ///< 3 - GIC Distributor Info
+ NULL, ///< 4 - GIC MSI Frame Info
+ NULL, ///< 5 - GIC Redistributor Info
+ NULL, ///< 6 - GIC ITS Info
+ NULL, ///< 7 - Generic Timer Info
+ NULL, ///< 8 - Platform GT Block Info
+ NULL, ///< 9 - Generic Timer Block Frame Info
+ NULL, ///< 10 - Platform Generic Watchdog
+ TokenFixerItsGroup, ///< 11 - ITS Group
+ TokenFixerNamedComponentNode, ///< 12 - Named Component
+ TokenFixerRootComplexNode, ///< 13 - Root Complex
+ TokenFixerNotImplemented, ///< 14 - SMMUv1 or SMMUv2
+ TokenFixerSmmuV3Node, ///< 15 - SMMUv3
+ TokenFixerNotImplemented, ///< 16 - PMCG
+ NULL, ///< 17 - GIC ITS Identifier Array
+ NULL, ///< 18 - ID Mapping Array
+ NULL, ///< 19 - SMMU Interrupt Array
+ NULL, ///< 20 - CMN-600 Info
+ NULL, ///< 21 - Reserved Memory Range Node
+ NULL, ///< 22 - Memory Range Descriptor
+ NULL ///< 23 - Embedded Trace Extension/Module Info
};
/** CmObj token fixer.
@@ -209,14 +193,17 @@ FixupCmObjectSelfToken (
CM_OBJECT_TOKEN_FIXER TokenFixerFunc;
CM_OBJECT_ID ArmNamespaceObjId;
- // Only support Arm objects for now.
- if ((CmObjDesc == NULL) ||
- (GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm))
- {
+ if (CmObjDesc == NULL) {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
+ // Only support Arm objects for now.
+ if (GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm) {
+ ASSERT (0);
+ return EFI_UNSUPPORTED;
+ }
+
ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId);
if (ArmNamespaceObjId >= EArmObjMax) {
ASSERT (0);
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c
index bdeb5c7..08d11ac 100644
--- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepo.c
@@ -127,10 +127,12 @@ DynPlatRepoAddObject (
OUT CM_OBJECT_TOKEN *Token OPTIONAL
)
{
- EFI_STATUS Status;
- CM_OBJ_NODE *ObjNode;
- CM_OBJECT_ID ArmNamespaceObjId;
- CM_OBJECT_TOKEN NewToken;
+ EFI_STATUS Status;
+ CM_OBJ_NODE *ObjNode;
+ CM_OBJECT_ID ObjId;
+ CM_OBJECT_TOKEN NewToken;
+ LIST_ENTRY *ObjList;
+ EOBJECT_NAMESPACE_ID NamespaceId;
// The dynamic repository must be able to receive objects.
if ((This == NULL) ||
@@ -142,15 +144,33 @@ DynPlatRepoAddObject (
}
// Check the CmObjDesc:
- // - only Arm objects are supported for now.
- // - only EArmObjCmRef objects can be added as arrays.
- ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId);
- if ((CmObjDesc->Size == 0) ||
- (CmObjDesc->Count == 0) ||
- (ArmNamespaceObjId >= EArmObjMax) ||
- ((CmObjDesc->Count > 1) && (ArmNamespaceObjId != EArmObjCmRef)) ||
- (GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId) != EObjNameSpaceArm))
- {
+ // - only Arm objects and Arch Common objects are supported for now.
+ // - only EArchCommonObjCmRef objects can be added as arrays.
+ if ((CmObjDesc->Size == 0) || (CmObjDesc->Count == 0)) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ObjId = GET_CM_OBJECT_ID (CmObjDesc->ObjectId);
+ NamespaceId = GET_CM_NAMESPACE_ID (CmObjDesc->ObjectId);
+
+ if (EObjNameSpaceArm == NamespaceId) {
+ if (ObjId >= EArmObjMax) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ObjList = &This->ArmCmObjList[ObjId];
+ } else if (EObjNameSpaceArchCommon == NamespaceId) {
+ if ((ObjId >= EArchCommonObjMax) ||
+ ((CmObjDesc->Count > 1) && (ObjId != EArchCommonObjCmRef)))
+ {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ObjList = &This->ArchCommonCmObjList[ObjId];
+ } else {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
@@ -166,15 +186,17 @@ DynPlatRepoAddObject (
}
// Fixup self-token if necessary.
- Status = FixupCmObjectSelfToken (&ObjNode->CmObjDesc, NewToken);
- if (EFI_ERROR (Status)) {
- FreeCmObjNode (ObjNode);
- ASSERT (0);
- return Status;
+ if (EObjNameSpaceArm == NamespaceId) {
+ Status = FixupCmObjectSelfToken (&ObjNode->CmObjDesc, NewToken);
+ if (EFI_ERROR (Status)) {
+ FreeCmObjNode (ObjNode);
+ ASSERT (0);
+ return Status;
+ }
}
// Add to link list.
- InsertTailList (&This->ArmCmObjList[ArmNamespaceObjId], &ObjNode->Link);
+ InsertTailList (ObjList, &ObjNode->Link);
This->ObjectCount += 1;
if (Token != NULL) {
@@ -184,11 +206,14 @@ DynPlatRepoAddObject (
return EFI_SUCCESS;
}
-/** Group lists of CmObjNode from the ArmNameSpace to one array.
+/** Group lists of CmObjNode from the Arm Namespace or ArchCommon namespace
+ to one array.
@param [in] This This dynamic platform repository.
- @param [in] ArmObjIndex Index in EARM_OBJECT_ID
- (must be < EArmObjMax).
+ @param [in] NamespaceId The namespace ID which can be EObjNameSpaceArm or
+ EObjNameSpaceArchCommon.
+ @param [in] ObjIndex Index in EARM_OBJECT_ID (must be < EArmObjMax) or
+ EARCH_COMMON_OBJECT_ID (must be <EArchCommonObjMax).
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@@ -200,7 +225,8 @@ EFI_STATUS
EFIAPI
GroupCmObjNodes (
IN DYNAMIC_PLATFORM_REPOSITORY_INFO *This,
- IN UINT32 ArmObjIndex
+ IN EOBJECT_NAMESPACE_ID NamespaceId,
+ IN UINT32 ObjIndex
)
{
EFI_STATUS Status;
@@ -212,19 +238,38 @@ GroupCmObjNodes (
CM_OBJ_DESCRIPTOR *CmObjDesc;
LIST_ENTRY *ListHead;
LIST_ENTRY *Link;
+ CM_OBJ_DESCRIPTOR *ObjArray;
- if ((This == NULL) ||
- (ArmObjIndex >= EArmObjMax))
- {
+ if (This == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (NamespaceId == EObjNameSpaceArm) {
+ if (ObjIndex >= EArmObjMax) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ListHead = &This->ArmCmObjList[ObjIndex];
+ ObjArray = &This->ArmCmObjArray[ObjIndex];
+ } else if (NamespaceId == EObjNameSpaceArchCommon) {
+ if (ObjIndex >= EArchCommonObjMax) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ListHead = &This->ArchCommonCmObjList[ObjIndex];
+ ObjArray = &This->ArchCommonCmObjArray[ObjIndex];
+ } else {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
- Count = 0;
- Size = 0;
- CmObjId = CREATE_CM_ARM_OBJECT_ID (ArmObjIndex);
- ListHead = &This->ArmCmObjList[ArmObjIndex];
- Link = GetFirstNode (ListHead);
+ Count = 0;
+ Size = 0;
+ CmObjId = CREATE_CM_OBJECT_ID (NamespaceId, ObjIndex);
+ Link = GetFirstNode (ListHead);
// Compute the total count and size of the CmObj in the list.
while (Link != ListHead) {
@@ -235,9 +280,12 @@ GroupCmObjNodes (
return EFI_INVALID_PARAMETER;
}
- if ((CmObjDesc->Count != 1) && (ArmObjIndex != EArmObjCmRef)) {
+ if ((CmObjDesc->Count != 1) &&
+ ((NamespaceId != EObjNameSpaceArchCommon) ||
+ (ObjIndex != EArchCommonObjCmRef)))
+ {
// We expect each descriptor to contain an individual object.
- // EArmObjCmRef objects are counted as groups, so +1 as well.
+ // EArchCommonObjCmRef objects are counted as groups, so +1 as well.
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
@@ -286,7 +334,7 @@ GroupCmObjNodes (
Link = GetNextNode (ListHead, Link);
} // while
- CmObjDesc = &This->ArmCmObjArray[ArmObjIndex];
+ CmObjDesc = ObjArray;
CmObjDesc->ObjectId = CmObjId;
CmObjDesc->Size = (UINT32)Size;
CmObjDesc->Count = (UINT32)Count;
@@ -317,7 +365,7 @@ DynamicPlatRepoFinalise (
)
{
EFI_STATUS Status;
- UINTN ArmObjIndex;
+ UINTN ObjIndex;
if ((This == NULL) ||
(This->RepoState != DynRepoTransient))
@@ -340,18 +388,29 @@ DynamicPlatRepoFinalise (
// - Convert the list of nodes to an array
// (the array is wrapped in a CmObjDesc).
// - Add the Token/CmObj binding to the token mapper.
- for (ArmObjIndex = 0; ArmObjIndex < EArmObjMax; ArmObjIndex++) {
- Status = GroupCmObjNodes (This, (UINT32)ArmObjIndex);
+ for (ObjIndex = 0; ObjIndex < EArmObjMax; ObjIndex++) {
+ Status = GroupCmObjNodes (This, EObjNameSpaceArm, (UINT32)ObjIndex);
if (EFI_ERROR (Status)) {
ASSERT (0);
- // Free the TokenMapper.
- // Ignore the returned Status since we already failed.
- TokenMapperShutdown (&This->TokenMapper);
- return Status;
+ goto error_handler;
+ }
+ } // for
+
+ for (ObjIndex = 0; ObjIndex < EArchCommonObjMax; ObjIndex++) {
+ Status = GroupCmObjNodes (This, EObjNameSpaceArchCommon, (UINT32)ObjIndex);
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ goto error_handler;
}
} // for
return EFI_SUCCESS;
+
+error_handler:
+ // Free the TokenMapper.
+ // Ignore the returned Status since we already failed.
+ TokenMapperShutdown (&This->TokenMapper);
+ return Status;
}
/** Get a CmObj from the dynamic repository.
@@ -376,9 +435,10 @@ DynamicPlatRepoGetObject (
IN OUT CM_OBJ_DESCRIPTOR *CmObjDesc
)
{
- EFI_STATUS Status;
- CM_OBJ_DESCRIPTOR *Desc;
- CM_OBJECT_ID ArmNamespaceObjId;
+ EFI_STATUS Status;
+ CM_OBJ_DESCRIPTOR *Desc;
+ CM_OBJECT_ID ObjId;
+ EOBJECT_NAMESPACE_ID NamespaceId;
if ((This == NULL) ||
(CmObjDesc == NULL) ||
@@ -388,8 +448,28 @@ DynamicPlatRepoGetObject (
return EFI_INVALID_PARAMETER;
}
- ArmNamespaceObjId = GET_CM_OBJECT_ID (CmObjectId);
- if (ArmNamespaceObjId >= EArmObjMax) {
+ NamespaceId = GET_CM_NAMESPACE_ID (CmObjectId);
+ ObjId = GET_CM_OBJECT_ID (CmObjectId);
+
+ if (NamespaceId == EObjNameSpaceArm) {
+ if (ObjId >= EArmObjMax) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Desc = &This->ArmCmObjArray[ObjId];
+ } else if (NamespaceId == EObjNameSpaceArchCommon) {
+ if ((ObjId >= EArchCommonObjMax) ||
+ ((ObjId == EArchCommonObjCmRef) &&
+ (Token == CM_NULL_TOKEN)))
+ {
+ // EArchCommonObjCmRef object must be requested using a valid token.
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Desc = &This->ArchCommonCmObjArray[ObjId];
+ } else {
ASSERT (0);
return EFI_INVALID_PARAMETER;
}
@@ -406,14 +486,6 @@ DynamicPlatRepoGetObject (
return Status;
}
- if (ArmNamespaceObjId == EArmObjCmRef) {
- // EArmObjCmRef object must be requested using a valid token.
- ASSERT (0);
- return EFI_INVALID_PARAMETER;
- }
-
- Desc = &This->ArmCmObjArray[ArmNamespaceObjId];
-
// Nothing here.
if (Desc->Count == 0) {
return EFI_NOT_FOUND;
@@ -462,6 +534,10 @@ DynamicPlatRepoInit (
InitializeListHead (&Repo->ArmCmObjList[Index]);
}
+ for (Index = 0; Index < EArchCommonObjMax; Index++) {
+ InitializeListHead (&Repo->ArchCommonCmObjList[Index]);
+ }
+
Repo->ObjectCount = 0;
Repo->RepoState = DynRepoTransient;
@@ -470,31 +546,27 @@ DynamicPlatRepoInit (
return EFI_SUCCESS;
}
-/** Shutdown the dynamic platform repository.
+/** Free Arm Namespace objects.
- Free all the memory allocated for the dynamic platform repository.
+ Free all the memory allocated for the Arm namespace objects in the
+ dynamic platform repository.
@param [in] DynPlatRepo The dynamic platform repository.
- @retval EFI_INVALID_PARAMETER A parameter is invalid.
- @retval EFI_SUCCESS Success.
**/
-EFI_STATUS
+STATIC
+VOID
EFIAPI
-DynamicPlatRepoShutdown (
+DynamicPlatRepoFreeArmObjects (
IN DYNAMIC_PLATFORM_REPOSITORY_INFO *DynPlatRepo
)
{
- EFI_STATUS Status;
UINT32 Index;
LIST_ENTRY *ListHead;
CM_OBJ_DESCRIPTOR *CmObjDesc;
VOID *Data;
- if (DynPlatRepo == NULL) {
- ASSERT (0);
- return EFI_INVALID_PARAMETER;
- }
+ ASSERT (DynPlatRepo != NULL);
// Free the list of objects.
for (Index = 0; Index < EArmObjMax; Index++) {
@@ -513,6 +585,73 @@ DynamicPlatRepoShutdown (
FreePool (Data);
}
} // for
+}
+
+/** Free Arch Common Namespace objects.
+
+ Free all the memory allocated for the Arch Common namespace objects in the
+ dynamic platform repository.
+
+ @param [in] DynPlatRepo The dynamic platform repository.
+
+**/
+STATIC
+VOID
+EFIAPI
+DynamicPlatRepoFreeArchCommonObjects (
+ IN DYNAMIC_PLATFORM_REPOSITORY_INFO *DynPlatRepo
+ )
+{
+ UINT32 Index;
+ LIST_ENTRY *ListHead;
+ CM_OBJ_DESCRIPTOR *CmObjDesc;
+ VOID *Data;
+
+ ASSERT (DynPlatRepo != NULL);
+
+ // Free the list of objects.
+ for (Index = 0; Index < EArchCommonObjMax; Index++) {
+ // Free all the nodes with this object Id.
+ ListHead = &DynPlatRepo->ArchCommonCmObjList[Index];
+ while (!IsListEmpty (ListHead)) {
+ FreeCmObjNode ((CM_OBJ_NODE *)GetFirstNode (ListHead));
+ } // while
+ } // for
+
+ // Free the arrays.
+ CmObjDesc = DynPlatRepo->ArchCommonCmObjArray;
+ for (Index = 0; Index < EArchCommonObjMax; Index++) {
+ Data = CmObjDesc[Index].Data;
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+ } // for
+}
+
+/** Shutdown the dynamic platform repository.
+
+ Free all the memory allocated for the dynamic platform repository.
+
+ @param [in] DynPlatRepo The dynamic platform repository.
+
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_SUCCESS Success.
+**/
+EFI_STATUS
+EFIAPI
+DynamicPlatRepoShutdown (
+ IN DYNAMIC_PLATFORM_REPOSITORY_INFO *DynPlatRepo
+ )
+{
+ EFI_STATUS Status;
+
+ if (DynPlatRepo == NULL) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DynamicPlatRepoFreeArmObjects (DynPlatRepo);
+ DynamicPlatRepoFreeArchCommonObjects (DynPlatRepo);
// Free the TokenMapper
Status = TokenMapperShutdown (&DynPlatRepo->TokenMapper);
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h
index eaee5d4..0c842bc 100644
--- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoInternal.h
@@ -67,7 +67,16 @@ typedef struct DynamicPlatformRepositoryInfo {
/// This array is populated when the Repo is finalized.
CM_OBJ_DESCRIPTOR ArmCmObjArray[EArmObjMax];
- /// A token mapper for the objects in the ArmNamespaceObjectArray
+ /// Link lists of CmObj from the ArchCommon Namespace
+ /// that are added in the Transient state.
+ LIST_ENTRY ArchCommonCmObjList[EArchCommonObjMax];
+
+ /// Structure Members used in Finalized state.
+ /// An array of CmObj Descriptors from the ArchCommon Namespace
+ /// This array is populated when the Repo is finalized.
+ CM_OBJ_DESCRIPTOR ArchCommonCmObjArray[EArchCommonObjMax];
+
+ /// A token mapper for the objects in the <Arm|ArchCommon>CmObjArray
/// The Token mapper is populated when the Repo is finalized in
/// a call to DynamicPlatRepoFinalise ().
TOKEN_MAPPER TokenMapper;
diff --git a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c
index 9391e93..2300375 100644
--- a/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c
+++ b/DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/TokenMapper.c
@@ -66,11 +66,12 @@ TokenMapperAddObject (
// Point inside the finalized array.
CmObjDesc->Data = Data;
- // Only EArmObjCmRef CmObj can be added as arrays (more than 1 elements).
- if ((GET_CM_NAMESPACE_ID (ObjectId) == EObjNameSpaceArm) &&
- (GET_CM_OBJECT_ID (ObjectId) == EArmObjCmRef))
+ // Only EArchCommonObjCmRef CmObj can be added as
+ // arrays (more than 1 elements).
+ if ((GET_CM_NAMESPACE_ID (ObjectId) == EObjNameSpaceArchCommon) &&
+ (GET_CM_OBJECT_ID (ObjectId) == EArchCommonObjCmRef))
{
- CmObjDesc->Count = Size / sizeof (CM_ARM_OBJ_REF);
+ CmObjDesc->Count = Size / sizeof (CM_ARCH_COMMON_OBJ_REF);
} else {
CmObjDesc->Count = 1;
}
diff --git a/DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.c b/DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.c
index b35fb6a..3f8aae4 100644
--- a/DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.c
+++ b/DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.c
@@ -53,10 +53,10 @@
EFI_STATUS
EFIAPI
GeneratePciSlots (
- IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,
- IN CONST MAPPING_TABLE *MappingTable,
- IN UINT32 Uid,
- IN OUT AML_OBJECT_NODE_HANDLE PciNode
+ IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo,
+ IN CONST MAPPING_TABLE *MappingTable,
+ IN UINT32 Uid,
+ IN OUT AML_OBJECT_NODE_HANDLE PciNode
)
{
EFI_STATUS Status;
@@ -132,8 +132,8 @@ GeneratePciSlots (
EFI_STATUS
EFIAPI
AddOscMethod (
- IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO *PciInfo,
- IN OUT AML_OBJECT_NODE_HANDLE PciNode
+ IN CONST CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciInfo,
+ IN OUT AML_OBJECT_NODE_HANDLE PciNode
)
{
EFI_STATUS Status;
diff --git a/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c b/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c
index f2594de..e8eef40 100644
--- a/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c
+++ b/DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.c
@@ -46,7 +46,7 @@ extern CHAR8 ssdtserialporttemplate_aml_code[];
/** Validate the Serial Port Information.
- @param [in] SerialPortInfoTable Table of CM_ARM_SERIAL_PORT_INFO.
+ @param [in] SerialPortInfoTable Table of CM_ARCH_COMMON_SERIAL_PORT_INFO.
@param [in] SerialPortCount Count of SerialPort in the table.
@retval EFI_SUCCESS Success.
@@ -55,12 +55,12 @@ extern CHAR8 ssdtserialporttemplate_aml_code[];
EFI_STATUS
EFIAPI
ValidateSerialPortInfo (
- IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfoTable,
- IN UINT32 SerialPortCount
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfoTable,
+ IN UINT32 SerialPortCount
)
{
- UINT32 Index;
- CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo;
+ UINT32 Index;
+ CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo;
if ((SerialPortInfoTable == NULL) ||
(SerialPortCount == 0))
@@ -163,9 +163,9 @@ STATIC
EFI_STATUS
EFIAPI
FixupIds (
- IN AML_ROOT_NODE_HANDLE RootNodeHandle,
- IN CONST UINT64 Uid,
- IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo
+ IN AML_ROOT_NODE_HANDLE RootNodeHandle,
+ IN CONST UINT64 Uid,
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo
)
{
EFI_STATUS Status;
@@ -290,8 +290,8 @@ STATIC
EFI_STATUS
EFIAPI
FixupCrs (
- IN AML_ROOT_NODE_HANDLE RootNodeHandle,
- IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo
+ IN AML_ROOT_NODE_HANDLE RootNodeHandle,
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo
)
{
EFI_STATUS Status;
@@ -366,9 +366,9 @@ STATIC
EFI_STATUS
EFIAPI
FixupName (
- IN AML_ROOT_NODE_HANDLE RootNodeHandle,
- IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo,
- IN CONST CHAR8 *Name
+ IN AML_ROOT_NODE_HANDLE RootNodeHandle,
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo,
+ IN CONST CHAR8 *Name
)
{
EFI_STATUS Status;
@@ -410,11 +410,11 @@ STATIC
EFI_STATUS
EFIAPI
FixupSerialPortInfo (
- IN AML_ROOT_NODE_HANDLE RootNodeHandle,
- IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo,
- IN CONST CHAR8 *Name,
- IN CONST UINT64 Uid,
- OUT EFI_ACPI_DESCRIPTION_HEADER **Table
+ IN AML_ROOT_NODE_HANDLE RootNodeHandle,
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo,
+ IN CONST CHAR8 *Name,
+ IN CONST UINT64 Uid,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **Table
)
{
EFI_STATUS Status;
@@ -480,11 +480,11 @@ FreeSsdtSerialPortTable (
EFI_STATUS
EFIAPI
BuildSsdtSerialPortTable (
- IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo,
- IN CONST CM_ARM_SERIAL_PORT_INFO *SerialPortInfo,
- IN CONST CHAR8 *Name,
- IN CONST UINT64 Uid,
- OUT EFI_ACPI_DESCRIPTION_HEADER **Table
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo,
+ IN CONST CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo,
+ IN CONST CHAR8 *Name,
+ IN CONST UINT64 Uid,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **Table
)
{
EFI_STATUS Status;
diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
index 69b6eba..0f74f3d 100644
--- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
@@ -2,6 +2,8 @@
Configuration Manager Object parser.
Copyright (c) 2021 - 2023, ARM Limited. All rights reserved.<BR>
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -16,7 +18,8 @@ VOID
EFIAPI
PrintString (
CONST CHAR8 *Format,
- UINT8 *Ptr
+ UINT8 *Ptr,
+ UINT32 Length
);
STATIC
@@ -24,31 +27,26 @@ VOID
EFIAPI
PrintStringPtr (
CONST CHAR8 *Format,
- UINT8 *Ptr
+ UINT8 *Ptr,
+ UINT32 Length
);
STATIC
VOID
EFIAPI
-PrintChar4 (
+PrintChars (
CONST CHAR8 *Format,
- UINT8 *Ptr
+ UINT8 *Ptr,
+ UINT32 Length
);
STATIC
VOID
EFIAPI
-PrintChar6 (
+HexDump (
CONST CHAR8 *Format,
- UINT8 *Ptr
- );
-
-STATIC
-VOID
-EFIAPI
-PrintChar8 (
- CONST CHAR8 *Format,
- UINT8 *Ptr
+ UINT8 *Ptr,
+ UINT32 Length
);
/** A parser for EArmObjBootArchInfo.
@@ -57,9 +55,9 @@ STATIC CONST CM_OBJ_PARSER CmArmBootArchInfoParser[] = {
{ "BootArchFlags", 2, "0x%x", NULL }
};
-/** A parser for EArmObjPowerManagementProfileInfo.
+/** A parser for EArchCommonObjPowerManagementProfileInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmArmPowerManagementProfileInfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonPowerManagementProfileInfoParser[] = {
{ "PowerManagementProfile", 1, "0x%x", NULL }
};
@@ -122,10 +120,10 @@ STATIC CONST CM_OBJ_PARSER CmArmGicItsInfoParser[] = {
{ "ProximityDomain", 4, "0x%x", NULL }
};
-/** A parser for EArmObjSerialConsolePortInfo,
- EArmObjSerialDebugPortInfo and EArmObjSerialPortInfo.
+/** A parser for EArchCommonObjConsolePortInfo,
+ EArchCommonObjSerialDebugPortInfo and EArchCommonObjSerialPortInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmArmSerialPortInfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonSerialPortInfoParser[] = {
{ "BaseAddress", 8, "0x%llx", NULL },
{ "Interrupt", 4, "0x%x", NULL },
{ "BaudRate", 8, "0x%llx", NULL },
@@ -182,9 +180,9 @@ STATIC CONST CM_OBJ_PARSER CmArmGenericWatchdogInfoParser[] = {
{ "Flags", 4, "0x%x", NULL }
};
-/** A parser for EArmObjPciConfigSpaceInfo.
+/** A parser for EArchCommonObjPciConfigSpaceInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmArmPciConfigSpaceInfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonPciConfigSpaceInfoParser[] = {
{ "BaseAddress", 8, "0x%llx", NULL },
{ "PciSegmentGroupNumber", 2, "0x%x", NULL },
{ "StartBusNumber", 1, "0x%x", NULL },
@@ -193,15 +191,15 @@ STATIC CONST CM_OBJ_PARSER CmArmPciConfigSpaceInfoParser[] = {
{ "InterruptMapToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
};
-/** A parser for EArmObjHypervisorVendorIdentity.
+/** A parser for EArchCommonObjHypervisorVendorIdentity.
*/
-STATIC CONST CM_OBJ_PARSER CmArmHypervisorVendorIdParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonHypervisorVendorIdentityParser[] = {
{ "HypervisorVendorId", 8, "0x%llx", NULL }
};
-/** A parser for EArmObjFixedFeatureFlags.
+/** A parser for EArchCommonObjFixedFeatureFlags.
*/
-STATIC CONST CM_OBJ_PARSER CmArmFixedFeatureFlagsParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonFixedFeatureFlagsParser[] = {
{ "Flags", 4, "0x%x", NULL }
};
@@ -317,18 +315,18 @@ STATIC CONST CM_OBJ_PARSER CmArmIdMappingParser[] = {
/** A parser for EArmObjSmmuInterruptArray.
*/
-STATIC CONST CM_OBJ_PARSER CmArmGenericInterruptParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonGenericInterruptParser[] = {
{ "Interrupt", 4, "0x%x", NULL },
{ "Flags", 4, "0x%x", NULL }
};
-/** A parser for EArmObjProcHierarchyInfo.
+/** A parser for EArchCommonObjProcHierarchyInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmArmProcHierarchyInfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonProcHierarchyInfoParser[] = {
{ "Token", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
{ "Flags", 4, "0x%x", NULL },
{ "ParentToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
- { "GicCToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
+ { "AcpiIdObjectToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
{ "NoOfPrivateResources", 4, "0x%x", NULL },
{ "PrivateResourcesArrayToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
{ "LpiToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
@@ -337,9 +335,9 @@ STATIC CONST CM_OBJ_PARSER CmArmProcHierarchyInfoParser[] = {
{ "OverrideUid", 4, "0x%x", NULL }
};
-/** A parser for EArmObjCacheInfo.
+/** A parser for EArchCommonObjCacheInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmArmCacheInfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonCacheInfoParser[] = {
{ "Token", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
{ "NextLevelOfCacheToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
{ "Size", 4, "0x%x", NULL },
@@ -350,52 +348,40 @@ STATIC CONST CM_OBJ_PARSER CmArmCacheInfoParser[] = {
{ "CacheId", 4, "0x%x", NULL },
};
-/** A parser for EArmObjProcNodeIdInfo.
+/** A parser for EArchCommonObjCmRef.
*/
-STATIC CONST CM_OBJ_PARSER CmArmProcNodeIdInfoParser[] = {
- { "Token", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
- { "VendorId", 4, "0x%p", NULL },
- { "Level1Id", 8, "0x%x", NULL },
- { "Level2Id", 8, "0x%x", NULL },
- { "MajorRev", 2, "0x%x", NULL },
- { "MinorRev", 2, "0x%x", NULL },
- { "SpinRev", 2, "0x%x", NULL }
-};
-
-/** A parser for EArmObjCmRef.
-*/
-STATIC CONST CM_OBJ_PARSER CmArmObjRefParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonObjRefParser[] = {
{ "ReferenceToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }
};
-/** A parser for EArmObjMemoryAffinityInfo.
+/** A parser for EArchCommonObjMemoryAffinityInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmArmMemoryAffinityInfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonMemoryAffinityInfoParser[] = {
{ "ProximityDomain", 4, "0x%x", NULL },
{ "BaseAddress", 8, "0x%llx", NULL },
{ "Length", 8, "0x%llx", NULL },
{ "Flags", 4, "0x%x", NULL }
};
-/** A parser for EArmObjDeviceHandleAcpi.
+/** A parser for EArchCommonObjDeviceHandleAcpi.
*/
-STATIC CONST CM_OBJ_PARSER CmArmDeviceHandleAcpiParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonDeviceHandleAcpiParser[] = {
{ "Hid", 8, "0x%llx", NULL },
{ "Uid", 4, "0x%x", NULL }
};
-/** A parser for EArmObjDeviceHandlePci.
+/** A parser for EArchCommonObjDeviceHandlePci.
*/
-STATIC CONST CM_OBJ_PARSER CmArmDeviceHandlePciParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonDeviceHandlePciParser[] = {
{ "SegmentNumber", 2, "0x%x", NULL },
{ "BusNumber", 1, "0x%x", NULL },
{ "DeviceNumber", 1, "0x%x", NULL },
{ "FunctionNumber", 1, "0x%x", NULL }
};
-/** A parser for EArmObjGenericInitiatorAffinityInfo.
+/** A parser for EArchCommonObjGenericInitiatorAffinityInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmArmGenericInitiatorAffinityInfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonGenericInitiatorAffinityInfoParser[] = {
{ "ProximityDomain", 4, "0x%x", NULL },
{ "Flags", 4, "0x%x", NULL },
{ "DeviceHandleType", 1, "0x%x", NULL },
@@ -429,9 +415,9 @@ STATIC CONST CM_OBJ_PARSER AcpiGenericAddressParser[] = {
{ "Address", 8, "0x%llx", NULL },
};
-/** A parser for EArmObjLpiInfo.
+/** A parser for EArchCommonObjLpiInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmArmLpiInfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonLpiInfoParser[] = {
{ "MinResidency", 4, "0x%x", NULL },
{ "WorstCaseWakeLatency", 4, "0x%x", NULL },
{ "Flags", 4, "0x%x", NULL },
@@ -452,24 +438,24 @@ STATIC CONST CM_OBJ_PARSER CmArmLpiInfoParser[] = {
{ "StateName", 16, NULL, PrintString },
};
-/** A parser for EArmObjPciAddressMapInfo.
+/** A parser for EArchCommonObjPciAddressMapInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmArmPciAddressMapInfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonPciAddressMapInfoParser[] = {
{ "SpaceCode", 1, "%d", NULL },
{ "PciAddress", 8, "0x%llx", NULL },
{ "CpuAddress", 8, "0x%llx", NULL },
{ "AddressSize", 8, "0x%llx", NULL },
};
-/** A parser for EArmObjPciInterruptMapInfo.
+/** A parser for EArchCommonObjPciInterruptMapInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmPciInterruptMapInfoParser[] = {
- { "PciBus", 1, "0x%x", NULL },
- { "PciDevice", 1, "0x%x", NULL },
- { "PciInterrupt", 1, "0x%x", NULL },
- { "IntcInterrupt", sizeof (CM_ARM_GENERIC_INTERRUPT),
- NULL, NULL, CmArmGenericInterruptParser,
- ARRAY_SIZE (CmArmGenericInterruptParser) },
+STATIC CONST CM_OBJ_PARSER CmArchCommonPciInterruptMapInfoParser[] = {
+ { "PciBus", 1, "0x%x", NULL },
+ { "PciDevice", 1, "0x%x", NULL },
+ { "PciInterrupt", 1, "0x%x", NULL },
+ { "IntcInterrupt", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT),
+ NULL, NULL, CmArchCommonGenericInterruptParser,
+ ARRAY_SIZE (CmArchCommonGenericInterruptParser) },
};
/** A parser for EArmObjRmr.
@@ -491,9 +477,9 @@ STATIC CONST CM_OBJ_PARSER CmArmMemoryRangeDescriptorInfoParser[] = {
{ "Length", 8, "0x%llx", NULL },
};
-/** A parser for EArmObjCpcInfo.
+/** A parser for EArchCommonObjCpcInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmArmCpcInfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonCpcInfoParser[] = {
{ "Revision", 4, "0x%lx", NULL },
{ "HighestPerformanceBuffer", sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE),
NULL, NULL, AcpiGenericAddressParser,
@@ -586,9 +572,9 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceChannelTimingInfoParser[] = {
{ "MinRequestTurnaroundTime", 2, "0x%x", NULL },
};
-/** A parser for EArmObjPccSubspaceType0Info.
+/** A parser for EArchCommonObjPccSubspaceType0Info.
*/
-STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType0InfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType0InfoParser[] = {
{ "SubspaceId", 1, "0x%x", NULL },
{ "Type", 1, "0x%x", NULL },
{ "BaseAddress", 8, "0x%llx", NULL },
@@ -601,38 +587,38 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType0InfoParser[] = {
ARRAY_SIZE (CmArmPccSubspaceChannelTimingInfoParser) },
};
-/** A parser for EArmObjPccSubspaceType1Info.
+/** A parser for EArchCommonObjPccSubspaceType1Info.
*/
-STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType1InfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType1InfoParser[] = {
{ "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO),
- NULL, NULL, CmArmPccSubspaceType0InfoParser,
- ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
- { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT),
- NULL, NULL, CmArmGenericInterruptParser,
- ARRAY_SIZE (CmArmGenericInterruptParser) },
+ NULL, NULL, CmArchCommonPccSubspaceType0InfoParser,
+ ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) },
+ { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT),
+ NULL, NULL, CmArchCommonGenericInterruptParser,
+ ARRAY_SIZE (CmArchCommonGenericInterruptParser) },
};
-/** A parser for EArmObjPccSubspaceType2Info.
+/** A parser for EArchCommonObjPccSubspaceType2Info.
*/
-STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType2InfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType2InfoParser[] = {
{ "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO),
- NULL, NULL, CmArmPccSubspaceType0InfoParser,
- ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
- { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL,NULL,
- CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) },
+ NULL, NULL, CmArchCommonPccSubspaceType0InfoParser,
+ ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) },
+ { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT),NULL,NULL,
+ CmArchCommonGenericInterruptParser, ARRAY_SIZE (CmArchCommonGenericInterruptParser) },
{ "PlatIrqAckReg", sizeof (PCC_MAILBOX_REGISTER_INFO),
NULL, NULL, CmArmMailboxRegisterInfoParser,
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
};
-/** A parser for EArmObjPccSubspaceType3Info or EArmObjPccSubspaceType4Info.
+/** A parser for EArchCommonObjPccSubspaceType3Info or EArchCommonObjPccSubspaceType4Info.
*/
-STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType34InfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType34InfoParser[] = {
{ "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO),
- NULL, NULL, CmArmPccSubspaceType0InfoParser,
- ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
- { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL,NULL,
- CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) },
+ NULL, NULL, CmArchCommonPccSubspaceType0InfoParser,
+ ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) },
+ { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT),NULL,NULL,
+ CmArchCommonGenericInterruptParser, ARRAY_SIZE (CmArchCommonGenericInterruptParser) },
{ "PlatIrqAckReg", sizeof (PCC_MAILBOX_REGISTER_INFO),
NULL, NULL, CmArmMailboxRegisterInfoParser,
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
@@ -647,15 +633,15 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType34InfoParser[] = {
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
};
-/** A parser for EArmObjPccSubspaceType5Info.
+/** A parser for EArchCommonObjPccSubspaceType5Info.
*/
-STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType5InfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonPccSubspaceType5InfoParser[] = {
{ "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO),
- NULL, NULL, CmArmPccSubspaceType0InfoParser,
- ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
- { "Version", 2, "0x%x",NULL },
- { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL, NULL,
- CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) },
+ NULL, NULL, CmArchCommonPccSubspaceType0InfoParser,
+ ARRAY_SIZE (CmArchCommonPccSubspaceType0InfoParser) },
+ { "Version", 2, "0x%x",NULL },
+ { "PlatIrq", sizeof (CM_ARCH_COMMON_GENERIC_INTERRUPT),NULL, NULL,
+ CmArchCommonGenericInterruptParser, ARRAY_SIZE (CmArchCommonGenericInterruptParser) },
{ "CmdCompleteCheckReg", sizeof (PCC_MAILBOX_REGISTER_INFO),
NULL, NULL, CmArmMailboxRegisterInfoParser,
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
@@ -670,135 +656,249 @@ STATIC CONST CM_OBJ_PARSER CmArmEtInfo[] = {
{ "EtType", sizeof (ARM_ET_TYPE), "0x%x", NULL }
};
-/** A parser for EArmObjPsdInfo.
+/** A parser for EArchCommonObjPsdInfo.
*/
-STATIC CONST CM_OBJ_PARSER CmArmPsdInfoParser[] = {
+STATIC CONST CM_OBJ_PARSER CmArchCommonPsdInfoParser[] = {
{ "Revision", 1, "0x%x", NULL },
{ "DomainId", 4, "0x%x", NULL },
{ "CoordType", 4, "0x%x", NULL },
{ "NumProc", 4, "0x%x", NULL },
};
+/** A parser for EArchCommonObjTpm2InterfaceInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmArchCommonTpm2InterfaceInfo[] = {
+ { "PlatformClass", sizeof (UINT16), "0x%x", NULL },
+ { "AddressOfControlArea", sizeof (UINT64), "0x%llx", NULL },
+ { "StartMethod", sizeof (UINT32), "0x%x", NULL },
+ { "StartMethodParametersSize", sizeof (UINT8), "0x%x", NULL },
+ { "StartMethodParameters", EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE, NULL, HexDump },
+ { "Laml", sizeof (UINT32), "0x%x", NULL },
+ { "Lasa", sizeof (UINT64), "0x%llx", NULL },
+};
+
+/** A parser for Arch Common namespace objects.
+*/
+STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = {
+ CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjReserved),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjPowerManagementProfileInfo, CmArchCommonPowerManagementProfileInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjSerialPortInfo, CmArchCommonSerialPortInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjConsolePortInfo, CmArchCommonSerialPortInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjSerialDebugPortInfo, CmArchCommonSerialPortInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjHypervisorVendorIdentity, CmArchCommonHypervisorVendorIdentityParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjFixedFeatureFlags, CmArchCommonFixedFeatureFlagsParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjCmRef, CmArchCommonObjRefParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjPciConfigSpaceInfo, CmArchCommonPciConfigSpaceInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjPciAddressMapInfo, CmArchCommonPciAddressMapInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjPciInterruptMapInfo, CmArchCommonPciInterruptMapInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjMemoryAffinityInfo, CmArchCommonMemoryAffinityInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandleAcpi, CmArchCommonDeviceHandleAcpiParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjDeviceHandlePci, CmArchCommonDeviceHandlePciParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjGenericInitiatorAffinityInfo,CmArchCommonGenericInitiatorAffinityInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjLpiInfo, CmArchCommonLpiInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjProcHierarchyInfo, CmArchCommonProcHierarchyInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjCacheInfo, CmArchCommonCacheInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjCpcInfo, CmArchCommonCpcInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType0Info, CmArchCommonPccSubspaceType0InfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType1Info, CmArchCommonPccSubspaceType1InfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType2Info, CmArchCommonPccSubspaceType2InfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType3Info, CmArchCommonPccSubspaceType34InfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType4Info, CmArchCommonPccSubspaceType34InfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType5Info, CmArchCommonPccSubspaceType5InfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjPsdInfo, CmArchCommonPsdInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjTpm2InterfaceInfo, CmArchCommonTpm2InterfaceInfo),
+ CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax)
+};
+
/** A parser for Arm namespace objects.
*/
STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
- { "EArmObjReserved", NULL, 0 },
- { "EArmObjBootArchInfo", CmArmBootArchInfoParser,
- ARRAY_SIZE (CmArmBootArchInfoParser) },
- { "EArmObjCpuInfo", NULL, 0 },
- { "EArmObjPowerManagementProfileInfo", CmArmPowerManagementProfileInfoParser,
- ARRAY_SIZE (CmArmPowerManagementProfileInfoParser) },
- { "EArmObjGicCInfo", CmArmGicCInfoParser, ARRAY_SIZE (CmArmGicCInfoParser) },
- { "EArmObjGicDInfo", CmArmGicDInfoParser, ARRAY_SIZE (CmArmGicDInfoParser) },
- { "EArmObjGicMsiFrameInfo", CmArmGicMsiFrameInfoParser,
- ARRAY_SIZE (CmArmGicMsiFrameInfoParser) },
- { "EArmObjGicRedistributorInfo", CmArmGicRedistInfoParser,
- ARRAY_SIZE (CmArmGicRedistInfoParser) },
- { "EArmObjGicItsInfo", CmArmGicItsInfoParser,
- ARRAY_SIZE (CmArmGicItsInfoParser) },
- { "EArmObjSerialConsolePortInfo", CmArmSerialPortInfoParser,
- ARRAY_SIZE (CmArmSerialPortInfoParser) },
- { "EArmObjSerialDebugPortInfo", CmArmSerialPortInfoParser,
- ARRAY_SIZE (CmArmSerialPortInfoParser) },
- { "EArmObjGenericTimerInfo", CmArmGenericTimerInfoParser,
- ARRAY_SIZE (CmArmGenericTimerInfoParser) },
- { "EArmObjPlatformGTBlockInfo", CmArmGTBlockInfoParser,
- ARRAY_SIZE (CmArmGTBlockInfoParser) },
- { "EArmObjGTBlockTimerFrameInfo", CmArmGTBlockTimerFrameInfoParser,
- ARRAY_SIZE (CmArmGTBlockTimerFrameInfoParser) },
- { "EArmObjPlatformGenericWatchdogInfo", CmArmGenericWatchdogInfoParser,
- ARRAY_SIZE (CmArmGenericWatchdogInfoParser) },
- { "EArmObjPciConfigSpaceInfo", CmArmPciConfigSpaceInfoParser,
- ARRAY_SIZE (CmArmPciConfigSpaceInfoParser) },
- { "EArmObjHypervisorVendorIdentity", CmArmHypervisorVendorIdParser,
- ARRAY_SIZE (CmArmHypervisorVendorIdParser) },
- { "EArmObjFixedFeatureFlags", CmArmFixedFeatureFlagsParser,
- ARRAY_SIZE (CmArmFixedFeatureFlagsParser) },
- { "EArmObjItsGroup", CmArmItsGroupNodeParser,
- ARRAY_SIZE (CmArmItsGroupNodeParser) },
- { "EArmObjNamedComponent", CmArmNamedComponentNodeParser,
- ARRAY_SIZE (CmArmNamedComponentNodeParser) },
- { "EArmObjRootComplex", CmArmRootComplexNodeParser,
- ARRAY_SIZE (CmArmRootComplexNodeParser) },
- { "EArmObjSmmuV1SmmuV2", CmArmSmmuV1SmmuV2NodeParser,
- ARRAY_SIZE (CmArmSmmuV1SmmuV2NodeParser) },
- { "EArmObjSmmuV3", CmArmSmmuV3NodeParser,
- ARRAY_SIZE (CmArmSmmuV3NodeParser) },
- { "EArmObjPmcg", CmArmPmcgNodeParser, ARRAY_SIZE (CmArmPmcgNodeParser) },
- { "EArmObjGicItsIdentifierArray", CmArmGicItsIdentifierParser,
- ARRAY_SIZE (CmArmGicItsIdentifierParser) },
- { "EArmObjIdMappingArray", CmArmIdMappingParser,
- ARRAY_SIZE (CmArmIdMappingParser) },
- { "EArmObjSmmuInterruptArray", CmArmGenericInterruptParser,
- ARRAY_SIZE (CmArmGenericInterruptParser) },
- { "EArmObjProcHierarchyInfo", CmArmProcHierarchyInfoParser,
- ARRAY_SIZE (CmArmProcHierarchyInfoParser) },
- { "EArmObjCacheInfo", CmArmCacheInfoParser,
- ARRAY_SIZE (CmArmCacheInfoParser) },
- { "EArmObjProcNodeIdInfo", CmArmProcNodeIdInfoParser,
- ARRAY_SIZE (CmArmProcNodeIdInfoParser) },
- { "EArmObjCmRef", CmArmObjRefParser, ARRAY_SIZE (CmArmObjRefParser) },
- { "EArmObjMemoryAffinityInfo", CmArmMemoryAffinityInfoParser,
- ARRAY_SIZE (CmArmMemoryAffinityInfoParser) },
- { "EArmObjDeviceHandleAcpi", CmArmDeviceHandleAcpiParser,
- ARRAY_SIZE (CmArmDeviceHandleAcpiParser) },
- { "EArmObjDeviceHandlePci", CmArmDeviceHandlePciParser,
- ARRAY_SIZE (CmArmDeviceHandlePciParser) },
- { "EArmObjGenericInitiatorAffinityInfo",
- CmArmGenericInitiatorAffinityInfoParser,
- ARRAY_SIZE (CmArmGenericInitiatorAffinityInfoParser) },
- { "EArmObjSerialPortInfo", CmArmSerialPortInfoParser,
- ARRAY_SIZE (CmArmSerialPortInfoParser) },
- { "EArmObjCmn600Info", CmArmCmn600InfoParser,
- ARRAY_SIZE (CmArmCmn600InfoParser) },
- { "EArmObjLpiInfo", CmArmLpiInfoParser,
- ARRAY_SIZE (CmArmLpiInfoParser) },
- { "EArmObjPciAddressMapInfo", CmArmPciAddressMapInfoParser,
- ARRAY_SIZE (CmArmPciAddressMapInfoParser) },
- { "EArmObjPciInterruptMapInfo", CmPciInterruptMapInfoParser,
- ARRAY_SIZE (CmPciInterruptMapInfoParser) },
- { "EArmObjRmr", CmArmRmrInfoParser,
- ARRAY_SIZE (CmArmRmrInfoParser) },
- { "EArmObjMemoryRangeDescriptor", CmArmMemoryRangeDescriptorInfoParser,
- ARRAY_SIZE (CmArmMemoryRangeDescriptorInfoParser) },
- { "EArmObjCpcInfo", CmArmCpcInfoParser,
- ARRAY_SIZE (CmArmCpcInfoParser) },
- { "EArmObjPccSubspaceType0Info", CmArmPccSubspaceType0InfoParser,
- ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
- { "EArmObjPccSubspaceType1Info", CmArmPccSubspaceType1InfoParser,
- ARRAY_SIZE (CmArmPccSubspaceType1InfoParser) },
- { "EArmObjPccSubspaceType2Info", CmArmPccSubspaceType2InfoParser,
- ARRAY_SIZE (CmArmPccSubspaceType2InfoParser) },
- { "EArmObjPccSubspaceType3Info", CmArmPccSubspaceType34InfoParser,
- ARRAY_SIZE (CmArmPccSubspaceType34InfoParser) },
- { "EArmObjPccSubspaceType4Info", CmArmPccSubspaceType34InfoParser,
- ARRAY_SIZE (CmArmPccSubspaceType34InfoParser) },
- { "EArmObjPccSubspaceType5Info", CmArmPccSubspaceType5InfoParser,
- ARRAY_SIZE (CmArmPccSubspaceType5InfoParser) },
- { "EArmObjEtInfo", CmArmEtInfo,
- ARRAY_SIZE (CmArmEtInfo) },
- { "EArmObjPsdInfo", CmArmPsdInfoParser,
- ARRAY_SIZE (CmArmPsdInfoParser) },
- { "EArmObjMax", NULL, 0 },
+ CM_PARSER_ADD_OBJECT_RESERVED (EArmObjReserved),
+ CM_PARSER_ADD_OBJECT (EArmObjBootArchInfo, CmArmBootArchInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjGicCInfo, CmArmGicCInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjGicDInfo, CmArmGicDInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjGicMsiFrameInfo, CmArmGicMsiFrameInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjGicRedistributorInfo, CmArmGicRedistInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjGicItsInfo, CmArmGicItsInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjGenericTimerInfo, CmArmGenericTimerInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjPlatformGTBlockInfo, CmArmGTBlockInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjGTBlockTimerFrameInfo, CmArmGTBlockTimerFrameInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjPlatformGenericWatchdogInfo,CmArmGenericWatchdogInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjItsGroup, CmArmItsGroupNodeParser),
+ CM_PARSER_ADD_OBJECT (EArmObjNamedComponent, CmArmNamedComponentNodeParser),
+ CM_PARSER_ADD_OBJECT (EArmObjRootComplex, CmArmRootComplexNodeParser),
+ CM_PARSER_ADD_OBJECT (EArmObjSmmuV1SmmuV2, CmArmSmmuV1SmmuV2NodeParser),
+ CM_PARSER_ADD_OBJECT (EArmObjSmmuV3, CmArmSmmuV3NodeParser),
+ CM_PARSER_ADD_OBJECT (EArmObjPmcg, CmArmPmcgNodeParser),
+ CM_PARSER_ADD_OBJECT (EArmObjGicItsIdentifierArray, CmArmGicItsIdentifierParser),
+ CM_PARSER_ADD_OBJECT (EArmObjIdMappingArray, CmArmIdMappingParser),
+ CM_PARSER_ADD_OBJECT (EArmObjSmmuInterruptArray, CmArchCommonGenericInterruptParser),
+ CM_PARSER_ADD_OBJECT (EArmObjCmn600Info, CmArmCmn600InfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjRmr, CmArmRmrInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjMemoryRangeDescriptor, CmArmMemoryRangeDescriptorInfoParser),
+ CM_PARSER_ADD_OBJECT (EArmObjEtInfo, CmArmEtInfo),
+ CM_PARSER_ADD_OBJECT_RESERVED (EArmObjMax)
+};
+
+/** A parser for EX64ObjFadtSciInterrupt.
+*/
+STATIC CONST CM_OBJ_PARSER CmX64ObjFadtSciInterruptParser[] = {
+ { "SciInterrupt", 2, "0x%x", NULL }
+};
+
+/** A parser for EX64ObjFadtSciCmdInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmX64ObjFadtSciCmdInfoParser[] = {
+ { "SciCmd", 4, "0x%x", NULL },
+ { "AcpiEnable", 1, "0x%x", NULL },
+ { "AcpiDisable", 1, "0x%x", NULL },
+ { "S4BiosReq", 1, "0x%x", NULL },
+ { "PstateCnt", 1, "0x%x", NULL },
+ { "CstCnt", 1, "0x%x", NULL }
+};
+
+/** A parser for EX64ObjFadtPmBlockInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmX64ObjFadtPmBlockInfoParser[] = {
+ { "Pm1aEvtBlk", 4, "0x%x", NULL },
+ { "Pm1bEvtBlk", 4, "0x%x", NULL },
+ { "Pm1aCntBlk", 4, "0x%x", NULL },
+ { "Pm1bCntBlk", 4, "0x%x", NULL },
+ { "Pm2CntBlk", 4, "0x%x", NULL },
+ { "PmTmrBlk", 4, "0x%x", NULL },
+ { "Pm1EvtLen", 1, "0x%x", NULL },
+ { "Pm1CntLen", 1, "0x%x", NULL },
+ { "Pm2CntLen", 1, "0x%x", NULL },
+ { "PmTmrLen", 1, "0x%x", NULL }
+};
+
+/** A parser for EX64ObjFadtGpeBlockInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmX64ObjFadtGpeBlockInfoParser[] = {
+ { "Gpe0Blk", 4, "0x%x", NULL },
+ { "Gpe1Blk", 4, "0x%x", NULL },
+ { "Gpe0BlkLen", 1, "0x%x", NULL },
+ { "Gpe1BlkLen", 1, "0x%x", NULL },
+ { "Gpe1Base", 1, "0x%x", NULL }
+};
+
+/** A parser for EX64ObjFadtXpmBlockInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmX64ObjFadtXpmBlockInfoParser[] = {
+ { "XPm1aEvtBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "XPm1bEvtBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "XPm1aCntBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "XPm1bCntBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "XPm2CntBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "XPmTmrBlk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) }
+};
+
+/** A parser for EX64ObjFadtXgpeBlockInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmX64ObjFadtXgpeBlockInfoParser[] = {
+ { "XGpe0Blk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "XGpe1Blk", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) }
+};
+
+/** A parser for EX64ObjFadtSleepBlockInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmX64ObjFadtSleepBlockInfoParser[] = {
+ { "SleepControlReg", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "SleepStatusReg", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) }
+};
+
+/** A parser for EX64ObjFadtResetBlockInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmX64ObjFadtResetBlockInfoParser[] = {
+ { "ResetReg", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "ResetValue", 1, "0x%x",NULL }
+};
+
+/** A parser for EX64ObjFadtMiscInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmX64ObjFadtMiscInfoParser[] = {
+ { "PLvl2Lat", 2, "0x%x", NULL },
+ { "PLvl3Lat", 2, "0x%x", NULL },
+ { "FlushSize", 2, "0x%x", NULL },
+ { "FlushStride", 2, "0x%x", NULL },
+ { "DutyOffset", 1, "0x%x", NULL },
+ { "DutyWidth", 1, "0x%x", NULL },
+ { "DayAlrm", 1, "0x%x", NULL },
+ { "MonAlrm", 1, "0x%x", NULL },
+ { "Century", 1, "0x%x", NULL }
+};
+
+/** A parser for EX64ObjWsmtFlagsInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmX64ObjWsmtFlagsInfoParser[] = {
+ { "WsmtFlags", 4, "0x%x", NULL }
+};
+
+/** A parser for EX64ObjHpetInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmX64ObjHpetInfoParser[] = {
+ { "BaseAddressLower32Bit", 4, "0x%x", NULL },
+ { "MainCounterMinimumClockTickInPeriodicMode", 2, "0x%x", NULL },
+ { "PageProtectionAndOemAttribute", 1, "0x%x", NULL }
+};
+
+/** A parser for X64 namespace objects.
+*/
+STATIC CONST CM_OBJ_PARSER_ARRAY X64NamespaceObjectParser[] = {
+ CM_PARSER_ADD_OBJECT_RESERVED (EX64ObjReserved),
+ CM_PARSER_ADD_OBJECT (EX64ObjFadtSciInterrupt, CmX64ObjFadtSciInterruptParser),
+ CM_PARSER_ADD_OBJECT (EX64ObjFadtSciCmdInfo, CmX64ObjFadtSciCmdInfoParser),
+ CM_PARSER_ADD_OBJECT (EX64ObjFadtPmBlockInfo, CmX64ObjFadtPmBlockInfoParser),
+ CM_PARSER_ADD_OBJECT (EX64ObjFadtGpeBlockInfo, CmX64ObjFadtGpeBlockInfoParser),
+ CM_PARSER_ADD_OBJECT (EX64ObjFadtXpmBlockInfo, CmX64ObjFadtXpmBlockInfoParser),
+ CM_PARSER_ADD_OBJECT (EX64ObjFadtXgpeBlockInfo, CmX64ObjFadtXgpeBlockInfoParser),
+ CM_PARSER_ADD_OBJECT (EX64ObjFadtSleepBlockInfo,CmX64ObjFadtSleepBlockInfoParser),
+ CM_PARSER_ADD_OBJECT (EX64ObjFadtResetBlockInfo,CmX64ObjFadtResetBlockInfoParser),
+ CM_PARSER_ADD_OBJECT (EX64ObjFadtMiscInfo, CmX64ObjFadtMiscInfoParser),
+ CM_PARSER_ADD_OBJECT (EX64ObjWsmtFlagsInfo, CmX64ObjWsmtFlagsInfoParser),
+ CM_PARSER_ADD_OBJECT (EX64ObjHpetInfo, CmX64ObjHpetInfoParser),
+ CM_PARSER_ADD_OBJECT_RESERVED (EX64ObjMax)
};
/** A parser for EStdObjCfgMgrInfo.
*/
STATIC CONST CM_OBJ_PARSER StdObjCfgMgrInfoParser[] = {
- { "Revision", 4, "0x%x", NULL },
- { "OemId[6]", 6, "%c%c%c%c%c%c", PrintChar6 }
+ { "Revision", 4, "0x%x", NULL },
+ { "OemId[6]", 6, NULL, PrintChars }
};
/** A parser for EStdObjAcpiTableList.
*/
STATIC CONST CM_OBJ_PARSER StdObjAcpiTableInfoParser[] = {
- { "AcpiTableSignature", 4, "%c%c%c%c", PrintChar4 },
- { "AcpiTableRevision", 1, "%d", NULL },
- { "TableGeneratorId", sizeof (ACPI_TABLE_GENERATOR_ID), "0x%x", NULL },
- { "AcpiTableData", sizeof (EFI_ACPI_DESCRIPTION_HEADER *), "0x%p", NULL },
- { "OemTableId", 8, "%c%c%c%c%c%c%c%c", PrintChar8 },
- { "OemRevision", 4, "0x%x", NULL },
- { "MinorRevision", 1, "0x%x", NULL },
+ { "AcpiTableSignature", 4, NULL, PrintChars },
+ { "AcpiTableRevision", 1, "%d", NULL },
+ { "TableGeneratorId", sizeof (ACPI_TABLE_GENERATOR_ID), "0x%x", NULL },
+ { "AcpiTableData", sizeof (EFI_ACPI_DESCRIPTION_HEADER *), "0x%p", NULL },
+ { "OemTableId", 8, NULL, PrintChars },
+ { "OemRevision", 4, "0x%x", NULL },
+ { "MinorRevision", 1, "0x%x", NULL },
};
/** A parser for EStdObjSmbiosTableList.
@@ -811,13 +911,10 @@ STATIC CONST CM_OBJ_PARSER StdObjSmbiosTableInfoParser[] = {
/** A parser for Standard namespace objects.
*/
STATIC CONST CM_OBJ_PARSER_ARRAY StdNamespaceObjectParser[] = {
- { "EStdObjCfgMgrInfo", StdObjCfgMgrInfoParser,
- ARRAY_SIZE (StdObjCfgMgrInfoParser) },
- { "EStdObjAcpiTableList", StdObjAcpiTableInfoParser,
- ARRAY_SIZE (StdObjAcpiTableInfoParser) },
- { "EStdObjSmbiosTableList", StdObjSmbiosTableInfoParser,
- ARRAY_SIZE (StdObjSmbiosTableInfoParser) },
- { "EStdObjMax", NULL, 0}
+ CM_PARSER_ADD_OBJECT (EStdObjCfgMgrInfo, StdObjCfgMgrInfoParser),
+ CM_PARSER_ADD_OBJECT (EStdObjAcpiTableList, StdObjAcpiTableInfoParser),
+ CM_PARSER_ADD_OBJECT (EStdObjSmbiosTableList, StdObjSmbiosTableInfoParser),
+ CM_PARSER_ADD_OBJECT_RESERVED (EStdObjMax)
};
/** Print string data.
@@ -826,13 +923,15 @@ STATIC CONST CM_OBJ_PARSER_ARRAY StdNamespaceObjectParser[] = {
@param [in] Format Format to print the Ptr.
@param [in] Ptr Pointer to the string.
+ @param [in] Length Length of the field
**/
STATIC
VOID
EFIAPI
PrintString (
IN CONST CHAR8 *Format,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
if (Ptr == NULL) {
@@ -840,7 +939,7 @@ PrintString (
return;
}
- DEBUG ((DEBUG_ERROR, "%a", Ptr));
+ DEBUG ((DEBUG_INFO, "%a", Ptr));
}
/** Print string from pointer.
@@ -849,13 +948,15 @@ PrintString (
@param [in] Format Format to print the string.
@param [in] Ptr Pointer to the string pointer.
+ @param [in] Length Length of the field
**/
STATIC
VOID
EFIAPI
PrintStringPtr (
IN CONST CHAR8 *Format,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
UINT8 *String;
@@ -871,82 +972,51 @@ PrintStringPtr (
String = (UINT8 *)"(NULLPTR)";
}
- PrintString (Format, String);
+ PrintString (Format, String, Length);
}
-/** Print 4 characters.
+/** Print characters.
@param [in] Format Format to print the Ptr.
@param [in] Ptr Pointer to the characters.
+ @param [in] Length Length of the field
**/
STATIC
VOID
EFIAPI
-PrintChar4 (
+PrintChars (
IN CONST CHAR8 *Format,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
- DEBUG ((
- DEBUG_ERROR,
- (Format != NULL) ? Format : "%c%c%c%c",
- Ptr[0],
- Ptr[1],
- Ptr[2],
- Ptr[3]
- ));
-}
-
-/** Print 6 characters.
+ UINT32 Index;
- @param [in] Format Format to print the Ptr.
- @param [in] Ptr Pointer to the characters.
-**/
-STATIC
-VOID
-EFIAPI
-PrintChar6 (
- IN CONST CHAR8 *Format,
- IN UINT8 *Ptr
- )
-{
- DEBUG ((
- DEBUG_ERROR,
- (Format != NULL) ? Format : "%c%c%c%c%c%c",
- Ptr[0],
- Ptr[1],
- Ptr[2],
- Ptr[3],
- Ptr[4],
- Ptr[5]
- ));
+ for (Index = 0; Index < Length; Index++) {
+ DEBUG ((DEBUG_INFO, "%c", Ptr[Index]));
+ }
}
-/** Print 8 characters.
+/** Dump data in Hex format
@param [in] Format Format to print the Ptr.
- @param [in] Ptr Pointer to the characters.
+ @param [in] Ptr Pointer to the string.
+ @param [in] Length Length of the field
**/
STATIC
VOID
EFIAPI
-PrintChar8 (
- IN CONST CHAR8 *Format,
- IN UINT8 *Ptr
+HexDump (
+ IN CONST CHAR8 *Format,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
- DEBUG ((
- DEBUG_ERROR,
- (Format != NULL) ? Format : "%c%c%c%c%c%c%c%c",
- Ptr[0],
- Ptr[1],
- Ptr[2],
- Ptr[3],
- Ptr[4],
- Ptr[5],
- Ptr[6],
- Ptr[7]
- ));
+ UINT32 Index;
+
+ for (Index = 0; Index < Length; Index++) {
+ DEBUG ((DEBUG_INFO, "0x%02x ", *Ptr++));
+ }
}
/** Print fields of the objects.
@@ -988,7 +1058,7 @@ PrintCmObjDesc (
*RemainingSize -= Parser[Index].Length;
if (*RemainingSize < 0) {
DEBUG ((
- DEBUG_INFO,
+ DEBUG_ERROR,
"\nERROR: %a: Buffer overrun\n",
Parser[Index].NameStr
));
@@ -1008,7 +1078,7 @@ PrintCmObjDesc (
Parser[Index].NameStr
));
if (Parser[Index].PrintFormatter != NULL) {
- Parser[Index].PrintFormatter (Parser[Index].Format, Data);
+ Parser[Index].PrintFormatter (Parser[Index].Format, Data, Parser[Index].Length);
} else if (Parser[Index].Format != NULL) {
switch (Parser[Index].Length) {
case 1:
@@ -1111,6 +1181,37 @@ ParseCmObjDesc (
ParserArray = &ArmNamespaceObjectParser[ObjId];
break;
+
+ case EObjNameSpaceArchCommon:
+ if (ObjId >= EArchCommonObjMax) {
+ ASSERT (0);
+ return;
+ }
+
+ if (ObjId >= ARRAY_SIZE (ArchCommonNamespaceObjectParser)) {
+ DEBUG ((DEBUG_ERROR, "ObjId 0x%x is missing from the ArchCommonNamespaceObjectParser array\n", ObjId));
+ ASSERT (0);
+ return;
+ }
+
+ ParserArray = &ArchCommonNamespaceObjectParser[ObjId];
+ break;
+
+ case EObjNameSpaceX64:
+ if (ObjId >= EX64ObjMax) {
+ ASSERT (0);
+ return;
+ }
+
+ if (ObjId >= ARRAY_SIZE (X64NamespaceObjectParser)) {
+ DEBUG ((DEBUG_ERROR, "ObjId 0x%x is missing from the X64NamespaceObjectParser array\n", ObjId));
+ ASSERT (0);
+ return;
+ }
+
+ ParserArray = &X64NamespaceObjectParser[ObjId];
+ break;
+
default:
// Not supported
DEBUG ((DEBUG_ERROR, "NameSpaceId 0x%x, ObjId 0x%x is not supported by the parser\n", NameSpaceId, ObjId));
@@ -1131,6 +1232,9 @@ ParseCmObjDesc (
ObjIndex + 1,
ObjectCount
));
+
+ ASSERT (ObjId == ParserArray->ObjectId);
+
if (ParserArray->Parser == NULL) {
DEBUG ((DEBUG_ERROR, "Parser not implemented\n"));
RemainingSize = 0;
diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h
index 3204f53..3ec82d2 100644
--- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.h
@@ -2,6 +2,7 @@
Configuration Manager Object parser.
Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+ Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -11,13 +12,26 @@
#define OUTPUT_FIELD_COLUMN_WIDTH 32
+/** A helper macro for populating the Reserved objects
+ like EArmObjReserved, EArmObjMax, etc. in the CM_OBJ_PARSER_ARRAY.
+**/
+#define CM_PARSER_ADD_OBJECT_RESERVED(ObjectId) \
+ {ObjectId, #ObjectId, NULL, 0}
+
+/** A helper macro for populating the Cm Arm objects
+ in the CM_OBJ_PARSER_ARRAY.
+**/
+#define CM_PARSER_ADD_OBJECT(ObjectId, Parser) \
+ {ObjectId, #ObjectId, Parser, ARRAY_SIZE(Parser) }
+
/** Function prototype to format a field print.
@param [in] Format Format string for tracing the data as specified by
the 'Format' member of ACPI_PARSER.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field
**/
-typedef VOID (EFIAPI *FNPTR_PRINT_FORMATTER)(CONST CHAR8 *Format, UINT8 *Ptr);
+typedef VOID (EFIAPI *FNPTR_PRINT_FORMATTER)(CONST CHAR8 *Format, UINT8 *Ptr, UINT32 Length);
/**
The CM_OBJ_PARSER structure describes the fields of an CmObject and
@@ -58,6 +72,9 @@ struct CmObjParser {
with their object names.
*/
typedef struct CmObjParserArray {
+ /// Object ID
+ CONST UINTN ObjectId;
+
/// Object name
CONST CHAR8 *ObjectName;
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c
new file mode 100644
index 0000000..2c9105e
--- /dev/null
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtHwInfoParser.c
@@ -0,0 +1,83 @@
+/** @file
+ Arm Flattened Device Tree parser library for KvmTool.
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "FdtHwInfoParser.h"
+#include "Arm/BootArch/ArmBootArchParser.h"
+#include "Arm/GenericTimer/ArmGenericTimerParser.h"
+#include "Arm/Gic/ArmGicDispatcher.h"
+#include "Pci/PciConfigSpaceParser.h"
+#include "Serial/SerialPortParser.h"
+
+/** Ordered table of parsers/dispatchers.
+
+ A parser parses a Device Tree to populate a specific CmObj type. None,
+ one or many CmObj can be created by the parser.
+ The created CmObj are then handed to the parser's caller through the
+ HW_INFO_ADD_OBJECT interface.
+ This can also be a dispatcher. I.e. a function that not parsing a
+ Device Tree but calling other parsers.
+*/
+STATIC CONST FDT_HW_INFO_PARSER_FUNC HwInfoParserTable[] = {
+ ArmBootArchInfoParser,
+ ArmGenericTimerInfoParser,
+ ArmGicDispatcher,
+ PciConfigInfoParser,
+ SerialPortDispatcher
+};
+
+/** Main dispatcher: sequentially call the parsers/dispatchers
+ of the HwInfoParserTable.
+
+ A parser parses a Device Tree to populate a specific CmObj type. None,
+ one or many CmObj can be created by the parser.
+ The created CmObj are then handed to the parser's caller through the
+ HW_INFO_ADD_OBJECT interface.
+ This can also be a dispatcher. I.e. a function that not parsing a
+ Device Tree but calling other parsers.
+
+ @param [in] FdtParserHandle A handle to the parser instance.
+ @param [in] FdtBranch When searching for DT node name, restrict
+ the search to this Device Tree branch.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+ @retval EFI_UNSUPPORTED Unsupported.
+**/
+EFI_STATUS
+EFIAPI
+ArchFdtHwInfoMainDispatcher (
+ IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
+ IN INT32 FdtBranch
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+
+ if (fdt_check_header (FdtParserHandle->Fdt) < 0) {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Index = 0; Index < ARRAY_SIZE (HwInfoParserTable); Index++) {
+ Status = HwInfoParserTable[Index](
+ FdtParserHandle,
+ FdtBranch
+ );
+ if (EFI_ERROR (Status) &&
+ (Status != EFI_NOT_FOUND))
+ {
+ // If EFI_NOT_FOUND, the parser didn't find information in the DT.
+ // Don't trigger an error.
+ ASSERT (0);
+ return Status;
+ }
+ } // for
+
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c
new file mode 100644
index 0000000..71774fa
--- /dev/null
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/ArmFdtInterrupt.c
@@ -0,0 +1,118 @@
+/** @file
+ Flattened device tree utility.
+
+ Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - Device tree Specification - Release v0.3
+ - linux/Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml
+ - linux//Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml
+**/
+
+#include <FdtHwInfoParserInclude.h>
+#include "FdtUtility.h"
+
+/** Get the interrupt Id of an interrupt described in a fdt.
+
+ Data must describe a GIC interrupt. A GIC interrupt is on at least
+ 3 UINT32 cells.
+ This function DOES NOT SUPPORT extended SPI range and extended PPI range.
+
+ @param [in] Data Pointer to the first cell of an "interrupts" property.
+
+ @retval The interrupt id.
+**/
+UINT32
+EFIAPI
+FdtGetInterruptId (
+ UINT32 CONST *Data
+ )
+{
+ UINT32 IrqType;
+ UINT32 IrqId;
+
+ ASSERT (Data != NULL);
+
+ IrqType = fdt32_to_cpu (Data[IRQ_TYPE_OFFSET]);
+ IrqId = fdt32_to_cpu (Data[IRQ_NUMBER_OFFSET]);
+
+ switch (IrqType) {
+ case DT_SPI_IRQ:
+ IrqId += SPI_OFFSET;
+ break;
+
+ case DT_PPI_IRQ:
+ IrqId += PPI_OFFSET;
+ break;
+
+ default:
+ ASSERT (0);
+ IrqId = 0;
+ }
+
+ return IrqId;
+}
+
+/** Get the ACPI interrupt flags of an interrupt described in a fdt.
+
+ Data must describe a GIC interrupt. A GIC interrupt is on at least
+ 3 UINT32 cells.
+
+ PPI interrupt cpu mask on bits [15:8] are ignored.
+
+ @param [in] Data Pointer to the first cell of an "interrupts" property.
+
+ @retval The interrupt flags (for ACPI).
+**/
+UINT32
+EFIAPI
+FdtGetInterruptFlags (
+ UINT32 CONST *Data
+ )
+{
+ UINT32 IrqFlags;
+ UINT32 AcpiIrqFlags;
+
+ ASSERT (Data != NULL);
+
+ IrqFlags = fdt32_to_cpu (Data[IRQ_FLAGS_OFFSET]);
+
+ AcpiIrqFlags = DT_IRQ_IS_EDGE_TRIGGERED (IrqFlags) ? BIT0 : 0;
+ AcpiIrqFlags |= DT_IRQ_IS_ACTIVE_LOW (IrqFlags) ? BIT1 : 0;
+
+ return AcpiIrqFlags;
+}
+
+/** For relevant architectures, get the "#address-cells" and/or "#size-cells"
+ property of the node.
+
+ According to the Device Tree specification, s2.3.5 "#address-cells and
+ #size-cells":
+ "If missing, a client program should assume a default value of 2 for
+ #address-cells, and a value of 1 for #size-cells."
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node having to get the
+ "#address-cells" and "#size-cells"
+ properties from.
+ @param [out] AddressCells If success, number of address-cells.
+ If the property is not available,
+ default value is 2.
+ @param [out] SizeCells If success, number of size-cells.
+ If the property is not available,
+ default value is 1.
+
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetIntcAddressCells (
+ IN CONST VOID *Fdt,
+ IN INT32 Node,
+ OUT INT32 *AddressCells, OPTIONAL
+ OUT INT32 *SizeCells OPTIONAL
+ )
+{
+ return FdtGetAddressInfo (Fdt, Node, AddressCells, SizeCells);
+}
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.c
index b07b6b8..b5c42d8 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.c
@@ -8,9 +8,11 @@
- linux/Documentation/devicetree/bindings/arm/psci.yaml
**/
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
#include "FdtHwInfoParser.h"
#include "CmObjectDescUtility.h"
-#include "BootArch/ArmBootArchParser.h"
+#include "Arm/BootArch/ArmBootArchParser.h"
/** List of "compatible" property values for Psci nodes.
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.h
index 51654f0..51654f0 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/BootArch/ArmBootArchParser.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/BootArch/ArmBootArchParser.h
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.c
index 988a812..c79ad92 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.c
@@ -8,10 +8,11 @@
- linux/Documentation/devicetree/bindings/timer/arm,arch_timer.yaml
**/
+#include <Library/BaseMemoryLib.h>
#include "FdtHwInfoParser.h"
#include "CmObjectDescUtility.h"
-#include "GenericTimer/ArmGenericTimerParser.h"
-#include "Gic/ArmGicDispatcher.h"
+#include "Arm/GenericTimer/ArmGenericTimerParser.h"
+#include "Arm/Gic/ArmGicDispatcher.h"
/** List of "compatible" property values for timer nodes.
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.h
index d7fa278..d7fa278 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/GenericTimer/ArmGenericTimerParser.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/GenericTimer/ArmGenericTimerParser.h
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c
index ee82f7a..3955219 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.c
@@ -11,10 +11,11 @@
- linux/Documentation/devicetree/bindings/arm/pmu.yaml
**/
+#include <Library/ArmLib.h>
#include "FdtHwInfoParser.h"
#include "CmObjectDescUtility.h"
-#include "Gic/ArmGicCParser.h"
-#include "Gic/ArmGicDispatcher.h"
+#include "Arm/Gic/ArmGicCParser.h"
+#include "Arm/Gic/ArmGicDispatcher.h"
/** List of "compatible" property values for CPU nodes.
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.h
index 539f39c..539f39c 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicCParser.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicCParser.h
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.c
index b7f5696..d59219f 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.c
@@ -9,10 +9,11 @@
- linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
**/
+#include <Library/BaseMemoryLib.h>
#include "CmObjectDescUtility.h"
#include "FdtHwInfoParser.h"
-#include "Gic/ArmGicDispatcher.h"
-#include "Gic/ArmGicDParser.h"
+#include "Arm/Gic/ArmGicDispatcher.h"
+#include "Arm/Gic/ArmGicDParser.h"
/** Parse a Gic compatible interrupt-controller node,
extracting GicD information.
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.h
index b9581f0..b9581f0 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDParser.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDParser.h
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.c
index 1f3af1f..ca34d24 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.c
@@ -10,12 +10,12 @@
**/
#include "FdtHwInfoParser.h"
-#include "Gic/ArmGicCParser.h"
-#include "Gic/ArmGicDispatcher.h"
-#include "Gic/ArmGicDParser.h"
-#include "Gic/ArmGicItsParser.h"
-#include "Gic/ArmGicMsiFrameParser.h"
-#include "Gic/ArmGicRParser.h"
+#include "Arm/Gic/ArmGicCParser.h"
+#include "Arm/Gic/ArmGicDispatcher.h"
+#include "Arm/Gic/ArmGicDParser.h"
+#include "Arm/Gic/ArmGicItsParser.h"
+#include "Arm/Gic/ArmGicMsiFrameParser.h"
+#include "Arm/Gic/ArmGicRParser.h"
/** List of "compatible" property values for GicV2 interrupt nodes.
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.h
index aa942f7..aa942f7 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicDispatcher.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicDispatcher.h
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.c
index f23818f..253c221 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.c
@@ -8,10 +8,11 @@
- linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
**/
+#include <Library/BaseMemoryLib.h>
#include "CmObjectDescUtility.h"
#include "FdtHwInfoParser.h"
-#include "Gic/ArmGicDispatcher.h"
-#include "Gic/ArmGicItsParser.h"
+#include "Arm/Gic/ArmGicDispatcher.h"
+#include "Arm/Gic/ArmGicItsParser.h"
/** Parse a Gic compatible interrupt-controller node,
extracting GicIts information.
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.h
index be94449..be94449 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicItsParser.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicItsParser.h
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.c
index c474cb2..daadcec 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.c
@@ -9,10 +9,11 @@
- linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
**/
+#include <Library/BaseMemoryLib.h>
#include "CmObjectDescUtility.h"
#include "FdtHwInfoParser.h"
-#include "Gic/ArmGicDispatcher.h"
-#include "Gic/ArmGicMsiFrameParser.h"
+#include "Arm/Gic/ArmGicDispatcher.h"
+#include "Arm/Gic/ArmGicMsiFrameParser.h"
/** List of "compatible" property values for Msi-frame nodes.
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.h
index 2821a78..2821a78 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicMsiFrameParser.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicMsiFrameParser.h
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.c
index 0f9c7bb..1c5bc97 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.c
@@ -8,10 +8,11 @@
- linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
**/
+#include <Library/BaseMemoryLib.h>
#include "CmObjectDescUtility.h"
#include "FdtHwInfoParser.h"
-#include "Gic/ArmGicDispatcher.h"
-#include "Gic/ArmGicRParser.h"
+#include "Arm/Gic/ArmGicDispatcher.h"
+#include "Arm/Gic/ArmGicRParser.h"
/** Parse a Gic compatible interrupt-controller node,
extracting GicR information.
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.h
index c2b7eab..c2b7eab 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Gic/ArmGicRParser.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Arm/Gic/ArmGicRParser.h
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c
index 8be1b5b..120a98c 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.c
@@ -219,11 +219,11 @@ AddMultipleCmObj (
/** Add multiple CmObj to the Configuration Manager.
- Get one token referencing a EArmObjCmRef CmObj itself referencing
+ Get one token referencing a EArchCommonObjCmRef CmObj itself referencing
the input CmObj. In the table below, RefToken is returned.
Token referencing an Array of tokens Array of CmObj
- array of EArmObjCmRef referencing each from the input:
+ array of EArchCommonObjCmRef referencing each from the input:
CmObj: CmObj from the input:
RefToken ---> CmObjToken[0] ---> CmObj[0]
@@ -234,7 +234,7 @@ AddMultipleCmObj (
@param [in] CmObjDesc CmObjDesc containing multiple CmObj
to add.
@param [out] Token If success, token referencing an array
- of EArmObjCmRef CmObj, themselves
+ of EArchCommonObjCmRef CmObj, themselves
referencing the input CmObjs.
@retval EFI_SUCCESS The function completed successfully.
@@ -286,12 +286,12 @@ AddMultipleCmObjWithCmObjRef (
goto exit_handler;
}
- CmObjRef.ObjectId = CREATE_CM_ARM_OBJECT_ID (EArmObjCmRef);
+ CmObjRef.ObjectId = CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjCmRef);
CmObjRef.Data = TokenTable;
CmObjRef.Count = CmObjDesc->Count;
CmObjRef.Size = TokenTableSize;
- // Add the array of EArmObjCmRef CmObjs.
+ // Add the array of EArchCommonObjCmRef CmObjs.
Status = FdtParserHandle->HwInfoAdd (
FdtParserHandle,
FdtParserHandle->Context,
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h
index 270e0c3..14e1353 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/CmObjectDescUtility.h
@@ -98,11 +98,11 @@ AddMultipleCmObj (
/** Add multiple CmObj to the Configuration Manager.
- Get one token referencing a EArmObjCmRef CmObj itself referencing
+ Get one token referencing a EArchCommonObjCmRef CmObj itself referencing
the input CmObj. In the table below, RefToken is returned.
Token referencing an Array of tokens Array of CmObj
- array of EArmObjCmRef referencing each from the input:
+ array of EArchCommonObjCmRef referencing each from the input:
CmObj: CmObj from the input:
RefToken ---> CmObjToken[0] ---> CmObj[0]
@@ -113,7 +113,7 @@ AddMultipleCmObj (
@param [in] CmObjDesc CmObjDesc containing multiple CmObj
to add.
@param [out] Token If success, token referencing an array
- of EArmObjCmRef CmObj, themselves
+ of EArchCommonObjCmRef CmObj, themselves
referencing the input CmObjs.
@retval EFI_SUCCESS The function completed successfully.
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c
index 376de07..8e980da 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c
@@ -6,82 +6,6 @@
**/
#include "FdtHwInfoParser.h"
-#include "BootArch/ArmBootArchParser.h"
-#include "GenericTimer/ArmGenericTimerParser.h"
-#include "Gic/ArmGicDispatcher.h"
-#include "Pci/ArmPciConfigSpaceParser.h"
-#include "Serial/ArmSerialPortParser.h"
-
-/** Ordered table of parsers/dispatchers.
-
- A parser parses a Device Tree to populate a specific CmObj type. None,
- one or many CmObj can be created by the parser.
- The created CmObj are then handed to the parser's caller through the
- HW_INFO_ADD_OBJECT interface.
- This can also be a dispatcher. I.e. a function that not parsing a
- Device Tree but calling other parsers.
-*/
-STATIC CONST FDT_HW_INFO_PARSER_FUNC HwInfoParserTable[] = {
- ArmBootArchInfoParser,
- ArmGenericTimerInfoParser,
- ArmGicDispatcher,
- ArmPciConfigInfoParser,
- SerialPortDispatcher
-};
-
-/** Main dispatcher: sequentially call the parsers/dispatchers
- of the HwInfoParserTable.
-
- A parser parses a Device Tree to populate a specific CmObj type. None,
- one or many CmObj can be created by the parser.
- The created CmObj are then handed to the parser's caller through the
- HW_INFO_ADD_OBJECT interface.
- This can also be a dispatcher. I.e. a function that not parsing a
- Device Tree but calling other parsers.
-
- @param [in] FdtParserHandle A handle to the parser instance.
- @param [in] FdtBranch When searching for DT node name, restrict
- the search to this Device Tree branch.
-
- @retval EFI_SUCCESS The function completed successfully.
- @retval EFI_ABORTED An error occurred.
- @retval EFI_INVALID_PARAMETER Invalid parameter.
- @retval EFI_NOT_FOUND Not found.
- @retval EFI_UNSUPPORTED Unsupported.
-**/
-STATIC
-EFI_STATUS
-EFIAPI
-MainDispatcher (
- IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
- IN INT32 FdtBranch
- )
-{
- EFI_STATUS Status;
- UINT32 Index;
-
- if (fdt_check_header (FdtParserHandle->Fdt) < 0) {
- ASSERT (0);
- return EFI_INVALID_PARAMETER;
- }
-
- for (Index = 0; Index < ARRAY_SIZE (HwInfoParserTable); Index++) {
- Status = HwInfoParserTable[Index](
- FdtParserHandle,
- FdtBranch
- );
- if (EFI_ERROR (Status) &&
- (Status != EFI_NOT_FOUND))
- {
- // If EFI_NOT_FOUND, the parser didn't find information in the DT.
- // Don't trigger an error.
- ASSERT (0);
- return Status;
- }
- } // for
-
- return EFI_SUCCESS;
-}
/** Initialise the HwInfoParser.
@@ -159,7 +83,7 @@ HwInfoParse (
}
// Call all the parsers from the root node (-1).
- Status = MainDispatcher (
+ Status = ArchFdtHwInfoMainDispatcher (
(FDT_HW_INFO_PARSER_HANDLE)ParserHandle,
-1
);
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.h
index 8a8cf38..90850b3 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.h
@@ -60,4 +60,31 @@ EFI_STATUS
IN INT32 FdtBranch
);
+/** Main dispatcher: sequentially call the parsers/dispatchers
+ of the HwInfoParserTable.
+
+ A parser parses a Device Tree to populate a specific CmObj type. None,
+ one or many CmObj can be created by the parser.
+ The created CmObj are then handed to the parser's caller through the
+ HW_INFO_ADD_OBJECT interface.
+ This can also be a dispatcher. I.e. a function that not parsing a
+ Device Tree but calling other parsers.
+
+ @param [in] FdtParserHandle A handle to the parser instance.
+ @param [in] FdtBranch When searching for DT node name, restrict
+ the search to this Device Tree branch.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Not found.
+ @retval EFI_UNSUPPORTED Unsupported.
+**/
+EFI_STATUS
+EFIAPI
+ArchFdtHwInfoMainDispatcher (
+ IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
+ IN INT32 FdtBranch
+ );
+
#endif // FDT_HW_INFO_PARSER_H_
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserInclude.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserInclude.h
index 583f290..60f671e 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserInclude.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserInclude.h
@@ -10,7 +10,6 @@
#include <Base.h>
#include <libfdt.h>
-#include <Library/ArmLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf
index d2c171a..41d1244 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf
@@ -22,35 +22,43 @@
FdtHwInfoParser.h
FdtUtility.c
FdtUtility.h
- BootArch/ArmBootArchParser.c
- BootArch/ArmBootArchParser.h
- GenericTimer/ArmGenericTimerParser.c
- GenericTimer/ArmGenericTimerParser.h
- Gic/ArmGicCParser.c
- Gic/ArmGicCParser.h
- Gic/ArmGicDispatcher.c
- Gic/ArmGicDispatcher.h
- Gic/ArmGicDParser.c
- Gic/ArmGicDParser.h
- Gic/ArmGicItsParser.c
- Gic/ArmGicItsParser.h
- Gic/ArmGicMsiFrameParser.c
- Gic/ArmGicMsiFrameParser.h
- Gic/ArmGicRParser.c
- Gic/ArmGicRParser.h
- Pci/ArmPciConfigSpaceParser.c
- Pci/ArmPciConfigSpaceParser.h
- Serial/ArmSerialPortParser.c
- Serial/ArmSerialPortParser.h
+ Pci/PciConfigSpaceParser.c
+ Pci/PciConfigSpaceParser.h
+ Serial/SerialPortParser.c
+ Serial/SerialPortParser.h
-[Packages]
+[Sources.ARM, Sources.AARCH64]
+ Arm/ArmFdtInterrupt.c
+ Arm/ArmFdtHwInfoParser.c
+ Arm/BootArch/ArmBootArchParser.c
+ Arm/BootArch/ArmBootArchParser.h
+ Arm/GenericTimer/ArmGenericTimerParser.c
+ Arm/GenericTimer/ArmGenericTimerParser.h
+ Arm/Gic/ArmGicCParser.c
+ Arm/Gic/ArmGicCParser.h
+ Arm/Gic/ArmGicDispatcher.c
+ Arm/Gic/ArmGicDispatcher.h
+ Arm/Gic/ArmGicDParser.c
+ Arm/Gic/ArmGicDParser.h
+ Arm/Gic/ArmGicItsParser.c
+ Arm/Gic/ArmGicItsParser.h
+ Arm/Gic/ArmGicMsiFrameParser.c
+ Arm/Gic/ArmGicMsiFrameParser.h
+ Arm/Gic/ArmGicRParser.c
+ Arm/Gic/ArmGicRParser.h
+
+[Packages.ARM, Packages.AARCH64]
ArmPkg/ArmPkg.dec
+
+[Packages]
DynamicTablesPkg/DynamicTablesPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
DebugLib
FdtLib
MemoryAllocationLib
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c
index 5314cf3..9d8bd3e 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c
@@ -10,80 +10,10 @@
- linux//Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml
**/
+#include <Library/BaseLib.h>
#include <FdtHwInfoParserInclude.h>
#include "FdtUtility.h"
-/** Get the interrupt Id of an interrupt described in a fdt.
-
- Data must describe a GIC interrupt. A GIC interrupt is on at least
- 3 UINT32 cells.
- This function DOES NOT SUPPORT extended SPI range and extended PPI range.
-
- @param [in] Data Pointer to the first cell of an "interrupts" property.
-
- @retval The interrupt id.
-**/
-UINT32
-EFIAPI
-FdtGetInterruptId (
- UINT32 CONST *Data
- )
-{
- UINT32 IrqType;
- UINT32 IrqId;
-
- ASSERT (Data != NULL);
-
- IrqType = fdt32_to_cpu (Data[IRQ_TYPE_OFFSET]);
- IrqId = fdt32_to_cpu (Data[IRQ_NUMBER_OFFSET]);
-
- switch (IrqType) {
- case DT_SPI_IRQ:
- IrqId += SPI_OFFSET;
- break;
-
- case DT_PPI_IRQ:
- IrqId += PPI_OFFSET;
- break;
-
- default:
- ASSERT (0);
- IrqId = 0;
- }
-
- return IrqId;
-}
-
-/** Get the ACPI interrupt flags of an interrupt described in a fdt.
-
- Data must describe a GIC interrupt. A GIC interrupt is on at least
- 3 UINT32 cells.
-
- PPI interrupt cpu mask on bits [15:8] are ignored.
-
- @param [in] Data Pointer to the first cell of an "interrupts" property.
-
- @retval The interrupt flags (for ACPI).
-**/
-UINT32
-EFIAPI
-FdtGetInterruptFlags (
- UINT32 CONST *Data
- )
-{
- UINT32 IrqFlags;
- UINT32 AcpiIrqFlags;
-
- ASSERT (Data != NULL);
-
- IrqFlags = fdt32_to_cpu (Data[IRQ_FLAGS_OFFSET]);
-
- AcpiIrqFlags = DT_IRQ_IS_EDGE_TRIGGERED (IrqFlags) ? BIT0 : 0;
- AcpiIrqFlags |= DT_IRQ_IS_ACTIVE_LOW (IrqFlags) ? BIT1 : 0;
-
- return AcpiIrqFlags;
-}
-
/** Check whether a node has the input name.
@param [in] Fdt Pointer to a Flattened Device Tree.
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h
index 3f5d131..2d70487 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h
@@ -455,4 +455,34 @@ FdtGetParentAddressInfo (
OUT INT32 *SizeCells OPTIONAL
);
+/** For relevant architectures, get the "#address-cells" and/or "#size-cells"
+ property of the node.
+
+ According to the Device Tree specification, s2.3.5 "#address-cells and
+ #size-cells":
+ "If missing, a client program should assume a default value of 2 for
+ #address-cells, and a value of 1 for #size-cells."
+
+ @param [in] Fdt Pointer to a Flattened Device Tree.
+ @param [in] Node Offset of the node having to get the
+ "#address-cells" and "#size-cells"
+ properties from.
+ @param [out] AddressCells If success, number of address-cells.
+ If the property is not available,
+ default value is 2.
+ @param [out] SizeCells If success, number of size-cells.
+ If the property is not available,
+ default value is 1.
+
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+FdtGetIntcAddressCells (
+ IN CONST VOID *Fdt,
+ IN INT32 Node,
+ OUT INT32 *AddressCells, OPTIONAL
+ OUT INT32 *SizeCells OPTIONAL
+ );
+
#endif // FDT_UTILITY_H_
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c
index 2ffff1c..466538e 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.c
@@ -1,5 +1,5 @@
/** @file
- Arm PCI Configuration Space Parser.
+ PCI Configuration Space Parser.
Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -13,11 +13,11 @@
**/
#include "CmObjectDescUtility.h"
+#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include "FdtHwInfoParser.h"
-#include "Pci/ArmPciConfigSpaceParser.h"
-#include "Gic/ArmGicDispatcher.h"
+#include "Pci/PciConfigSpaceParser.h"
/** List of "compatible" property values for host PCIe bridges nodes.
@@ -188,8 +188,8 @@ ParseAddressMap (
UINT32 Count;
UINT32 PciAddressAttr;
- CM_ARM_PCI_ADDRESS_MAP_INFO *PciAddressMapInfo;
- UINT32 BufferSize;
+ CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO *PciAddressMapInfo;
+ UINT32 BufferSize;
// The mapping is done on AddressMapSize bytes.
AddressMapSize = (PCI_ADDRESS_CELLS + AddressCells + PCI_SIZE_CELLS) *
@@ -208,7 +208,7 @@ ParseAddressMap (
Count = DataSize / AddressMapSize;
// Allocate a buffer to store each address mapping.
- BufferSize = Count * sizeof (CM_ARM_PCI_ADDRESS_MAP_INFO);
+ BufferSize = Count * sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO);
PciAddressMapInfo = AllocateZeroPool (BufferSize);
if (PciAddressMapInfo == NULL) {
ASSERT (0);
@@ -246,9 +246,9 @@ ParseAddressMap (
} // for
PciInfo->Mapping[PciMappingTableAddress].ObjectId =
- CREATE_CM_ARM_OBJECT_ID (EArmObjPciAddressMapInfo);
+ CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjPciAddressMapInfo);
PciInfo->Mapping[PciMappingTableAddress].Size =
- sizeof (CM_ARM_PCI_ADDRESS_MAP_INFO) * Count;
+ sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO) * Count;
PciInfo->Mapping[PciMappingTableAddress].Data = PciAddressMapInfo;
PciInfo->Mapping[PciMappingTableAddress].Count = Count;
@@ -306,13 +306,12 @@ ParseIrqMap (
CONST UINT8 *IrqMapMask;
INT32 IrqMapMaskSize;
- INT32 PHandleOffset;
- UINT32 GicVersion;
+ INT32 PHandleOffset;
UINT32 PciAddressAttr;
- CM_ARM_PCI_INTERRUPT_MAP_INFO *PciInterruptMapInfo;
- UINT32 BufferSize;
+ CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO *PciInterruptMapInfo;
+ UINT32 BufferSize;
Data = fdt_getprop (Fdt, HostPciNode, "interrupt-map", &DataSize);
if ((Data == NULL) || (DataSize <= 0)) {
@@ -366,15 +365,8 @@ ParseIrqMap (
return EFI_ABORTED;
}
- // Only support Gic(s) for now.
- Status = GetGicVersion (Fdt, IntcNode, &GicVersion);
- if (EFI_ERROR (Status)) {
- ASSERT (0);
- return Status;
- }
-
// Get the "address-cells" property of the IntcNode.
- Status = FdtGetAddressInfo (Fdt, IntcNode, &IntcAddressCells, NULL);
+ Status = FdtGetIntcAddressCells (Fdt, IntcNode, &IntcAddressCells, NULL);
if (EFI_ERROR (Status)) {
ASSERT (0);
return Status;
@@ -413,7 +405,7 @@ ParseIrqMap (
// Allocate a buffer to store each interrupt mapping.
IrqMapCount = DataSize / IrqMapSize;
- BufferSize = IrqMapCount * sizeof (CM_ARM_PCI_ADDRESS_MAP_INFO);
+ BufferSize = IrqMapCount * sizeof (CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO);
PciInterruptMapInfo = AllocateZeroPool (BufferSize);
if (PciInterruptMapInfo == NULL) {
ASSERT (0);
@@ -455,9 +447,9 @@ ParseIrqMap (
} // for
PciInfo->Mapping[PciMappingTableInterrupt].ObjectId =
- CREATE_CM_ARM_OBJECT_ID (EArmObjPciInterruptMapInfo);
+ CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjPciInterruptMapInfo);
PciInfo->Mapping[PciMappingTableInterrupt].Size =
- sizeof (CM_ARM_PCI_INTERRUPT_MAP_INFO) * IrqMapCount;
+ sizeof (CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO) * IrqMapCount;
PciInfo->Mapping[PciMappingTableInterrupt].Data = PciInterruptMapInfo;
PciInfo->Mapping[PciMappingTableInterrupt].Count = IrqMapCount;
@@ -468,7 +460,7 @@ ParseIrqMap (
@param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
@param [in] HostPciNode Offset of a host-pci node.
- @param [in, out] PciInfo The CM_ARM_PCI_CONFIG_SPACE_INFO to populate.
+ @param [in, out] PciInfo The CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO to populate.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_ABORTED An error occurred.
@@ -579,9 +571,9 @@ PciNodeParser (
/** Add the parsed Pci information to the Configuration Manager.
CmObj of the following types are concerned:
- - EArmObjPciConfigSpaceInfo
- - EArmObjPciAddressMapInfo
- - EArmObjPciInterruptMapInfo
+ - EArchCommonObjPciConfigSpaceInfo
+ - EArchCommonObjPciAddressMapInfo
+ - EArchCommonObjPciInterruptMapInfo
@param [in] FdtParserHandle A handle to the parser instance.
@param [in] PciTableInfo PCI_PARSER_TABLE structure containing the
@@ -599,8 +591,8 @@ PciInfoAdd (
IN PCI_PARSER_TABLE *PciTableInfo
)
{
- EFI_STATUS Status;
- CM_ARM_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfo;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO *PciConfigSpaceInfo;
if ((FdtParserHandle == NULL) ||
(PciTableInfo == NULL))
@@ -640,9 +632,11 @@ PciInfoAdd (
// Add the configuration space CmObj to the Configuration Manager.
Status = AddSingleCmObj (
FdtParserHandle,
- CREATE_CM_ARM_OBJECT_ID (EArmObjPciConfigSpaceInfo),
+ CREATE_CM_ARCH_COMMON_OBJECT_ID (
+ EArchCommonObjPciConfigSpaceInfo
+ ),
&PciTableInfo->PciConfigSpaceInfo,
- sizeof (CM_ARM_PCI_CONFIG_SPACE_INFO),
+ sizeof (CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO),
NULL
);
ASSERT_EFI_ERROR (Status);
@@ -682,29 +676,29 @@ FreeParserTable (
return EFI_SUCCESS;
}
-/** CM_ARM_PCI_CONFIG_SPACE_INFO parser function.
+/** CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO parser function.
The following structure is populated:
- typedef struct CmArmPciConfigSpaceInfo {
+ typedef struct CmArchCommonPciConfigSpaceInfo {
UINT64 BaseAddress; // {Populated}
UINT16 PciSegmentGroupNumber; // {Populated}
UINT8 StartBusNumber; // {Populated}
UINT8 EndBusNumber; // {Populated}
- } CM_ARM_PCI_CONFIG_SPACE_INFO;
+ } CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO;
- typedef struct CmArmPciAddressMapInfo {
+ typedef struct CmArchCommonPciAddressMapInfo {
UINT8 SpaceCode; // {Populated}
UINT64 PciAddress; // {Populated}
UINT64 CpuAddress; // {Populated}
UINT64 AddressSize; // {Populated}
- } CM_ARM_PCI_ADDRESS_MAP_INFO;
+ } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO;
- typedef struct CmArmPciInterruptMapInfo {
- UINT8 PciBus; // {Populated}
- UINT8 PciDevice; // {Populated}
- UINT8 PciInterrupt; // {Populated}
- CM_ARM_GENERIC_INTERRUPT IntcInterrupt; // {Populated}
- } CM_ARM_PCI_INTERRUPT_MAP_INFO;
+ typedef struct CmArchCommonPciInterruptMapInfo {
+ UINT8 PciBus; // {Populated}
+ UINT8 PciDevice; // {Populated}
+ UINT8 PciInterrupt; // {Populated}
+ CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; // {Populated}
+ } CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO;
A parser parses a Device Tree to populate a specific CmObj type. None,
one or many CmObj can be created by the parser.
@@ -725,7 +719,7 @@ FreeParserTable (
**/
EFI_STATUS
EFIAPI
-ArmPciConfigInfoParser (
+PciConfigInfoParser (
IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
IN INT32 FdtBranch
)
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.h
index 6e0027a..aeffe7a 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/ArmPciConfigSpaceParser.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Pci/PciConfigSpaceParser.h
@@ -1,5 +1,5 @@
/** @file
- Arm PCI Configuration Space Parser.
+ PCI Configuration Space Parser.
Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -12,8 +12,8 @@
- linux kernel code
**/
-#ifndef ARM_PCI_CONFIG_SPACE_PARSER_H_
-#define ARM_PCI_CONFIG_SPACE_PARSER_H_
+#ifndef PCI_CONFIG_SPACE_PARSER_H_
+#define PCI_CONFIG_SPACE_PARSER_H_
/** Read LEN bits at OFF offsets bits of the ADDR.
@@ -83,38 +83,38 @@ typedef enum PciMappingTable {
*/
typedef struct PciParserTable {
/// PCI Configuration Space Info
- CM_ARM_PCI_CONFIG_SPACE_INFO PciConfigSpaceInfo;
+ CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO PciConfigSpaceInfo;
/// Store the address mapping and interrupt mapping as CmObjDesc
/// before adding them to the Configuration Manager.
- CM_OBJ_DESCRIPTOR Mapping[PciMappingTableMax];
+ CM_OBJ_DESCRIPTOR Mapping[PciMappingTableMax];
} PCI_PARSER_TABLE;
#pragma pack()
-/** CM_ARM_PCI_CONFIG_SPACE_INFO parser function.
+/** CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO parser function.
The following structure is populated:
- typedef struct CmArmPciConfigSpaceInfo {
+ typedef struct CmArchCommonPciConfigSpaceInfo {
UINT64 BaseAddress; // {Populated}
UINT16 PciSegmentGroupNumber; // {Populated}
UINT8 StartBusNumber; // {Populated}
UINT8 EndBusNumber; // {Populated}
- } CM_ARM_PCI_CONFIG_SPACE_INFO;
+ } CM_ARCH_COMMON_PCI_CONFIG_SPACE_INFO;
- typedef struct CmArmPciAddressMapInfo {
+ typedef struct CmArchCommonPciAddressMapInfo {
UINT8 SpaceCode; // {Populated}
UINT64 PciAddress; // {Populated}
UINT64 CpuAddress; // {Populated}
UINT64 AddressSize; // {Populated}
- } CM_ARM_PCI_ADDRESS_MAP_INFO;
+ } CM_ARCH_COMMON_PCI_ADDRESS_MAP_INFO;
- typedef struct CmArmPciInterruptMapInfo {
- UINT8 PciBus; // {Populated}
- UINT8 PciDevice; // {Populated}
- UINT8 PciInterrupt; // {Populated}
- CM_ARM_GENERIC_INTERRUPT IntcInterrupt; // {Populated}
- } CM_ARM_PCI_INTERRUPT_MAP_INFO;
+ typedef struct CmArchCommonPciInterruptMapInfo {
+ UINT8 PciBus; // {Populated}
+ UINT8 PciDevice; // {Populated}
+ UINT8 PciInterrupt; // {Populated}
+ CM_ARCH_COMMON_GENERIC_INTERRUPT IntcInterrupt; // {Populated}
+ } CM_ARCH_COMMON_PCI_INTERRUPT_MAP_INFO;
A parser parses a Device Tree to populate a specific CmObj type. None,
one or many CmObj can be created by the parser.
@@ -135,9 +135,9 @@ typedef struct PciParserTable {
**/
EFI_STATUS
EFIAPI
-ArmPciConfigInfoParser (
+PciConfigInfoParser (
IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
IN INT32 FdtBranch
);
-#endif // ARM_PCI_CONFIG_SPACE_PARSER_H_
+#endif // PCI_CONFIG_SPACE_PARSER_H_
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.c
index 732b482..3465900 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.c
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.c
@@ -1,5 +1,5 @@
/** @file
- Arm Serial Port Parser.
+ Serial Port Parser.
Copyright (c) 2021 - 2023, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -12,10 +12,12 @@
**/
#include <IndustryStandard/DebugPort2Table.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
#include "CmObjectDescUtility.h"
#include "FdtHwInfoParser.h"
-#include "Serial/ArmSerialPortParser.h"
+#include "Serial/SerialPortParser.h"
/** List of "compatible" property values for serial port nodes.
@@ -71,7 +73,7 @@ CONST COMPATIBILITY_INFO SerialSbsaCompatibleInfo = {
@param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
@param [in] SerialPortNode Offset of a serial-port node.
- @param [in] SerialPortInfo The CM_ARM_SERIAL_PORT_INFO to populate.
+ @param [in] SerialPortInfo The CM_ARCH_COMMON_SERIAL_PORT_INFO to populate.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_ABORTED An error occurred.
@@ -82,9 +84,9 @@ STATIC
EFI_STATUS
EFIAPI
SerialPortNodeParser (
- IN CONST VOID *Fdt,
- IN INT32 SerialPortNode,
- IN CM_ARM_SERIAL_PORT_INFO *SerialPortInfo
+ IN CONST VOID *Fdt,
+ IN INT32 SerialPortNode,
+ IN CM_ARCH_COMMON_SERIAL_PORT_INFO *SerialPortInfo
)
{
EFI_STATUS Status;
@@ -313,7 +315,7 @@ GetSerialConsoleNode (
return EFI_SUCCESS;
}
-/** CM_ARM_SERIAL_PORT_INFO dispatcher function (for a generic serial-port).
+/** CM_ARCH_COMMON_SERIAL_PORT_INFO dispatcher function (for a generic serial-port).
@param [in] FdtParserHandle A handle to the parser instance.
@param [in] GenericSerialInfo Pointer to a serial port info list.
@@ -329,11 +331,11 @@ GetSerialConsoleNode (
STATIC
EFI_STATUS
EFIAPI
-ArmSerialPortInfoDispatch (
+SerialPortInfoDispatch (
IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
- IN CM_ARM_SERIAL_PORT_INFO *GenericSerialInfo,
+ IN CM_ARCH_COMMON_SERIAL_PORT_INFO *GenericSerialInfo,
IN INT32 NodeCount,
- IN EARM_OBJECT_ID SerialObjectId
+ IN EARCH_COMMON_OBJECT_ID SerialObjectId
)
{
EFI_STATUS Status;
@@ -344,9 +346,9 @@ ArmSerialPortInfoDispatch (
return EFI_INVALID_PARAMETER;
}
- if ((SerialObjectId != EArmObjSerialPortInfo) &&
- (SerialObjectId != EArmObjSerialDebugPortInfo) &&
- (SerialObjectId != EArmObjSerialConsolePortInfo))
+ if ((SerialObjectId != EArchCommonObjSerialPortInfo) &&
+ (SerialObjectId != EArchCommonObjSerialDebugPortInfo) &&
+ (SerialObjectId != EArchCommonObjConsolePortInfo))
{
ASSERT (0);
return EFI_INVALID_PARAMETER;
@@ -354,10 +356,10 @@ ArmSerialPortInfoDispatch (
// Dispatch the Generic Serial ports
Status = CreateCmObjDesc (
- CREATE_CM_ARM_OBJECT_ID (SerialObjectId),
+ CREATE_CM_ARCH_COMMON_OBJECT_ID (SerialObjectId),
NodeCount,
GenericSerialInfo,
- sizeof (CM_ARM_SERIAL_PORT_INFO) * NodeCount,
+ sizeof (CM_ARCH_COMMON_SERIAL_PORT_INFO) * NodeCount,
&NewCmObjDesc
);
if (EFI_ERROR (Status)) {
@@ -372,19 +374,19 @@ ArmSerialPortInfoDispatch (
return Status;
}
-/** CM_ARM_SERIAL_PORT_INFO parser function (for debug/console serial-port).
+/** CM_ARCH_COMMON_SERIAL_PORT_INFO parser function (for debug/console serial-port).
This parser expects FdtBranch to be the debug serial-port node.
At most one CmObj is created.
The following structure is populated:
- typedef struct CmArmSerialPortInfo {
+ typedef struct EArchCommonSerialPortInfo {
UINT64 BaseAddress; // {Populated}
UINT32 Interrupt; // {Populated}
UINT64 BaudRate; // {default}
UINT32 Clock; // {Populated}
UINT16 PortSubtype; // {Populated}
UINT64 BaseAddressLength // {Populated}
- } CM_ARM_SERIAL_PORT_INFO;
+ } CM_ARCH_COMMON_SERIAL_PORT_INFO;
A parser parses a Device Tree to populate a specific CmObj type. None,
one or many CmObj can be created by the parser.
@@ -396,7 +398,8 @@ ArmSerialPortInfoDispatch (
@param [in] FdtParserHandle A handle to the parser instance.
@param [in] FdtBranch When searching for DT node name, restrict
the search to this Device Tree branch.
- @param [in] SerialObjectId ArmNamespace Object ID for the serial port.
+ @param [in] SerialObjectId ArchCommon Namespace Object ID for the serial
+ port.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_ABORTED An error occurred.
@@ -407,17 +410,17 @@ ArmSerialPortInfoDispatch (
STATIC
EFI_STATUS
EFIAPI
-ArmSerialPortInfoParser (
+SerialPortInfoParser (
IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
IN INT32 FdtBranch,
- IN EARM_OBJECT_ID SerialObjectId
+ IN EARCH_COMMON_OBJECT_ID SerialObjectId
)
{
- EFI_STATUS Status;
- CM_ARM_SERIAL_PORT_INFO SerialInfo;
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_SERIAL_PORT_INFO SerialInfo;
- if ((SerialObjectId != EArmObjSerialDebugPortInfo) &&
- (SerialObjectId != EArmObjSerialConsolePortInfo))
+ if ((SerialObjectId != EArchCommonObjSerialDebugPortInfo) &&
+ (SerialObjectId != EArchCommonObjConsolePortInfo))
{
ASSERT (0);
return EFI_INVALID_PARAMETER;
@@ -435,7 +438,7 @@ ArmSerialPortInfoParser (
return Status;
}
- Status = ArmSerialPortInfoDispatch (
+ Status = SerialPortInfoDispatch (
FdtParserHandle,
&SerialInfo,
1,
@@ -447,11 +450,11 @@ ArmSerialPortInfoParser (
/** SerialPort dispatcher.
- This disptacher populates the CM_ARM_SERIAL_PORT_INFO structure for
+ This disptacher populates the CM_ARCH_COMMON_SERIAL_PORT_INFO structure for
the following CM_OBJ_ID:
- - EArmObjSerialConsolePortInfo
- - EArmObjSerialDebugPortInfo
- - EArmObjSerialPortInfo
+ - EArchCommonObjConsolePortInfo
+ - EArchCommonObjSerialDebugPortInfo
+ - EArchCommonObjSerialPortInfo
A parser parses a Device Tree to populate a specific CmObj type. None,
one or many CmObj can be created by the parser.
@@ -477,16 +480,16 @@ SerialPortDispatcher (
IN INT32 FdtBranch
)
{
- EFI_STATUS Status;
- INT32 SerialConsoleNode;
- INT32 SerialDebugNode;
- INT32 SerialNode;
- UINT32 Index;
- UINT32 SerialNodeCount;
- UINT32 SerialNodesRemaining;
- CM_ARM_SERIAL_PORT_INFO *GenericSerialInfo;
- UINT32 GenericSerialIndex;
- VOID *Fdt;
+ EFI_STATUS Status;
+ INT32 SerialConsoleNode;
+ INT32 SerialDebugNode;
+ INT32 SerialNode;
+ UINT32 Index;
+ UINT32 SerialNodeCount;
+ UINT32 SerialNodesRemaining;
+ CM_ARCH_COMMON_SERIAL_PORT_INFO *GenericSerialInfo;
+ UINT32 GenericSerialIndex;
+ VOID *Fdt;
if (FdtParserHandle == NULL) {
ASSERT (0);
@@ -528,10 +531,10 @@ SerialPortDispatcher (
return Status;
} else {
// Parse the console serial-port.
- Status = ArmSerialPortInfoParser (
+ Status = SerialPortInfoParser (
FdtParserHandle,
SerialConsoleNode,
- EArmObjSerialConsolePortInfo
+ EArchCommonObjConsolePortInfo
);
if (EFI_ERROR (Status)) {
ASSERT (0);
@@ -550,7 +553,7 @@ SerialPortDispatcher (
SerialNodesRemaining--;
GenericSerialInfo = AllocateZeroPool (
SerialNodesRemaining *
- sizeof (CM_ARM_SERIAL_PORT_INFO)
+ sizeof (CM_ARCH_COMMON_SERIAL_PORT_INFO)
);
if (GenericSerialInfo == NULL) {
ASSERT (0);
@@ -586,10 +589,10 @@ SerialPortDispatcher (
// The first serial-port node, not being the console serial-port,
// will be the debug serial-port.
SerialDebugNode = SerialNode;
- Status = ArmSerialPortInfoParser (
+ Status = SerialPortInfoParser (
FdtParserHandle,
SerialDebugNode,
- EArmObjSerialDebugPortInfo
+ EArchCommonObjSerialDebugPortInfo
);
if (EFI_ERROR (Status)) {
ASSERT (0);
@@ -616,11 +619,11 @@ SerialPortDispatcher (
} // for
if (GenericSerialIndex > 0) {
- Status = ArmSerialPortInfoDispatch (
+ Status = SerialPortInfoDispatch (
FdtParserHandle,
GenericSerialInfo,
GenericSerialIndex,
- EArmObjSerialPortInfo
+ EArchCommonObjSerialPortInfo
);
}
diff --git a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.h
index de08e57..22c686d 100644
--- a/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/ArmSerialPortParser.h
+++ b/DynamicTablesPkg/Library/FdtHwInfoParserLib/Serial/SerialPortParser.h
@@ -1,5 +1,5 @@
/** @file
- Arm Serial Port Parser.
+ Serial Port Parser.
Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -9,16 +9,16 @@
- linux/Documentation/devicetree/bindings/serial/8250.txt
**/
-#ifndef ARM_SERIAL_PORT_PARSER_H_
-#define ARM_SERIAL_PORT_PARSER_H_
+#ifndef SERIAL_PORT_PARSER_H_
+#define SERIAL_PORT_PARSER_H_
/** SerialPort dispatcher.
- This disptacher populates the CM_ARM_SERIAL_PORT_INFO structure for
+ This disptacher populates the CM_ARCH_COMMON_SERIAL_PORT_INFO structure for
the following CM_OBJ_ID:
- - EArmObjSerialConsolePortInfo
- - EArmObjSerialDebugPortInfo
- - EArmObjSerialPortInfo
+ - EArchCommonObjConsolePortInfo
+ - EArchCommonObjSerialDebugPortInfo
+ - EArchCommonObjSerialPortInfo
A parser parses a Device Tree to populate a specific CmObj type. None,
one or many CmObj can be created by the parser.
@@ -44,4 +44,4 @@ SerialPortDispatcher (
IN INT32 FdtBranch
);
-#endif // ARM_SERIAL_PORT_PARSER_H_
+#endif // SERIAL_PORT_PARSER_H_
diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md
index c1cdc5e..7a3d499 100644
--- a/DynamicTablesPkg/Readme.md
+++ b/DynamicTablesPkg/Readme.md
@@ -402,3 +402,118 @@ Refer to the following presentation from *UEFI Plugfest Seattle 2018*:
[Dynamic Tables Framework: A Step Towards Automatic Generation of Advanced Configuration and Power Interface (ACPI) & System Management BIOS (SMBIOS) Tables](http://www.uefi.org/sites/default/files/resources/Arm_Dynamic%20Tables%20Framework%20A%20Step%20Towards%20Automatic%20Generation%20of%20Advanced%20Configuration%20and%20Power%20Interface%20%28ACPI%29%20%26%20System%20Management%20BIOS%20%28SMBIOS%29%20Tables%20_0.pdf)
+## Configuration Manager Objects
+
+The CM_OBJECT_ID type is used to identify the Configuration Manager
+ objects.
+
+## Description of Configuration Manager Object ID
+
+| 31 - 28 | 27 - 8 | 7 - 0 |
+| :-------------: | :----: | :---------: |
+| `Name Space ID` | 0 | `Object ID` |
+------------------------------------------
+
+### Name Space ID: Bits [31:28]
+
+| ID | Description | Comments |
+| ---: | :-------------------------- | :--- |
+| 0000b | Standard | |
+| 0001b | Arch Common | |
+| 0010b | ARM | |
+| 0011b | X64 | |
+| 1111b | Custom/OEM | |
+| `*` | All other values are reserved. | |
+
+### Bits: [27:8] - Reserved, must be zero.
+
+### Bits: [7:0] - Object ID
+
+#### Object ID's in the Standard Namespace:
+
+| ID | Description | Comments |
+| ---: | :-------------------------- | :--- |
+| 0 | Configuration Manager Revision | |
+| 1 | ACPI Table List | |
+| 2 | SMBIOS Table List | |
+
+#### Object ID's in the ARM Namespace:
+
+| ID | Description | Comments |
+| ---: | :-------------------------- | :--- |
+| 0 | Reserved | |
+| 1 | Boot Architecture Info | |
+| 2 | GICC Info | |
+| 3 | GICD Info | |
+| 4 | GIC MSI Frame Info | |
+| 5 | GIC Redistributor Info | |
+| 6 | GIC ITS Info | |
+| 7 | Generic Timer Info | |
+| 8 | Platform GT Block Info | |
+| 9 | Generic Timer Block Frame Info | |
+| 10 | Platform Generic Watchdog | |
+| 11 | ITS Group | |
+| 12 | Named Component | |
+| 13 | Root Complex | |
+| 14 | SMMUv1 or SMMUv2 | |
+| 15 | SMMUv3 | |
+| 16 | PMCG | |
+| 17 | GIC ITS Identifier Array | |
+| 18 | ID Mapping Array | |
+| 19 | SMMU Interrupt Array | |
+| 20 | CMN 600 Info | |
+| 21 | Reserved Memory Range Node | |
+| 22 | Memory Range Descriptor | |
+| 23 | Embedded Trace Extension/Module Info | |
+| `*` | All other values are reserved. | |
+
+#### Object ID's in the Arch Common Namespace:
+
+| ID | Description | Comments |
+| ---: | :-------------------------- | :--- |
+| 0 | Reserved | |
+| 1 | Power Management Profile Info | |
+| 2 | Serial Port Info | |
+| 3 | Serial Console Port Info | |
+| 4 | Serial Debug Port Info | |
+| 5 | Hypervisor Vendor Id | |
+| 6 | Fixed feature flags for FADT | |
+| 7 | CM Object Reference | |
+| 8 | PCI Configuration Space Info | |
+| 9 | PCI Address Map Info | |
+| 10 | PCI Interrupt Map Info | |
+| 11 | Memory Affinity Info | |
+| 12 | Device Handle Acpi | |
+| 13 | Device Handle PCI | |
+| 14 | Generic Initiator Affinity Info | |
+| 15 | Low Power Idle State Info | |
+| 16 | Processor Hierarchy Info | |
+| 17 | Cache Info | |
+| 18 | Continuous Performance Control Info | |
+| 19 | Pcc Subspace Type 0 Info | |
+| 20 | Pcc Subspace Type 1 Info | |
+| 21 | Pcc Subspace Type 2 Info | |
+| 22 | Pcc Subspace Type 3 Info | |
+| 23 | Pcc Subspace Type 4 Info | |
+| 24 | Pcc Subspace Type 5 Info | |
+| 25 | P-State Dependency (PSD) Info | |
+| 26 | TPM Interface Info | |
+| `*` | All other values are reserved. | |
+
+#### Object ID's in the X64 Namespace:
+
+| ID | Description | Comments |
+| ---: | :-------------------------- | :--- |
+| 0 | Reserved | |
+| 1 | SCI Interrupt Info | |
+| 2 | SCI Command Info | |
+| 3 | Legacy Power Management Block Info | |
+| 4 | Legacy GPE Block Info | |
+| 5 | Power Management Block Info | |
+| 6 | GPE Block Info | |
+| 7 | Sleep Block Info | |
+| 8 | Reset Block Info | |
+| 9 | Miscellaneous Block Info | |
+| 10 | Windows protection flag Info | |
+| 11 | HPET device Info | |
+| `*` | All other values are reserved. | |
diff --git a/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c
index 2c2e73e..e846394 100644
--- a/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c
+++ b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.c
@@ -10,6 +10,7 @@
#include <IndustryStandard/Acpi.h>
#include <libfdt.h>
#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/HiiLib.h>
diff --git a/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.inf b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.inf
index c0ea2ca..050e00c 100644
--- a/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.inf
+++ b/EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.inf
@@ -32,6 +32,7 @@
[LibraryClasses]
BaseLib
+ BaseMemoryLib
DebugLib
FdtLib
HiiLib
diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c
new file mode 100644
index 0000000..7a0156d
--- /dev/null
+++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c
@@ -0,0 +1,197 @@
+/** @file
+
+ Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include "MemoryAttributeManagerDxe.h"
+
+extern UINT8 MemoryAttributeManagerDxeHiiBin[];
+extern UINT8 MemoryAttributeManagerDxeStrings[];
+
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+STATIC HII_VENDOR_DEVICE_PATH mVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8)(END_DEVICE_PATH_LENGTH),
+ (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+/**
+ Installs HII page for user configuration.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+InstallHiiPages (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_HANDLE DriverHandle;
+
+ DriverHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mVendorDevicePath,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ HiiHandle = HiiAddPackages (
+ &gMemoryAttributeManagerFormSetGuid,
+ DriverHandle,
+ MemoryAttributeManagerDxeStrings,
+ MemoryAttributeManagerDxeHiiBin,
+ NULL
+ );
+
+ if (HiiHandle == NULL) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mVendorDevicePath,
+ NULL
+ );
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function uninstalls the EFI_MEMORY_ATTRIBUTE_PROTOCOL
+ from CpuDxe's handle.
+**/
+STATIC
+VOID
+UninstallEfiMemoryAttributeProtocol (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ UINTN Size;
+ VOID *MemoryAttributeProtocol;
+
+ Size = sizeof (Handle);
+ Status = gBS->LocateHandle (
+ ByProtocol,
+ &gEfiMemoryAttributeProtocolGuid,
+ NULL,
+ &Size,
+ &Handle
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (Status == EFI_NOT_FOUND);
+ return;
+ }
+
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiMemoryAttributeProtocolGuid,
+ &MemoryAttributeProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ Status = gBS->UninstallProtocolInterface (
+ Handle,
+ &gEfiMemoryAttributeProtocolGuid,
+ MemoryAttributeProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "EFI Memory Attribute Protocol disabled due to user/platform preference!\n"
+ ));
+}
+
+/**
+ The entry point for MemoryAttributeManagerDxe driver.
+
+ @param[in] ImageHandle The image handle of the driver.
+ @param[in] SystemTable The system table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+MemoryAttributeManagerInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA Config;
+
+ Config.Enabled = PROTOCOL_ENABLED_DEFAULT;
+
+ Size = sizeof (MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA);
+ Status = gRT->GetVariable (
+ MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME,
+ &gMemoryAttributeManagerFormSetGuid,
+ NULL,
+ &Size,
+ &Config
+ );
+ if (EFI_ERROR (Status)) {
+ Status = gRT->SetVariable (
+ MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME,
+ &gMemoryAttributeManagerFormSetGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ Size,
+ &Config
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (!Config.Enabled) {
+ UninstallEfiMemoryAttributeProtocol ();
+ }
+
+ return InstallHiiPages ();
+}
diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h
new file mode 100644
index 0000000..a027f3e
--- /dev/null
+++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h
@@ -0,0 +1,22 @@
+/** @file
+
+ Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MEMORY_ATTRIBUTE_MANAGER_DXE_H_
+#define MEMORY_ATTRIBUTE_MANAGER_DXE_H_
+
+#include <Guid/MemoryAttributeManagerFormSet.h>
+
+#define PROTOCOL_ENABLED_DEFAULT FixedPcdGetBool(PcdMemoryAttributeEnabledDefault)
+
+#define MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME L"MemoryAttributeManagerData"
+
+typedef struct {
+ BOOLEAN Enabled;
+} MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA;
+
+#endif // __MEMORY_ATTRIBUTE_MANAGER_DXE_H__
diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf
new file mode 100644
index 0000000..b55639c
--- /dev/null
+++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf
@@ -0,0 +1,62 @@
+## @file
+# EFI Memory Attribute Protocol state manager
+#
+# This driver allows users to disable the EFI Memory Attribute protocol
+# through an HII setup option, in order to work around a broken version
+# of rhboot's shim used in some distros (e.g. CentOS Stream 9) which
+# incorrectly invokes the protocol and results in a Synchronous Exception.
+#
+# It is only applicable to ARM64 and there isn't any other technical
+# reason for disabling this security feature.
+#
+# See:
+# - https://github.com/microsoft/mu_silicon_arm_tiano/issues/124
+# - https://edk2.groups.io/g/devel/topic/99631663
+# - https://github.com/tianocore/edk2/pull/5840
+#
+# Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = MemoryAttributeManagerDxe
+ FILE_GUID = 5319346b-66ad-433a-9a91-f7fc286bc9a1
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = MemoryAttributeManagerInitialize
+
+[Sources]
+ MemoryAttributeManagerDxe.c
+ MemoryAttributeManagerDxe.h
+ MemoryAttributeManagerDxeHii.uni
+ MemoryAttributeManagerDxeHii.vfr
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ DevicePathLib
+ HiiLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+
+[Guids]
+ gMemoryAttributeManagerFormSetGuid
+
+[Protocols]
+ gEfiMemoryAttributeProtocolGuid
+
+[Pcd]
+ gEmbeddedTokenSpaceGuid.PcdMemoryAttributeEnabledDefault
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid AND
+ gEfiMemoryAttributeProtocolGuid
diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni
new file mode 100644
index 0000000..8537824
--- /dev/null
+++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni
@@ -0,0 +1,17 @@
+/** @file
+
+ Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#langdef en-US "English"
+
+#string STR_NULL_STRING #language en-US ""
+
+#string STR_FORM_SET_TITLE #language en-US "EFI Memory Attribute Protocol"
+#string STR_FORM_SET_TITLE_HELP #language en-US "Configure the state of the EFI Memory Attribute Protocol.\n\n"
+ "Some old OS loader versions (e.g. as found in CentOS Stream 9) do not properly support the protocol and may cause a Synchronous Exception. This security feature can be disabled to work around the issue; otherwise it should be kept enabled."
+
+#string STR_ENABLE_PROTOCOL_PROMPT #language en-US "Enable Protocol"
diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr
new file mode 100644
index 0000000..a303426
--- /dev/null
+++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr
@@ -0,0 +1,35 @@
+/** @file
+
+ Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiMultiPhase.h>
+#include <Guid/HiiPlatformSetupFormset.h>
+
+#include "MemoryAttributeManagerDxe.h"
+
+formset
+ guid = MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID,
+ title = STRING_TOKEN(STR_FORM_SET_TITLE),
+ help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP),
+ classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
+
+ efivarstore MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA,
+ attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ name = MemoryAttributeManagerData,
+ guid = MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID;
+
+ form formid = 1,
+ title = STRING_TOKEN(STR_FORM_SET_TITLE);
+
+ checkbox varid = MemoryAttributeManagerData.Enabled,
+ prompt = STRING_TOKEN(STR_ENABLE_PROTOCOL_PROMPT),
+ help = STRING_TOKEN(STR_NULL_STRING),
+ flags = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG | RESET_REQUIRED,
+ default = PROTOCOL_ENABLED_DEFAULT,
+ endcheckbox;
+ endform;
+endformset;
diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
index 5dfbbc2..bb0b677 100644
--- a/EmbeddedPkg/EmbeddedPkg.dec
+++ b/EmbeddedPkg/EmbeddedPkg.dec
@@ -33,7 +33,6 @@
[LibraryClasses.common]
PrePiLib|Include/Library/PrePiLib.h
RealTimeClockLib|Include/Library/RealTimeClockLib.h
- EfiResetSystemLib|Include/Library/EfiResetSystemLib.h
GdbSerialLib|Include/Library/GdbSerialLib.h
DebugAgentTimerLib|Include/Library/DebugAgentTimerLib.h
NorFlashInfoLib|Include/Library/NorFlashInfoLib.h
@@ -73,6 +72,9 @@
## Include/Guid/NvVarStoreFormatted.h
gEdkiiNvVarStoreFormattedGuid = { 0xd1a86e3f, 0x0707, 0x4c35, { 0x83, 0xcd, 0xdc, 0x2c, 0x29, 0xc8, 0x91, 0xa3 } }
+ # Include/Guid/MemoryAttributeManagerFormSet.h
+ gMemoryAttributeManagerFormSetGuid = { 0xefab3427, 0x4793, 0x4e9e, { 0xaa, 0x29, 0x88, 0x0c, 0x9a, 0x77, 0x5b, 0x5f } }
+
[Protocols.common]
gHardwareInterruptProtocolGuid = { 0x2890B3EA, 0x053D, 0x1643, { 0xAD, 0x0C, 0xD6, 0x48, 0x08, 0xDA, 0x3F, 0xF1 } }
gHardwareInterrupt2ProtocolGuid = { 0x32898322, 0x2da1, 0x474a, { 0xba, 0xaa, 0xf3, 0xf7, 0xcf, 0x56, 0x94, 0x70 } }
@@ -192,3 +194,8 @@
# Expected Overflow Android Kernel Command Line Characters
#
gEmbeddedTokenSpaceGuid.PcdAndroidKernelCommandLineOverflow|0|UINT32|0x000005C
+
+ #
+ # EFI Memory Attribute Protocol default enable state
+ #
+ gEmbeddedTokenSpaceGuid.PcdMemoryAttributeEnabledDefault|TRUE|BOOLEAN|0x00000060
diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc
index e9062ca..503d7cc 100644
--- a/EmbeddedPkg/EmbeddedPkg.dsc
+++ b/EmbeddedPkg/EmbeddedPkg.dsc
@@ -66,7 +66,6 @@
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
RealTimeClockLib|EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
- EfiResetSystemLib|EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf
GdbSerialLib|EmbeddedPkg/Library/GdbSerialLib/GdbSerialLib.inf
@@ -123,15 +122,13 @@
[LibraryClasses.common.SEC]
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+ # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
[LibraryClasses.ARM, LibraryClasses.AARCH64]
ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- # Add support for GCC stack protector
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
@@ -172,7 +169,7 @@
gEmbeddedTokenSpaceGuid.PcdPrePiStackSize|0
#
-# Optinal feature to help prevent EFI memory map fragments
+# Optional feature to help prevent EFI memory map fragments
# Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
# Values are in EFI Pages (4K). DXE Core will make sure that
# at least this much of each type of memory can be allocated
@@ -211,7 +208,6 @@
EmbeddedPkg/Library/GdbSerialLib/GdbSerialLib.inf
EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
- EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf
EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
EmbeddedPkg/Library/CoherentDmaLib/CoherentDmaLib.inf
EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
@@ -220,7 +216,6 @@
EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
- EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf {
<LibraryClasses>
@@ -239,6 +234,8 @@
EmbeddedPkg/Drivers/DtPlatformDxe/DtPlatformDxe.inf
EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf
+ EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf
+
EmbeddedPkg/Drivers/NonCoherentIoMmuDxe/NonCoherentIoMmuDxe.inf {
<LibraryClasses>
DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
diff --git a/EmbeddedPkg/GdbStub/SerialIo.c b/EmbeddedPkg/GdbStub/SerialIo.c
index 98ea611..fdc9e2d 100644
--- a/EmbeddedPkg/GdbStub/SerialIo.c
+++ b/EmbeddedPkg/GdbStub/SerialIo.c
@@ -457,7 +457,7 @@ GDB_SERIAL_DEV gdbSerialDevTemplate = {
0, // ControlMask
0, // Timeout
0, // BaudRate
- 1, // RceiveFifoDepth
+ 1, // ReceiveFifoDepth
0, // DataBits
0, // Parity
0 // StopBits
diff --git a/EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h b/EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h
new file mode 100644
index 0000000..2efdf03
--- /dev/null
+++ b/EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h
@@ -0,0 +1,17 @@
+/** @file
+
+ Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MEMORY_ATTRIBUTE_MANAGER_FORMSET_H_
+#define MEMORY_ATTRIBUTE_MANAGER_FORMSET_H_
+
+#define MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID \
+ { 0xefab3427, 0x4793, 0x4e9e, { 0xaa, 0x29, 0x88, 0x0c, 0x9a, 0x77, 0x5b, 0x5f } }
+
+extern EFI_GUID gMemoryAttributeManagerFormSetGuid;
+
+#endif // __MEMORY_ATTRIBUTE_MANAGER_FORMSET_H__
diff --git a/EmbeddedPkg/Include/Library/EfiResetSystemLib.h b/EmbeddedPkg/Include/Library/EfiResetSystemLib.h
deleted file mode 100644
index 5bfebfc..0000000
--- a/EmbeddedPkg/Include/Library/EfiResetSystemLib.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/** @file
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __EFI_RESET_SYSTEM_LIB_H___
-#define __EFI_RESET_SYSTEM_LIB_H___
-
-/**
- Resets the entire platform.
-
- @param ResetType The type of reset to perform.
- @param ResetStatus The status code for the reset.
- @param DataSize The size, in bytes, of WatchdogData.
- @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
- EfiResetShutdown the data buffer starts with a Null-terminated
- Unicode string, optionally followed by additional binary data.
-
-**/
-EFI_STATUS
-EFIAPI
-LibResetSystem (
- IN EFI_RESET_TYPE ResetType,
- IN EFI_STATUS ResetStatus,
- IN UINTN DataSize,
- IN CHAR16 *ResetData OPTIONAL
- );
-
-/**
- Initialize any infrastructure required for LibResetSystem () to 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 always returns EFI_SUCCESS.
-
-**/
-EFI_STATUS
-EFIAPI
-LibInitializeResetSystem (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-#endif
diff --git a/EmbeddedPkg/Include/libfdt.h b/EmbeddedPkg/Include/libfdt.h
index 6105b9c..a2db686 100644
--- a/EmbeddedPkg/Include/libfdt.h
+++ b/EmbeddedPkg/Include/libfdt.h
@@ -2311,7 +2311,7 @@ fdt_del_node (
* returns:
* 0, on success
* -FDT_ERR_NOSPACE, there's not enough space in the base device tree
- * -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or
+ * -FDT_ERR_NOTFOUND, the overlay points to some nonexistant nodes or
* properties in the base DT
* -FDT_ERR_BADPHANDLE,
* -FDT_ERR_BADOVERLAY,
diff --git a/EmbeddedPkg/Library/AcpiLib/AcpiLib.c b/EmbeddedPkg/Library/AcpiLib/AcpiLib.c
index cb593a7..0f75cd5 100644
--- a/EmbeddedPkg/Library/AcpiLib/AcpiLib.c
+++ b/EmbeddedPkg/Library/AcpiLib/AcpiLib.c
@@ -52,6 +52,9 @@ LocateAndInstallAcpiFromFvConditional (
UINTN AcpiTableSize;
UINTN AcpiTableKey;
BOOLEAN Valid;
+ BOOLEAN FoundAcpiFile;
+
+ FoundAcpiFile = FALSE;
// Ensure the ACPI Table is present
Status = gBS->LocateProtocol (
@@ -107,47 +110,48 @@ LocateAndInstallAcpiFromFvConditional (
&SectionSize,
&FvStatus
);
- if (!EFI_ERROR (Status)) {
- AcpiTableKey = 0;
- AcpiTableSize = ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Length;
- ASSERT (SectionSize >= AcpiTableSize);
-
- DEBUG ((
- DEBUG_ERROR,
- "- Found '%c%c%c%c' ACPI Table\n",
- (((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature & 0xFF),
- ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 8) & 0xFF),
- ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 16) & 0xFF),
- ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 24) & 0xFF)
- ));
-
- // Is the ACPI table valid?
- if (CheckAcpiTableFunction) {
- Valid = CheckAcpiTableFunction ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable);
- } else {
- Valid = TRUE;
- }
-
- // Install the ACPI Table
- if (Valid) {
- Status = AcpiProtocol->InstallAcpiTable (
- AcpiProtocol,
- AcpiTable,
- AcpiTableSize,
- &AcpiTableKey
- );
- }
-
- // Free memory allocated by ReadSection
- gBS->FreePool (AcpiTable);
-
- if (EFI_ERROR (Status)) {
- break;
- }
-
- // Increment the section instance
- SectionInstance++;
+
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ FoundAcpiFile = TRUE;
+
+ AcpiTableKey = 0;
+ AcpiTableSize = ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Length;
+ ASSERT (SectionSize >= AcpiTableSize);
+
+ DEBUG ((
+ DEBUG_ERROR,
+ "- Found '%c%c%c%c' ACPI Table\n",
+ (((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature & 0xFF),
+ ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 8) & 0xFF),
+ ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 16) & 0xFF),
+ ((((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable)->Signature >> 24) & 0xFF)
+ ));
+
+ // Is the ACPI table valid?
+ if (CheckAcpiTableFunction != NULL) {
+ Valid = CheckAcpiTableFunction ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable);
+ } else {
+ Valid = TRUE;
}
+
+ // Install the ACPI Table
+ if (Valid) {
+ Status = AcpiProtocol->InstallAcpiTable (
+ AcpiProtocol,
+ AcpiTable,
+ AcpiTableSize,
+ &AcpiTableKey
+ );
+ }
+
+ // Free memory allocated by ReadSection
+ gBS->FreePool (AcpiTable);
+
+ // Increment the section instance
+ SectionInstance++;
}
}
@@ -157,7 +161,7 @@ FREE_HANDLE_BUFFER:
//
gBS->FreePool (HandleBuffer);
- return EFI_SUCCESS;
+ return (FoundAcpiFile ? EFI_SUCCESS : EFI_NOT_FOUND);
}
/**
diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
index d16929f..1a0c92d 100644
--- a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
+++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
@@ -9,6 +9,7 @@
#include <libfdt.h>
#include <Library/AndroidBootImgLib.h>
+#include <Library/BaseMemoryLib.h>
#include <Library/PrintLib.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootServicesTableLib.h>
diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
index 9754664..0973315 100644
--- a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
+++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
@@ -26,6 +26,7 @@
AndroidBootImgLib.c
[LibraryClasses]
+ BaseLib
DebugLib
FdtLib
PrintLib
diff --git a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c
index e193352..403cc8e 100644
--- a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c
+++ b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c
@@ -500,10 +500,12 @@ DmaAllocateAlignedBuffer (
{
EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
VOID *Allocation;
- UINT64 MemType;
+ UINT64 Attributes;
UNCACHED_ALLOCATION *Alloc;
EFI_STATUS Status;
+ Attributes = EFI_MEMORY_XP;
+
if (Alignment == 0) {
Alignment = EFI_PAGE_SIZE;
}
@@ -534,9 +536,9 @@ DmaAllocateAlignedBuffer (
// Choose a suitable uncached memory type that is supported by the region
if (GcdDescriptor.Capabilities & EFI_MEMORY_WC) {
- MemType = EFI_MEMORY_WC;
+ Attributes |= EFI_MEMORY_WC;
} else if (GcdDescriptor.Capabilities & EFI_MEMORY_UC) {
- MemType = EFI_MEMORY_UC;
+ Attributes |= EFI_MEMORY_UC;
} else {
Status = EFI_UNSUPPORTED;
goto FreeBuffer;
@@ -553,11 +555,37 @@ DmaAllocateAlignedBuffer (
InsertHeadList (&UncachedAllocationList, &Alloc->Link);
- // Remap the region with the new attributes
+ // Ensure that EFI_MEMORY_XP is in the capability set
+ if ((GcdDescriptor.Capabilities & EFI_MEMORY_XP) != EFI_MEMORY_XP) {
+ Status = gDS->SetMemorySpaceCapabilities (
+ (PHYSICAL_ADDRESS)(UINTN)Allocation,
+ EFI_PAGES_TO_SIZE (Pages),
+ GcdDescriptor.Capabilities | EFI_MEMORY_XP
+ );
+
+ // if we were to fail setting the capability, this would indicate an internal failure of the GCD code. We should
+ // assert here to let a platform know something went crazy, but for a release build we can let the allocation occur
+ // without the EFI_MEMORY_XP bit set, as that was the existing behavior
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a failed to set EFI_MEMORY_XP capability on 0x%llx for length 0x%llx. Attempting to allocate without XP set.\n",
+ __func__,
+ Allocation,
+ EFI_PAGES_TO_SIZE (Pages)
+ ));
+
+ ASSERT_EFI_ERROR (Status);
+
+ Attributes &= ~EFI_MEMORY_XP;
+ }
+ }
+
+ // Remap the region with the new attributes and mark it non-executable
Status = gDS->SetMemorySpaceAttributes (
(PHYSICAL_ADDRESS)(UINTN)Allocation,
EFI_PAGES_TO_SIZE (Pages),
- MemType
+ Attributes
);
if (EFI_ERROR (Status)) {
goto FreeAlloc;
diff --git a/EmbeddedPkg/Library/PrePiHobLib/Hob.c b/EmbeddedPkg/Library/PrePiHobLib/Hob.c
index cbc3515..49b2fecb8 100644
--- a/EmbeddedPkg/Library/PrePiHobLib/Hob.c
+++ b/EmbeddedPkg/Library/PrePiHobLib/Hob.c
@@ -333,14 +333,10 @@ GetFirstGuidHob (
}
/**
- Get the Boot Mode from the HOB list.
+ This service enables PEIMs to ascertain the present value of the boot mode.
- This function returns the system boot mode information from the
- PHIT HOB in HOB list.
- @param VOID
-
- @return The Boot Mode.
+ @retval BootMode
**/
EFI_BOOT_MODE
@@ -356,14 +352,11 @@ GetBootMode (
}
/**
- Get the Boot Mode from the HOB list.
-
- This function returns the system boot mode information from the
- PHIT HOB in HOB list.
+ This service enables PEIMs to update the boot mode variable.
- @param VOID
+ @param BootMode The value of the boot mode to set.
- @return The Boot Mode.
+ @retval EFI_SUCCESS The value was successfully updated
**/
EFI_STATUS
@@ -376,7 +369,7 @@ SetBootMode (
Hob.Raw = GetHobList ();
Hob.HandoffInformationTable->BootMode = BootMode;
- return BootMode;
+ return EFI_SUCCESS;
}
/**
diff --git a/EmbeddedPkg/Library/TemplateResetSystemLib/ResetSystemLib.c b/EmbeddedPkg/Library/TemplateResetSystemLib/ResetSystemLib.c
deleted file mode 100644
index 60bbaeb..0000000
--- a/EmbeddedPkg/Library/TemplateResetSystemLib/ResetSystemLib.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/** @file
- Template library implementation to support ResetSystem Runtime call.
-
- Fill in the templates with what ever makes you system reset.
-
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <PiDxe.h>
-
-#include <Library/BaseLib.h>
-#include <Library/IoLib.h>
-#include <Library/EfiResetSystemLib.h>
-
-/**
- Resets the entire platform.
-
- @param ResetType The type of reset to perform.
- @param ResetStatus The status code for the reset.
- @param DataSize The size, in bytes, of WatchdogData.
- @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
- EfiResetShutdown the data buffer starts with a Null-terminated
- Unicode string, optionally followed by additional binary data.
-
-**/
-EFI_STATUS
-EFIAPI
-LibResetSystem (
- IN EFI_RESET_TYPE ResetType,
- IN EFI_STATUS ResetStatus,
- IN UINTN DataSize,
- IN CHAR16 *ResetData OPTIONAL
- )
-{
- UINTN Address;
- UINT8 Data;
-
- switch (ResetType) {
- case EfiResetCold:
- // system power cycle
-
- // Example using IoLib functions to do IO.
- Address = 0x12345678;
- Data = MmioRead8 (Address);
- MmioWrite8 (Address, Data | 0x01);
-
- // Note this is a bad example asa MmioOr8 (Address, 0x01) does the same thing
- break;
-
- case EfiResetWarm:
- // not a full power cycle, maybe memory stays around.
- // if not support do the same thing as EfiResetCold.
- break;
-
- case EfiResetShutdown:
- // turn off the system.
- // if not support do the same thing as EfiResetCold.
- break;
-
- default:
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // If we reset, we would not have returned...
- //
- return EFI_DEVICE_ERROR;
-}
-
-/**
- Initialize any infrastructure required for LibResetSystem () to 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 always returns EFI_SUCCESS.
-
-**/
-EFI_STATUS
-EFIAPI
-LibInitializeResetSystem (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- return EFI_SUCCESS;
-}
diff --git a/EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf b/EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf
deleted file mode 100644
index cd7a9f8..0000000
--- a/EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf
+++ /dev/null
@@ -1,30 +0,0 @@
-#/** @file
-# Memory Status Code Library for UEFI drivers
-#
-# Lib to provide memory journal status code reporting Routines
-# Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-#**/
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = TemplateResetSystemLib
- FILE_GUID = 40BAFDE5-4CC8-4FBE-A8BA-071890076E50
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = EfiResetSystemLib
-
-
-[Sources.common]
- ResetSystemLib.c
-
-[Packages]
- MdePkg/MdePkg.dec
- EmbeddedPkg/EmbeddedPkg.dec
-
-[LibraryClasses]
- IoLib
- DebugLib
diff --git a/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c b/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c
index ce288d7..f066b1f 100644
--- a/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c
+++ b/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.c
@@ -2,7 +2,7 @@
*
* Implement virtual EFI RealTimeClock runtime services.
*
- * Coypright (c) 2019, Pete Batard <pete@akeo.ie>
+ * Copyright (c) 2019, Pete Batard <pete@akeo.ie>
* Copyright (c) 2018, Andrei Warkentin <andrey.warkentin@gmail.com>
* Copyright (c) 2011-2021, ARM Ltd. All rights reserved.
* Copyright (c) 2008-2010, Apple Inc. All rights reserved.
diff --git a/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf b/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
index 5d0f867..285e880 100644
--- a/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
+++ b/EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
@@ -34,4 +34,4 @@
# Current usage of this library expects GCC in a UNIX-like shell environment with the date command
[BuildOptions]
- GCC:*_*_*_CC_FLAGS = -DBUILD_EPOCH=`date +%s`
+ GCC:*_*_*_CC_FLAGS = -DBUILD_EPOCH=`printenv SOURCE_DATE_EPOCH || date +%s`
diff --git a/EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf b/EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
deleted file mode 100644
index fdb93bf..0000000
--- a/EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+++ /dev/null
@@ -1,45 +0,0 @@
-#/** @file
-# Reset Architectural Protocol Driver as defined in PI
-#
-# This Reset module simulates system reset by process exit on NT.
-# Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-#**/
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = Reset
- FILE_GUID = 16036A73-E8EF-46D0-953C-9B8E96527D13
- MODULE_TYPE = DXE_RUNTIME_DRIVER
- VERSION_STRING = 1.0
-
- ENTRY_POINT = InitializeReset
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32
-#
-
-[Sources.common]
- reset.c
-
-[Packages]
- MdePkg/MdePkg.dec
- EmbeddedPkg/EmbeddedPkg.dec
-
-[LibraryClasses]
- UefiBootServicesTableLib
- UefiDriverEntryPoint
- DebugLib
- EfiResetSystemLib
-
-[Protocols]
- gEfiResetArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED
-
-[Depex]
- TRUE
-
diff --git a/EmbeddedPkg/ResetRuntimeDxe/reset.c b/EmbeddedPkg/ResetRuntimeDxe/reset.c
deleted file mode 100644
index 213963b..0000000
--- a/EmbeddedPkg/ResetRuntimeDxe/reset.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/** @file
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <PiDxe.h>
-#include <Protocol/Reset.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/EfiResetSystemLib.h>
-
-/**
- Resets the entire platform.
-
- @param ResetType The type of reset to perform.
- @param ResetStatus The status code for the reset.
- @param DataSize The size, in bytes, of WatchdogData.
- @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
- EfiResetShutdown the data buffer starts with a Null-terminated
- Unicode string, optionally followed by additional binary data.
-
-**/
-VOID
-EFIAPI
-ResetSystemViaLib (
- IN EFI_RESET_TYPE ResetType,
- IN EFI_STATUS ResetStatus,
- IN UINTN DataSize,
- IN VOID *ResetData OPTIONAL
- )
-{
- LibResetSystem (ResetType, ResetStatus, DataSize, ResetData);
- return;
-}
-
-EFI_STATUS
-EFIAPI
-InitializeReset (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE Handle;
-
- LibInitializeResetSystem (ImageHandle, SystemTable);
-
- SystemTable->RuntimeServices->ResetSystem = ResetSystemViaLib;
-
- Handle = NULL;
- Status = gBS->InstallMultipleProtocolInterfaces (
- &Handle,
- &gEfiResetArchProtocolGuid,
- NULL,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- return Status;
-}
diff --git a/EmulatorPkg/EmulatorPkg.ci.yaml b/EmulatorPkg/EmulatorPkg.ci.yaml
index 6e9b285..6090fe3 100644
--- a/EmulatorPkg/EmulatorPkg.ci.yaml
+++ b/EmulatorPkg/EmulatorPkg.ci.yaml
@@ -9,6 +9,9 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "EmulatorPkg.dsc",
+ },
## options defined .pytool/Plugin/LicenseCheck
"LicenseCheck": {
"IgnoreFiles": []
diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc
index 1c356bc..e4bf3ce 100644
--- a/EmulatorPkg/EmulatorPkg.dsc
+++ b/EmulatorPkg/EmulatorPkg.dsc
@@ -151,6 +151,8 @@
PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
TimerLib|EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.inf
+ # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
[LibraryClasses.common.USER_DEFINED, LibraryClasses.common.BASE]
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
@@ -319,13 +321,25 @@
# Emulator, OS WIN application
# CLANGPDB is cross OS tool chain. It depends on WIN_HOST_BUILD flag
# to build WinHost application.
+ #
+ # USER_DEFINED components skip normal NULL lib linking, so we have to link this
+ # specially here for the libs that have stack guard enabled
##
- EmulatorPkg/Win/Host/WinHost.inf
+ EmulatorPkg/Win/Host/WinHost.inf {
+ <LibraryClasses>
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+ }
!else
##
# Emulator, OS POSIX application
+ #
+ # USER_DEFINED components skip normal NULL lib linking, so we have to link this
+ # specially here for the libs that have stack guard enabled
##
- EmulatorPkg/Unix/Host/Host.inf
+ EmulatorPkg/Unix/Host/Host.inf {
+ <LibraryClasses>
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+ }
!endif
!endif
diff --git a/EmulatorPkg/Unix/Host/Host.inf b/EmulatorPkg/Unix/Host/Host.inf
index f5ebbed..1b7481d 100644
--- a/EmulatorPkg/Unix/Host/Host.inf
+++ b/EmulatorPkg/Unix/Host/Host.inf
@@ -124,6 +124,7 @@
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:*_GCC_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
diff --git a/EmulatorPkg/Win/Host/WinHost.inf b/EmulatorPkg/Win/Host/WinHost.inf
index 4dac6e0..6bb3d96 100644
--- a/EmulatorPkg/Win/Host/WinHost.inf
+++ b/EmulatorPkg/Win/Host/WinHost.inf
@@ -94,6 +94,7 @@
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:*_VS2022_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
@@ -101,6 +102,7 @@
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:*_VS2022_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
diff --git a/FatPkg/EnhancedFatDxe/DiskCache.c b/FatPkg/EnhancedFatDxe/DiskCache.c
index d1a34a6..9ecb2ea 100644
--- a/FatPkg/EnhancedFatDxe/DiskCache.c
+++ b/FatPkg/EnhancedFatDxe/DiskCache.c
@@ -9,6 +9,206 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "Fat.h"
/**
+ Helper function to clear the dirty state of the cache line.
+
+ @param[in] CacheTag - CacheTag to clear
+
+**/
+STATIC
+VOID
+ClearCacheTagDirtyState (
+ IN CACHE_TAG *CacheTag
+ )
+{
+ if (CacheTag == NULL) {
+ ASSERT (CacheTag != NULL);
+ return;
+ }
+
+ ZeroMem (CacheTag->DirtyBlocks, sizeof (CacheTag->DirtyBlocks));
+ CacheTag->Dirty = FALSE;
+}
+
+/**
+ Helper function to set a bit in a dirty block. This is used to
+ track which blocks to later write to disk.
+
+ @param[in] BitNumber - Which bit to set in DirtyBlocks
+ @param[in] DirtyBlocks - Array of bits
+
+**/
+STATIC
+VOID
+SetBitInDirtyBlock (
+ IN UINTN BitNumber,
+ IN DIRTY_BLOCKS *DirtyBlocks
+ )
+{
+ UINTN BlockIndex;
+ UINTN BitIndex;
+
+ //
+ // ASSERTs checking BitNumber are DEBUG build only to verify the assumptions in the
+ // Fat.h defines (See Fat.h lines to describe DIRTY_BITS)
+ //
+ ASSERT (BitNumber < DIRTY_BITS);
+
+ BlockIndex = BitNumber / DIRTY_BITS_PER_BLOCK;
+ BitIndex = BitNumber % DIRTY_BITS_PER_BLOCK;
+ DirtyBlocks[BlockIndex] |= LShiftU64 (1ull, BitIndex);
+}
+
+/**
+ Helper function to check if a particular bit in a dirty block is marked dirty or not,
+ so that it can be written to the disk if it is dirty.
+
+ @param[in] BitNumber - Which bit to check in DirtyBlocks
+ @param[in] DirtyBlocks - Array of bits
+
+**/
+STATIC
+BOOLEAN
+IsBitInBlockDirty (
+ IN UINTN BitNumber,
+ IN DIRTY_BLOCKS *DirtyBlocks
+ )
+{
+ UINTN BlockIndex;
+ UINTN BitIndex;
+
+ ASSERT (BitNumber < DIRTY_BITS);
+
+ BlockIndex = BitNumber / DIRTY_BITS_PER_BLOCK;
+ BitIndex = BitNumber % DIRTY_BITS_PER_BLOCK;
+ return (DirtyBlocks[BlockIndex] & LShiftU64 (1ull, BitIndex)) != 0;
+}
+
+/**
+ Helper function to set a cache tag dirty for a given offset and length. Dirty blocks marked
+ here will be flushed to disk when the file is closed.
+
+ @param[in] DiskCache - DiskCache
+ @param[in] CacheTag - CacheTag to update
+ @param[in] Offset - Offset in the cache line to be marked modified
+ @param[in] Length - Length of the data to be marked modified
+
+**/
+STATIC
+VOID
+SetCacheTagDirty (
+ IN DISK_CACHE *DiskCache,
+ IN CACHE_TAG *CacheTag,
+ IN UINTN Offset,
+ IN UINTN Length
+ )
+{
+ UINTN Bit;
+ UINTN LastBit;
+
+ Bit = Offset / DiskCache->BlockSize;
+ LastBit = (Offset + Length - 1) / DiskCache->BlockSize;
+
+ ASSERT (Bit <= LastBit);
+ ASSERT (LastBit <= DIRTY_BITS);
+
+ do {
+ SetBitInDirtyBlock (Bit, CacheTag->DirtyBlocks);
+ } while (++Bit <= LastBit);
+
+ CacheTag->Dirty = TRUE;
+}
+
+/**
+ Cache version of FatDiskIo for writing only those LBA's with dirty data.
+
+ Keep track of LBA blocks within a cache line. Allow reads from the disk to read the
+ full cache line, and all writes to the cache line will update which Lba is dirty in DIRTY_BITS.
+
+ At flush time, when the cache line is written out, only write the blocks that are dirty, coalescing
+ adjacent writes to a single FatDiskIo write.
+
+ @param[in] CacheTag - Cache line to check for dirty bits from
+ @param[in] DataType - Type of Cache.
+ @param[in] Volume - FAT file system volume.
+ @param[in] IoMode - The access mode (disk read/write or cache access).
+ @param[in] Offset - The starting byte offset to read from.
+ @param[in] BufferSize - Size of Buffer.
+ @param[in, out] Buffer - Buffer containing read data.
+ @param[in] Task point to task instance.
+
+ @retval EFI_SUCCESS - The operation is performed successfully.
+ @retval EFI_VOLUME_CORRUPTED - The access is
+ @return Others - The status of read/write the disk
+
+**/
+STATIC
+EFI_STATUS
+CacheFatDiskIo (
+ IN CACHE_TAG *CacheTag,
+ IN CACHE_DATA_TYPE DataType,
+ IN FAT_VOLUME *Volume,
+ IN IO_MODE IoMode,
+ IN UINT64 Offset,
+ IN UINTN BufferSize,
+ IN OUT VOID *Buffer,
+ IN FAT_TASK *Task
+ )
+{
+ DISK_CACHE *DiskCache;
+ UINTN BlockIndexInTag;
+ VOID *WriteBuffer;
+ UINTN LastBit;
+ UINT64 StartPos;
+ EFI_STATUS Status;
+ UINTN WriteSize;
+
+ Status = EFI_SUCCESS;
+ if ((IoMode == WriteDisk) && (CacheTag->RealSize != 0)) {
+ DiskCache = &Volume->DiskCache[DataType];
+ WriteBuffer = Buffer;
+ LastBit = (CacheTag->RealSize - 1) / DiskCache->BlockSize;
+ StartPos = Offset;
+ BlockIndexInTag = 0;
+ WriteSize = 0;
+
+ do {
+ if (IsBitInBlockDirty (BlockIndexInTag, CacheTag->DirtyBlocks)) {
+ do {
+ WriteSize += DiskCache->BlockSize;
+ BlockIndexInTag++;
+ if (BlockIndexInTag > LastBit) {
+ break;
+ }
+ } while (IsBitInBlockDirty (BlockIndexInTag, CacheTag->DirtyBlocks));
+
+ Status = FatDiskIo (Volume, IoMode, StartPos, WriteSize, WriteBuffer, Task);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ StartPos += WriteSize + DiskCache->BlockSize;
+ WriteBuffer = (VOID *)((UINTN)WriteBuffer + WriteSize + DiskCache->BlockSize);
+ WriteSize = 0;
+ BlockIndexInTag++;
+ } else {
+ StartPos += DiskCache->BlockSize;
+ WriteBuffer = (VOID *)((UINTN)WriteBuffer + DiskCache->BlockSize);
+ BlockIndexInTag++;
+ }
+ } while (BlockIndexInTag <= LastBit);
+
+ ASSERT (WriteSize == 0);
+ } else {
+ Status = FatDiskIo (Volume, IoMode, Offset, BufferSize, Buffer, Task);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return Status;
+}
+
+/**
This function is used by the Data Cache.
@@ -57,8 +257,8 @@ FatFlushDataCacheRange (
CacheTag = &DiskCache->CacheTag[GroupNo];
if ((CacheTag->RealSize > 0) && (CacheTag->PageNo == PageNo)) {
//
- // When reading data form disk directly, if some dirty data
- // in cache is in this rang, this data in the Buffer need to
+ // When reading data from disk directly, if some dirty data
+ // in cache is in this range, this data in the Buffer needs to
// be updated with the cache's dirty data.
//
if (IoMode == ReadDisk) {
@@ -119,7 +319,7 @@ FatExchangeCachePage (
GroupNo = PageNo & DiskCache->GroupMask;
PageAlignment = DiskCache->PageAlignment;
PageAddress = DiskCache->CacheBase + (GroupNo << PageAlignment);
- EntryPos = DiskCache->BaseAddress + LShiftU64 (PageNo, PageAlignment);
+ EntryPos = (DiskCache->BaseAddress + LShiftU64 (PageNo, PageAlignment));
RealSize = CacheTag->RealSize;
if (IoMode == ReadDisk) {
RealSize = (UINTN)1 << PageAlignment;
@@ -139,7 +339,7 @@ FatExchangeCachePage (
//
// Only fat table writing will execute more than once
//
- Status = FatDiskIo (Volume, IoMode, EntryPos, RealSize, PageAddress, Task);
+ Status = CacheFatDiskIo (CacheTag, DataType, Volume, IoMode, EntryPos, RealSize, PageAddress, Task);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -147,7 +347,7 @@ FatExchangeCachePage (
EntryPos += Volume->FatSize;
} while (--WriteCount > 0);
- CacheTag->Dirty = FALSE;
+ ClearCacheTagDirtyState (CacheTag);
CacheTag->RealSize = RealSize;
return EFI_SUCCESS;
}
@@ -248,7 +448,7 @@ FatAccessUnalignedCachePage (
Source = DiskCache->CacheBase + (GroupNo << DiskCache->PageAlignment) + Offset;
Destination = Buffer;
if (IoMode != ReadDisk) {
- CacheTag->Dirty = TRUE;
+ SetCacheTagDirty (DiskCache, CacheTag, Offset, Length);
DiskCache->Dirty = TRUE;
Destination = Source;
Source = Buffer;
@@ -489,5 +689,9 @@ FatInitializeDiskCache (
Volume->CacheBuffer = CacheBuffer;
DiskCache[CacheFat].CacheBase = CacheBuffer;
DiskCache[CacheData].CacheBase = CacheBuffer + FatCacheSize;
+
+ DiskCache[CacheFat].BlockSize = Volume->BlockIo->Media->BlockSize;
+ DiskCache[CacheData].BlockSize = Volume->BlockIo->Media->BlockSize;
+
return EFI_SUCCESS;
}
diff --git a/FatPkg/EnhancedFatDxe/Fat.h b/FatPkg/EnhancedFatDxe/Fat.h
index 356cdbd..fb66990 100644
--- a/FatPkg/EnhancedFatDxe/Fat.h
+++ b/FatPkg/EnhancedFatDxe/Fat.h
@@ -84,6 +84,19 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define FAT_FATCACHE_GROUP_MIN_COUNT 1
#define FAT_FATCACHE_GROUP_MAX_COUNT 16
+// For cache block bits, use a UINT64
+typedef UINT64 DIRTY_BLOCKS;
+#define BITS_PER_BYTE 8
+#define DIRTY_BITS_PER_BLOCK ((sizeof (DIRTY_BLOCKS) * BITS_PER_BYTE))
+
+// largest cache line (64KB) / MinLbaSize (512) = 128 bits
+#define DIRTY_BITS ((1 << FAT_DATACACHE_PAGE_MAX_ALIGNMENT) / (1 << MIN_BLOCK_ALIGNMENT))
+
+// Number of DIRTY_BLOCKS to hold DIRTY_BITS bits.
+#define DIRTY_BLOCKS_SIZE (DIRTY_BITS / sizeof (DIRTY_BLOCKS))
+
+STATIC_ASSERT ((((1 << FAT_DATACACHE_PAGE_MAX_ALIGNMENT) / (1 << MIN_BLOCK_ALIGNMENT)) % sizeof (DIRTY_BLOCKS)) == 0, "DIRTY_BLOCKS not a proper size");
+
//
// Used in 8.3 generation algorithm
//
@@ -143,15 +156,17 @@ typedef enum {
// Disk cache tag
//
typedef struct {
- UINTN PageNo;
- UINTN RealSize;
- BOOLEAN Dirty;
+ UINTN PageNo;
+ UINTN RealSize;
+ BOOLEAN Dirty;
+ DIRTY_BLOCKS DirtyBlocks[DIRTY_BLOCKS_SIZE];
} CACHE_TAG;
typedef struct {
UINT64 BaseAddress;
UINT64 LimitAddress;
UINT8 *CacheBase;
+ UINT32 BlockSize;
BOOLEAN Dirty;
UINT8 PageAlignment;
UINTN GroupMask;
diff --git a/FatPkg/EnhancedFatDxe/Init.c b/FatPkg/EnhancedFatDxe/Init.c
index 208318c..9c51ed5 100644
--- a/FatPkg/EnhancedFatDxe/Init.c
+++ b/FatPkg/EnhancedFatDxe/Init.c
@@ -61,6 +61,32 @@ FatAllocateVolume (
//
Volume->RootDirEnt.FileString = Volume->RootFileString;
Volume->RootDirEnt.Entry.Attributes = FAT_ATTRIBUTE_DIRECTORY;
+
+ if ((BlockIo == NULL) || (BlockIo->Media == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a BlockIo or BlockIo is NULL!\n", __func__));
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ //
+ // Check to see if the underlying block device's BlockSize meets what the FAT spec requires
+ //
+ if ((BlockIo->Media->BlockSize != 512) &&
+ (BlockIo->Media->BlockSize != SIZE_1KB) &&
+ (BlockIo->Media->BlockSize != SIZE_2KB) &&
+ (BlockIo->Media->BlockSize != SIZE_4KB))
+ {
+ Status = EFI_UNSUPPORTED;
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a invalid BlockIo BlockSize %u for FAT filesystem on MediaId %u. Must be 512B, 1KB, 2KB, or 4KB\n",
+ __func__,
+ BlockIo->Media->BlockSize,
+ BlockIo->Media->MediaId
+ ));
+ goto Done;
+ }
+
//
// Check to see if there's a file system on the volume
//
@@ -221,7 +247,7 @@ FatOpenDevice (
Status = DiskIo->ReadDisk (DiskIo, Volume->MediaId, 0, sizeof (FatBs), &FatBs);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INIT, "FatOpenDevice: read of part_lba failed %r\n", Status));
+ DEBUG ((DEBUG_VERBOSE, "%a: read of part_lba failed %r\n", __func__, Status));
return Status;
}
diff --git a/FatPkg/FatPkg.ci.yaml b/FatPkg/FatPkg.ci.yaml
index fe95f48..d54e5bb 100644
--- a/FatPkg/FatPkg.ci.yaml
+++ b/FatPkg/FatPkg.ci.yaml
@@ -59,7 +59,8 @@
"Lfnbuffer",
"FFFFFFFFL",
"CDVOL",
- "DMDEPKG"
+ "DMDEPKG",
+ "lba's"
]
}
}
diff --git a/FatPkg/FatPkg.dsc b/FatPkg/FatPkg.dsc
index 076b577..76dddaa 100644
--- a/FatPkg/FatPkg.dsc
+++ b/FatPkg/FatPkg.dsc
@@ -49,6 +49,10 @@
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.PEIM]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
@@ -56,10 +60,6 @@
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
-[LibraryClasses.ARM, LibraryClasses.AARCH64]
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
###################################################################################################
#
# Components Section - list of the modules and components that will be processed by compilation
diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc
index f9f26c5..c38cbc4 100644
--- a/FmpDevicePkg/FmpDevicePkg.dsc
+++ b/FmpDevicePkg/FmpDevicePkg.dsc
@@ -72,17 +72,9 @@
FmpDependencyDeviceLib|FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf
TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
-[LibraryClasses.ARM, LibraryClasses.AARCH64]
- #
- # It is not possible to prevent the ARM compiler for generic intrinsic functions.
- # This library provides the intrinsic functions generate by a given compiler.
- # [LibraryClasses.ARM, LibraryClasses.AARCH64] and NULL mean link this library
- # into all ARM and AARCH64 images.
- #
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- # Add support for stack protector
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
[LibraryClasses.ARM]
ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c
index 1e7ec4a..b04998b 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.c
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.c
@@ -181,7 +181,12 @@ GetImageTypeIdGuid (
if (ImageTypeIdGuidSize == sizeof (EFI_GUID)) {
FmpDeviceLibGuid = (EFI_GUID *)PcdGetPtr (PcdFmpDeviceImageTypeIdGuid);
} else {
- DEBUG ((DEBUG_WARN, "FmpDxe(%s): Fall back to ImageTypeIdGuid of gEfiCallerIdGuid\n", mImageIdName));
+ DEBUG ((
+ DEBUG_ERROR,
+ "FmpDxe(%s): Fall back to ImageTypeIdGuid of gEfiCallerIdGuid. FmpDxe error: misconfiguration\n",
+ mImageIdName
+ ));
+ ASSERT (FALSE);
FmpDeviceLibGuid = &gEfiCallerIdGuid;
}
}
diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.inf b/FmpDevicePkg/FmpDxe/FmpDxe.inf
index 1c29638..d7a0273 100644..100755
--- a/FmpDevicePkg/FmpDxe/FmpDxe.inf
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.inf
@@ -5,6 +5,7 @@
#
# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
# Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
@@ -78,7 +79,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed ## SOMETIMES_PRODUCES
[Depex]
- gEfiVariableWriteArchProtocolGuid AND gEdkiiVariableLockProtocolGuid
+ gEfiVariableWriteArchProtocolGuid AND gEdkiiVariablePolicyProtocolGuid
[UserExtensions.TianoCore."ExtraFiles"]
FmpDxeExtra.uni
diff --git a/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf
index 762d485..40ff9f2 100644
--- a/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf
+++ b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf
@@ -69,6 +69,7 @@
gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage ## CONSUMES
gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxInterruptSupported ## CONSUMES
gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable ## CONSUMES
[Ppis]
gEfiTemporaryRamSupportPpiGuid ## PRODUCES
diff --git a/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf b/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf
index 3acf4f6..ac572a6 100644
--- a/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf
+++ b/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf
@@ -68,6 +68,7 @@
gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage ## CONSUMES
gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxInterruptSupported ## CONSUMES
gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable ## CONSUMES
[Ppis]
gEfiTemporaryRamSupportPpiGuid ## PRODUCES
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm
index 5fa5c03..e9bf0cb 100644
--- a/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm
+++ b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm
@@ -13,6 +13,7 @@
extern ASM_PFX(PcdGet32(PcdTemporaryRamBase))
extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize))
extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
struc FSPM_UPD_COMMON
; FSP_UPD_HEADER {
@@ -64,7 +65,7 @@ extern ASM_PFX(AsmGetFspInfoHeader)
extern ASM_PFX(FspMultiPhaseMemInitApiHandler)
STACK_SAVED_EAX_OFFSET EQU 4 * 7 ; size of a general purpose register * eax index
-API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call]
+API_PARAM1_OFFSET EQU 44h ; ApiParam1 [ sub esp,8 + push cr0/cr3/cr4/EFER + pushad + pushfd + push eax + call]
FSP_HEADER_IMGBASE_OFFSET EQU 1Ch
FSP_HEADER_CFGREG_OFFSET EQU 24h
@@ -153,6 +154,33 @@ NotMultiPhaseMemoryInitApi:
cli
pushad
+ ;
+ ; Allocate 4x4 bytes on the stack.
+ ;
+ sub esp, 16
+ cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0
+ jz SkipPagetableSave
+
+ add esp, 16
+ ; Save EFER MSR lower 32 bits
+ push ecx
+ push eax
+ mov ecx, 0xC0000080
+ rdmsr
+ mov edx, eax
+ pop eax
+ pop ecx
+ push edx
+
+ ; Save CR registers
+ mov edx, cr4
+ push edx
+ mov edx, cr3
+ push edx
+ mov edx, cr0
+ push edx
+SkipPagetableSave:
+
; Reserve 8 bytes for IDT save/restore
sub esp, 8
sidt [esp]
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm
index 861cce4..b162306 100644
--- a/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm
+++ b/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm
@@ -13,6 +13,7 @@
extern ASM_PFX(PcdGet32(PcdTemporaryRamBase))
extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize))
extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
struc FSPM_UPD_COMMON
; FSP_UPD_HEADER {
@@ -62,7 +63,7 @@ extern ASM_PFX(FspApiCommon)
extern ASM_PFX(AsmGetFspBaseAddress)
extern ASM_PFX(AsmGetFspInfoHeader)
-API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call]
+API_PARAM1_OFFSET EQU 44h ; ApiParam1 [ sub esp,8 + push cr0/cr3/cr4/EFER +pushad + pushfd + push eax + call]
FSP_HEADER_IMGBASE_OFFSET EQU 1Ch
FSP_HEADER_CFGREG_OFFSET EQU 24h
@@ -124,6 +125,33 @@ ASM_PFX(FspApiCommonContinue):
cli
pushad
+ ;
+ ; Allocate 4x4 bytes on the stack.
+ ;
+ sub esp, 16
+ cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0
+ jz SkipPagetableSave
+
+ add esp, 16
+ ; Save EFER MSR lower 32-bit
+ push ecx
+ push eax
+ mov ecx, 0xC0000080
+ rdmsr
+ mov edx, eax
+ pop eax
+ pop ecx
+ push edx
+
+ ; Save CR registers
+ mov edx, cr4
+ push edx
+ mov edx, cr3
+ push edx
+ mov edx, cr0
+ push edx
+
+SkipPagetableSave:
; Reserve 8 bytes for IDT save/restore
sub esp, 8
sidt [esp]
diff --git a/IntelFsp2Pkg/FspSecCore/SecFsp.c b/IntelFsp2Pkg/FspSecCore/SecFsp.c
index 281d39a..c4d4d11 100644
--- a/IntelFsp2Pkg/FspSecCore/SecFsp.c
+++ b/IntelFsp2Pkg/FspSecCore/SecFsp.c
@@ -53,7 +53,7 @@ SecGetPlatformData (
FSP_PLAT_DATA *FspPlatformData;
UINT32 TopOfCar;
UINT32 *StackPtr;
- UINT32 DwordSize;
+ UINT32 DataSize;
UINT32 TemporaryRamSize;
FspPlatformData = &FspData->PlatformData;
@@ -89,22 +89,21 @@ SecGetPlatformData (
//
// This following data was pushed onto stack after TempRamInit API
//
- DwordSize = 4;
- StackPtr = StackPtr - 1 - DwordSize;
- CopyMem (&(FspPlatformData->MicrocodeRegionBase), StackPtr, (DwordSize << 2));
- StackPtr--;
+ DataSize = *(StackPtr);
+ DataSize = DataSize / sizeof (DataSize);
+ StackPtr -= DataSize;
+ CopyMem (&(FspPlatformData->MicrocodeRegionBase), StackPtr + 1, 4 * sizeof (UINTN));
} else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) {
//
// This is the performance data for InitTempMemory API entry/exit
//
- DwordSize = 4;
- StackPtr = StackPtr - 1 - DwordSize;
- CopyMem (FspData->PerfData, StackPtr, (DwordSize << 2));
+ DataSize = *(StackPtr);
+ DataSize = DataSize / sizeof (DataSize);
+ StackPtr -= DataSize;
+ CopyMem (FspData->PerfData, StackPtr + 1, 2 * sizeof (UINT64)); // Copy from the end of the PER0 data
((UINT8 *)(&FspData->PerfData[0]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY;
((UINT8 *)(&FspData->PerfData[1]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT;
-
- StackPtr--;
} else {
StackPtr -= (*StackPtr);
}
diff --git a/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c b/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c
index 5f59938..644c374 100644
--- a/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c
+++ b/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c
@@ -31,7 +31,7 @@ FspApiCallingCheck (
//
// NotifyPhase check
//
- if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) {
+ if ((FspData == NULL) || ((UINT32)(UINTN)FspData == MAX_UINT32)) {
Status = EFI_UNSUPPORTED;
} else {
if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) {
@@ -42,7 +42,7 @@ FspApiCallingCheck (
//
// FspMemoryInit check
//
- if (((UINTN)FspData != MAX_ADDRESS) && ((UINTN)FspData != MAX_UINT32)) {
+ if ((UINT32)(UINTN)FspData != MAX_UINT32) {
Status = EFI_UNSUPPORTED;
} else if (ApiParam == NULL) {
Status = EFI_SUCCESS;
@@ -53,7 +53,7 @@ FspApiCallingCheck (
//
// TempRamExit check
//
- if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) {
+ if ((FspData == NULL) || ((UINT32)(UINTN)FspData == MAX_UINT32)) {
Status = EFI_UNSUPPORTED;
} else {
if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) {
@@ -64,7 +64,7 @@ FspApiCallingCheck (
//
// FspSiliconInit check
//
- if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) {
+ if ((FspData == NULL) || ((UINT32)(UINTN)FspData == MAX_UINT32)) {
Status = EFI_UNSUPPORTED;
} else {
if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) {
@@ -83,14 +83,14 @@ FspApiCallingCheck (
}
}
} else if (ApiIdx == FspMultiPhaseMemInitApiIndex) {
- if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) {
+ if ((FspData == NULL) || ((UINT32)(UINTN)FspData == MAX_UINT32)) {
Status = EFI_UNSUPPORTED;
}
} else if (ApiIdx == FspSmmInitApiIndex) {
//
// FspSmmInitApiIndex check
//
- if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) {
+ if ((FspData == NULL) || ((UINT32)(UINTN)FspData == MAX_UINT32)) {
Status = EFI_UNSUPPORTED;
} else {
if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) {
diff --git a/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm
index a3b38e4..3066156 100644
--- a/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm
+++ b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm
@@ -4,7 +4,7 @@
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;;
-
+ DEFAULT REL
SECTION .text
%include "PushPopRegsNasm.inc"
@@ -13,6 +13,7 @@
; Following are fixed PCDs
;
extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
struc FSPM_UPD_COMMON_FSP24
; FSP_UPD_HEADER {
@@ -142,6 +143,36 @@ NotMultiPhaseMemoryInitApi:
cli
PUSHA_64
+ ;
+ ; Allocate 4x8 bytes on the stack.
+ ;
+ sub rsp, 32
+ lea rdx, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))]
+ mov dl, byte [rdx]
+ cmp dl, 0
+ jz SkipPagetableSave
+
+ add rsp, 32
+ ; Save EFER MSR
+ push rcx
+ push rax
+ mov rcx, 0xC0000080
+ rdmsr
+ shl rdx, 0x20
+ or rdx, rax
+ pop rax
+ pop rcx
+ push rdx
+
+ ; Save CR registers
+ mov rdx, cr4
+ push rdx
+ mov rdx, cr3
+ push rdx
+ mov rdx, cr0
+ push rdx
+SkipPagetableSave:
+
; Reserve 16 bytes for IDT save/restore
sub rsp, 16
sidt [rsp]
diff --git a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm
index 2d2f75b..b0b6b6a 100644
--- a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm
+++ b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm
@@ -4,7 +4,7 @@
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;;
-
+ DEFAULT REL
SECTION .text
%include "PushPopRegsNasm.inc"
@@ -13,6 +13,7 @@
; Following are fixed PCDs
;
extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
struc FSPM_UPD_COMMON_FSP24
; FSP_UPD_HEADER {
@@ -110,6 +111,36 @@ ASM_PFX(FspApiCommonContinue):
cli
PUSHA_64
+ ;
+ ; Allocate 4x8 bytes on the stack.
+ ;
+ sub rsp, 32
+ lea rdx, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))]
+ mov dl, byte [rdx]
+ cmp dl, 0
+ jz SkipPagetableSave
+
+ add rsp, 32
+ ; Save EFER MSR
+ push rcx
+ push rax
+ mov rcx, 0xC0000080
+ rdmsr
+ shl rdx, 0x20
+ or rdx, rax
+ pop rax
+ pop rcx
+ push rdx
+
+ ; Save CR registers
+ mov rdx, cr4
+ push rdx
+ mov rdx, cr3
+ push rdx
+ mov rdx, cr0
+ push rdx
+SkipPagetableSave:
+
; Reserve 16 bytes for IDT save/restore
sub rsp, 16
sidt [rsp]
diff --git a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm
index f1c0673..3e7a640 100644
--- a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm
+++ b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm
@@ -30,7 +30,7 @@ extern ASM_PFX(SecCarInit)
; Define the data length that we saved on the stack top
;
DATA_LEN_OF_PER0 EQU 18h
-DATA_LEN_OF_MCUD EQU 18h
+DATA_LEN_OF_MCUD EQU 28h
DATA_LEN_AT_STACK_TOP EQU (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
;
diff --git a/IntelFsp2Pkg/IntelFsp2Pkg.dec b/IntelFsp2Pkg/IntelFsp2Pkg.dec
index d1c3d3e..8fe6b64 100644
--- a/IntelFsp2Pkg/IntelFsp2Pkg.dec
+++ b/IntelFsp2Pkg/IntelFsp2Pkg.dec
@@ -114,6 +114,14 @@
#
gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize |0x00000000|UINT32|0x10000006
+[PcdsFeatureFlag]
+ #
+ # Indicates if the FSP will save and restore page table. Only works in FSP API mode
+ # TRUE - FSP will save and restore page table
+ # FALSE - FSP will not save and restore page table
+ #
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable |FALSE|BOOLEAN|0x10000007
+
[PcdsFixedAtBuild,PcdsDynamic,PcdsDynamicEx]
gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedMemoryLength |0x00100000|UINT32|0x46530000
gIntelFsp2PkgTokenSpaceGuid.PcdBootLoaderEntry |0xFFFFFFE4|UINT32|0x46530100
diff --git a/IntelFsp2Pkg/IntelFsp2Pkg.dsc b/IntelFsp2Pkg/IntelFsp2Pkg.dsc
index 991ab01..ea61c5d 100644
--- a/IntelFsp2Pkg/IntelFsp2Pkg.dsc
+++ b/IntelFsp2Pkg/IntelFsp2Pkg.dsc
@@ -46,6 +46,10 @@
FspSecPlatformLib|IntelFsp2Pkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf
FspMultiPhaseLib|IntelFsp2Pkg/Library/BaseFspMultiPhaseLib/BaseFspMultiPhaseLib.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.PEIM, LibraryClasses.common.SEC]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
diff --git a/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf b/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf
index 8badd92..52fe0f8 100644
--- a/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf
+++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf
@@ -16,6 +16,7 @@
[Sources]
FspCommonLib.c
+ ReturnStatus.c
[Packages]
MdePkg/MdePkg.dec
diff --git a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
index d33d01f..663f9b3 100644
--- a/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
+++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
@@ -15,21 +15,14 @@
#pragma pack(1)
-//
-// API Parameter +0x34
-// API return address +0x30
-//
-// push FspInfoHeader +0x2C
-// pushfd +0x28
-// cli
-// pushad +0x24
-// sub esp, 8 +0x00
-// sidt fword ptr [esp]
-//
typedef struct {
UINT16 IdtrLimit;
UINT32 IdtrBase;
UINT16 Reserved;
+ UINT32 Cr0;
+ UINT32 Cr3;
+ UINT32 Cr4;
+ UINT32 Efer; // lower 32-bit of EFER since only NXE bit (BIT11) need to be restored.
UINT32 Registers[8]; // General Purpose Registers: Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx and Eax
UINT16 Flags[2];
UINT32 FspInfoHeader;
@@ -37,20 +30,12 @@ typedef struct {
UINT32 ApiParam[2];
} CONTEXT_STACK;
-//
-// API return address +0xB8
-// Reserved +0xB0
-// push API Parameter2 +0xA8
-// push API Parameter1 +0xA0
-// push FspInfoHeader +0x98
-// pushfq +0x90
-// cli
-// PUSHA_64 +0x10
-// sub rsp, 16 +0x00
-// sidt [rsp]
-//
typedef struct {
UINT64 Idtr[2]; // IDTR Limit - bit0:bi15, IDTR Base - bit16:bit79
+ UINT64 Cr0;
+ UINT64 Cr3;
+ UINT64 Cr4;
+ UINT64 Efer;
UINT64 Registers[16]; // General Purpose Registers: RDI, RSI, RBP, RSP, RBX, RDX, RCX, RAX, and R15 to R8
UINT32 Flags[2];
UINT64 FspInfoHeader;
@@ -89,10 +74,10 @@ GetFspGlobalDataPointer (
VOID
)
{
- FSP_GLOBAL_DATA *FspData;
+ UINT32 FspDataAddress;
- FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32 (PcdGlobalDataPointerAddress);
- return FspData;
+ FspDataAddress = *(UINT32 *)(UINTN)PcdGet32 (PcdGlobalDataPointerAddress);
+ return (FSP_GLOBAL_DATA *)(UINTN)FspDataAddress;
}
/**
@@ -566,33 +551,3 @@ SetPhaseStatusCode (
FspData = GetFspGlobalDataPointer ();
FspData->StatusCode = StatusCode;
}
-
-/**
- This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.
-
- @param[in] FspResetType Reset type that needs to returned as API return status
-
-**/
-VOID
-EFIAPI
-FspApiReturnStatusReset (
- IN EFI_STATUS FspResetType
- )
-{
- volatile BOOLEAN LoopUntilReset;
-
- LoopUntilReset = TRUE;
- DEBUG ((DEBUG_INFO, "FSP returning control to Bootloader with reset required return status %x\n", FspResetType));
- if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
- ///
- /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader
- /// calls the FSP API without honoring the reset request by FSP
- ///
- do {
- SetFspApiReturnStatus (FspResetType);
- Pei2LoaderSwitchStack ();
- DEBUG ((DEBUG_ERROR, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));
- DEBUG ((DEBUG_ERROR, "!!!ERROR: Please add support in BootLoader to honor the reset request from FSP\n"));
- } while (LoopUntilReset);
- }
-}
diff --git a/IntelFsp2Pkg/Library/BaseFspCommonLib/ReturnStatus.c b/IntelFsp2Pkg/Library/BaseFspCommonLib/ReturnStatus.c
new file mode 100644
index 0000000..1854e8c
--- /dev/null
+++ b/IntelFsp2Pkg/Library/BaseFspCommonLib/ReturnStatus.c
@@ -0,0 +1,42 @@
+/** @file
+ Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/FspCommonLib.h>
+#include <FspEas.h>
+#include <Library/FspSwitchStackLib.h>
+
+/**
+ This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.
+
+ @param[in] FspResetType Reset type that needs to returned as API return status
+
+**/
+VOID
+EFIAPI
+FspApiReturnStatusReset (
+ IN EFI_STATUS FspResetType
+ )
+{
+ volatile BOOLEAN LoopUntilReset;
+
+ LoopUntilReset = TRUE;
+ DEBUG ((DEBUG_INFO, "FSP returning control to Bootloader with reset required return status %x\n", FspResetType));
+ if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
+ ///
+ /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader
+ /// calls the FSP API without honoring the reset request by FSP
+ ///
+ do {
+ SetFspApiReturnStatus (FspResetType);
+ Pei2LoaderSwitchStack ();
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: Please add support in BootLoader to honor the reset request from FSP\n"));
+ } while (LoopUntilReset);
+ }
+}
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf
index 6909aec..0194c2e 100644
--- a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf
+++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf
@@ -32,5 +32,5 @@
BaseLib
IoLib
-
-
+[Pcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspSaveRestorePageTableEnable
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm
index 6599901..d138424 100644
--- a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm
+++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/Ia32/Stack.nasm
@@ -12,6 +12,12 @@
SECTION .text
extern ASM_PFX(SwapStack)
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
+
+; Page table related bits in CR0/CR4/EFER
+%define CR0_PG_MASK 0x80010000 ; CR0.PG and CR0.WP
+%define CR4_PG_MASK 0x10B0 ; CR4.PSE, CR4.PAE, CR4.PGE and CR4.LA57
+%define EFER_PG_MASK 0x800 ; EFER.NXE
;------------------------------------------------------------------------------
; UINT32
@@ -50,6 +56,34 @@ ASM_PFX(FspSwitchStack):
pushfd
cli
pushad
+
+ ;
+ ; Allocate 4x4 bytes on the stack.
+ ;
+ sub esp, 16
+ cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0
+ jz SkipPagetableSave
+
+ add esp, 16
+ ; Save EFER MSR lower 32 bits
+ push ecx
+ push eax
+ mov ecx, 0xC0000080
+ rdmsr
+ mov edx, eax
+ pop eax
+ pop ecx
+ push edx
+
+ ; Save CR registers
+ mov eax, cr4
+ push eax
+ mov eax, cr3
+ push eax
+ mov eax, cr0
+ push eax
+SkipPagetableSave:
+
sub esp, 8
sidt [esp]
@@ -61,6 +95,104 @@ ASM_PFX(FspSwitchStack):
; Restore previous contexts
lidt [esp]
add esp, 8
+
+ cmp byte [dword ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))], 0
+ jz SkipPagetableRestore
+ ; [esp] stores new cr0
+ ; [esp+4] stores new cr3
+ ; [esp+8] stores new cr4
+ ; [esp+12] stores new Efer
+ ;
+ ; When new EFER.NXE == 1, the restore flow is: EFER --> CRx
+ ; Otherwise: CRx --> EFER
+ ; When new CR0.PG == 1, the restore flow for CRx is: CR3 --> CR4 --> CR0
+ ; Otherwise, the restore flow is: CR0 --> CR3 --> CR4
+ ;
+ ; If NXE bit is changed to 1, change NXE before CR register
+ ; This is because Nx bit in page table entry in new CR3 will be invalid
+ ; if updating CR3 before EFER MSR.
+ ;
+ mov eax, [esp+12]
+ bt eax, 11
+ jnc SkipEferLabel1
+
+ ; Restore EFER MSR
+ mov ecx, 0xC0000080
+ rdmsr
+ and eax, ~EFER_PG_MASK
+ mov ebx, [esp+12]
+ and ebx, EFER_PG_MASK
+ or eax, ebx
+ wrmsr
+
+SkipEferLabel1:
+
+ ;
+ ; if new cr0 is to disable page table, change CR0 before CR3/CR4
+ ;
+ mov eax, [esp]
+ bt eax, 31
+ jc SkipCr0Label1
+
+ ; Restore CR0
+ mov edx, cr0
+ and edx, ~CR0_PG_MASK
+ mov eax, [esp]
+ and eax, CR0_PG_MASK
+ or edx, eax
+ mov cr0, edx
+
+SkipCr0Label1:
+
+ ; Restore CR3/CR4
+ mov eax, [esp+4]
+ mov cr3, eax
+
+ mov edx, cr4
+ and edx, ~CR4_PG_MASK
+ mov eax, [esp+8]
+ and eax, CR4_PG_MASK
+ or edx, eax
+ mov cr4, edx
+
+ ;
+ ; if new cr0 is to enable page table, change CR0 after CR3/CR4
+ ;
+ mov eax, [esp]
+ bt eax, 31
+ jnc SkipCr0Label2
+
+ ; Restore CR0
+ mov edx, cr0
+ and edx, ~CR0_PG_MASK
+ mov eax, [esp]
+ and eax, CR0_PG_MASK
+ or edx, eax
+ mov cr0, edx
+
+SkipCr0Label2:
+ ;
+ ; If NXE bit is changed to 0, change NXE after than CR regiser
+ ;
+ mov eax, [esp+12]
+ bt eax, 11
+ jc SkipEferLabel2
+
+ ; Restore EFER MSR
+ mov ecx, 0xC0000080
+ rdmsr
+ and eax, ~EFER_PG_MASK
+ mov ebx, [esp+12]
+ and ebx, EFER_PG_MASK
+ or eax, ebx
+ wrmsr
+
+SkipEferLabel2:
+SkipPagetableRestore:
+
+ ; pop page table related registers.
+ add esp, 16
+
popad
popfd
add esp, 4
diff --git a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm
index e3a7cf0..f40df51 100644
--- a/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm
+++ b/IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm
@@ -8,12 +8,18 @@
; Switch the stack from temporary memory to permanent memory.
;
;------------------------------------------------------------------------------
-
+ DEFAULT REL
SECTION .text
%include "PushPopRegsNasm.inc"
+; Page table related bits in CR0/CR4/EFER
+%define CR0_PG_MASK 0x80010000 ; CR0.PG and CR0.WP
+%define CR4_PG_MASK 0x10B0 ; CR4.PSE, CR4.PAE, CR4.PGE and CR4.LA57
+%define EFER_PG_MASK 0x800 ; EFER.NXE
+
extern ASM_PFX(SwapStack)
+extern ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))
;------------------------------------------------------------------------------
; UINT32
@@ -55,6 +61,37 @@ ASM_PFX(FspSwitchStack):
pushfq
cli
PUSHA_64
+
+ ;
+ ; Allocate 4x8 bytes on the stack.
+ ;
+ sub rsp, 32
+ lea rdx, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))]
+ mov dl, byte [rdx]
+ cmp dl, 0
+ jz SkipPagetableSave
+
+ add rsp, 32
+ ; Save EFER MSR
+ push rcx
+ push rax
+ mov rcx, 0xC0000080
+ rdmsr
+ shl rdx, 0x20
+ or rdx, rax
+ pop rax
+ pop rcx
+ push rdx
+
+ ; Save CR registers
+ mov rdx, cr4
+ push rdx
+ mov rdx, cr3
+ push rdx
+ mov rdx, cr0
+ push rdx
+SkipPagetableSave:
+
sub rsp, 16
sidt [rsp]
@@ -68,6 +105,76 @@ ASM_PFX(FspSwitchStack):
; Restore previous contexts
lidt [rsp]
add rsp, 16
+
+ lea rax, [ASM_PFX(FeaturePcdGet (PcdFspSaveRestorePageTableEnable))]
+ mov al, byte [rax]
+ cmp al, 0
+ jz SkipPagetableRestore
+ ; [rsp] stores new cr0
+ ; [rsp+8] stores new cr3
+ ; [rsp+16] stores new cr4
+ ; [rsp+24] stores new Efer
+ ;
+ ; When new EFER.NXE == 1, the restore flow is: EFER --> CRx
+ ; Otherwise: CRx --> EFER
+ ;
+ ; If NXE bit is changed to 1, change NXE before CR register
+ ; This is because Nx bit in page table entry in new CR3 will be invalid
+ ; if updating CR3 before EFER MSR.
+ ;
+ mov rax, [rsp + 24]
+ bt rax, 11
+ jnc SkipEferLabel1
+
+ ; Restore EFER MSR
+ mov ecx, 0xC0000080
+ rdmsr
+ and eax, ~EFER_PG_MASK
+ mov ebx, [rsp + 24]
+ and ebx, EFER_PG_MASK
+ or eax, ebx
+ wrmsr
+
+SkipEferLabel1:
+
+ mov rbx, [rsp]
+ mov rdx, cr0
+ and rdx, ~CR0_PG_MASK
+ and rbx, CR0_PG_MASK
+ or rdx, rbx
+ mov cr0, rdx
+
+ mov rbx, [rsp + 8]
+ mov cr3, rbx
+
+ mov rbx, [rsp + 16]
+ mov rdx, cr4
+ and rdx, ~CR4_PG_MASK
+ and rbx, CR4_PG_MASK
+ or rdx, rbx
+ mov cr4, rdx
+
+ ;
+ ; If NXE bit is changed to 0, change NXE after than CR regiser
+ ;
+ mov rax, [rsp + 24]
+ bt rax, 11
+ jc SkipEferLabel2
+
+ ; Restore EFER MSR
+ mov ecx, 0xC0000080
+ rdmsr
+ and eax, ~EFER_PG_MASK
+ mov ebx, [rsp + 24]
+ and ebx, EFER_PG_MASK
+ or eax, ebx
+ wrmsr
+
+SkipEferLabel2:
+SkipPagetableRestore:
+ ; pop page table related registers.
+ add rsp, 32
+
POPA_64
popfq
add rsp, 32 ; FspInfoHeader + ApiParam[2] + Reserved QWORD
diff --git a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c
index 7f1deb9..d9fbb21 100644
--- a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c
+++ b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c
@@ -3,7 +3,7 @@
register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi
notify to call FspSiliconInit API.
- Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -38,6 +38,7 @@
#include <FspStatusCode.h>
#include <FspGlobalData.h>
#include <Library/FspCommonLib.h>
+#include <Guid/MigratedFvInfo.h>
extern EFI_GUID gFspHobGuid;
@@ -278,18 +279,41 @@ TcgPpiNotify (
IN VOID *Ppi
)
{
- UINT32 FspMeasureMask;
+ UINT32 FspMeasureMask;
+ EFI_PHYSICAL_ADDRESS FsptBaseAddress;
+ EFI_PHYSICAL_ADDRESS FspmBaseAddress;
+ EDKII_MIGRATED_FV_INFO *MigratedFvInfo;
+ EFI_PEI_HOB_POINTERS Hob;
DEBUG ((DEBUG_INFO, "TcgPpiNotify FSPM\n"));
- FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig);
+ FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig);
+ FsptBaseAddress = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFsptBaseAddress);
+ FspmBaseAddress = (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFspmBaseAddress);
+ Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);
+ while (Hob.Raw != NULL) {
+ MigratedFvInfo = GET_GUID_HOB_DATA (Hob);
+ if ((MigratedFvInfo->FvOrgBase == PcdGet32 (PcdFsptBaseAddress)) && (MigratedFvInfo->FvDataBase != 0)) {
+ //
+ // Found the migrated FspT raw data
+ //
+ FsptBaseAddress = MigratedFvInfo->FvDataBase;
+ }
+
+ if ((MigratedFvInfo->FvOrgBase == PcdGet32 (PcdFspmBaseAddress)) && (MigratedFvInfo->FvDataBase != 0)) {
+ FspmBaseAddress = MigratedFvInfo->FvDataBase;
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);
+ }
if ((FspMeasureMask & FSP_MEASURE_FSPT) != 0) {
MeasureFspFirmwareBlob (
0,
"FSPT",
- PcdGet32 (PcdFsptBaseAddress),
- (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFsptBaseAddress))->FvLength
+ FsptBaseAddress,
+ (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FsptBaseAddress)->FvLength
);
}
@@ -297,8 +321,8 @@ TcgPpiNotify (
MeasureFspFirmwareBlob (
0,
"FSPM",
- PcdGet32 (PcdFspmBaseAddress),
- (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFspmBaseAddress))->FvLength
+ FspmBaseAddress,
+ (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FspmBaseAddress)->FvLength
);
}
diff --git a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
index 0307ce0..a0f384f 100644
--- a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
+++ b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
@@ -6,7 +6,7 @@
# register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi
# notify to call FspSiliconInit API.
#
-# Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -69,6 +69,7 @@
[Guids]
gFspHobGuid ## PRODUCES ## HOB
gFspApiPerformanceGuid ## SOMETIMES_CONSUMES ## GUID
+ gEdkiiMigratedFvInfoGuid ## SOMETIMES_CONSUMES ## HOB
[Ppis]
gEdkiiTcgPpiGuid ## NOTIFY
diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
index 922ccc0..6865ffa 100644
--- a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
+++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
@@ -90,23 +90,6 @@
# @Prompt Skip FSP API from FSP wrapper.
gIntelFsp2WrapperTokenSpaceGuid.PcdSkipFspApi|0x00000000|UINT32|0x40000009
- ## This PCD decides how FSP is measured
- # 1) The BootGuard ACM may already measured the FSP component, such as FSPT/FSPM.
- # We need a flag (PCD) to indicate if there is need to do such FSP measurement or NOT.
- # 2) The FSP binary includes FSP code and FSP UPD region. The UPD region is considered
- # as configuration block, and it may be updated by OEM by design.
- # This flag (PCD) is to indicate if we need isolate the UPD region from the FSP code region.
- # BIT0: Need measure FSP. (for FSP1.x) - reserved in FSP2.
- # BIT1: Need measure FSPT. (for FSP 2.x)
- # BIT2: Need measure FSPM. (for FSP 2.x)
- # BIT3: Need measure FSPS. (for FSP 2.x)
- # BIT4~30: reserved.
- # BIT31: Need isolate UPD region measurement.
- #0: measure FSP[T|M|S] as one binary in one record (PCR0).
- #1: measure FSP UPD region in one record (PCR1), the FSP code without UPD in another record (PCR0).
- #
- gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig|0x00000000|UINT32|0x4000000B
-
[PcdsFixedAtBuild, PcdsPatchableInModule,PcdsDynamic,PcdsDynamicEx]
## This PCD decides how Wrapper code utilizes FSP
# 0: DISPATCH mode (FSP Wrapper will load PeiCore from FSP without calling FSP API)
@@ -137,3 +120,20 @@
# Non-0 means PcdFspsUpdDataAddress will be ignored, otherwise PcdFspsUpdDataAddress will be used.
#
gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress64|0x00000000|UINT64|0x50000003
+
+ ## This PCD decides how FSP is measured
+ # 1) The BootGuard ACM may already measured the FSP component, such as FSPT/FSPM.
+ # We need a flag (PCD) to indicate if there is need to do such FSP measurement or NOT.
+ # 2) The FSP binary includes FSP code and FSP UPD region. The UPD region is considered
+ # as configuration block, and it may be updated by OEM by design.
+ # This flag (PCD) is to indicate if we need isolate the UPD region from the FSP code region.
+ # BIT0: Need measure FSP. (for FSP1.x) - reserved in FSP2.
+ # BIT1: Need measure FSPT. (for FSP 2.x)
+ # BIT2: Need measure FSPM. (for FSP 2.x)
+ # BIT3: Need measure FSPS. (for FSP 2.x)
+ # BIT4~30: reserved.
+ # BIT31: Need isolate UPD region measurement.
+ #0: measure FSP[T|M|S] as one binary in one record (PCR0).
+ #1: measure FSP UPD region in one record (PCR1), the FSP code without UPD in another record (PCR0).
+ #
+ gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig|0x00000000|UINT32|0x50000004
diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc
index fe62124..f904e6f 100644
--- a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc
+++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc
@@ -57,6 +57,10 @@
Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.PEIM,LibraryClasses.common.PEI_CORE]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
diff --git a/Maintainers.txt b/Maintainers.txt
index d22929b..a1c3709 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -85,7 +85,6 @@ ARM, AARCH64
F: */AArch64/
F: */Arm/
M: Leif Lindholm <quic_llindhol@quicinc.com> [leiflindholm]
-M: Ard Biesheuvel <ardb+tianocore@kernel.org> [ardbiesheuvel]
M: Sami Mujawar <sami.mujawar@arm.com> [samimujawar]
RISCV64
@@ -138,21 +137,19 @@ ArmPkg
F: ArmPkg/
W: https://github.com/tianocore/tianocore.github.io/wiki/ArmPkg
M: Leif Lindholm <quic_llindhol@quicinc.com> [leiflindholm]
-M: Ard Biesheuvel <ardb+tianocore@kernel.org> [ardbiesheuvel]
-R: Sami Mujawar <sami.mujawar@arm.com> [samimujawar]
+M: Sami Mujawar <sami.mujawar@arm.com> [samimujawar]
ArmPlatformPkg
F: ArmPlatformPkg/
W: https://github.com/tianocore/tianocore.github.io/wiki/ArmPlatformPkg
M: Leif Lindholm <quic_llindhol@quicinc.com> [leiflindholm]
-M: Ard Biesheuvel <ardb+tianocore@kernel.org> [ardbiesheuvel]
+M: Sami Mujawar <sami.mujawar@arm.com> [samimujawar]
ArmVirtPkg
F: ArmVirtPkg/
W: https://github.com/tianocore/tianocore.github.io/wiki/ArmVirtPkg
-M: Ard Biesheuvel <ardb+tianocore@kernel.org> [ardbiesheuvel]
+M: Sami Mujawar <sami.mujawar@arm.com> [samimujawar]
R: Leif Lindholm <quic_llindhol@quicinc.com> [leiflindholm]
-R: Sami Mujawar <sami.mujawar@arm.com> [samimujawar]
R: Gerd Hoffmann <kraxel@redhat.com> [kraxel]
BaseTools
@@ -175,7 +172,6 @@ F: CryptoPkg/
W: https://github.com/tianocore/tianocore.github.io/wiki/CryptoPkg
M: Jiewen Yao <jiewen.yao@intel.com> [jyao1]
M: Yi Li <yi1.li@intel.com> [liyi77]
-R: Wenxing Hou <wenxing.hou@intel.com> [Wenxing-hou]
DynamicTablesPkg
F: DynamicTablesPkg/
@@ -187,7 +183,6 @@ EmbeddedPkg
F: EmbeddedPkg/
W: https://github.com/tianocore/tianocore.github.io/wiki/EmbeddedPkg
M: Leif Lindholm <quic_llindhol@quicinc.com> [leiflindholm]
-M: Ard Biesheuvel <ardb+tianocore@kernel.org> [ardbiesheuvel]
M: Abner Chang <abner.chang@amd.com> [changab]
EmulatorPkg
@@ -225,7 +220,6 @@ M: Duggapu Chinni B <chinni.b.duggapu@intel.com> [cbduggap]
R: Star Zeng <star.zeng@intel.com> [lzeng14]
R: Ted Kuo <ted.kuo@intel.com> [tedkuo1]
R: Ashraf Ali S <ashraf.ali.s@intel.com> [AshrafAliS]
-R: Susovan Mohapatra <susovan.mohapatra@intel.com> [susovanmohapatra]
IntelFsp2WrapperPkg
F: IntelFsp2WrapperPkg/
@@ -237,7 +231,6 @@ M: Chen Gang C <gang.c.chen@intel.com> [chengangc]
R: Star Zeng <star.zeng@intel.com> [lzeng14]
R: Ted Kuo <ted.kuo@intel.com> [tedkuo1]
R: Ashraf Ali S <ashraf.ali.s@intel.com> [AshrafAliS]
-R: Susovan Mohapatra <susovan.mohapatra@intel.com> [susovanmohapatra]
MdeModulePkg
F: MdeModulePkg/
@@ -259,23 +252,8 @@ F: MdeModulePkg/Universal/DevicePathDxe/
F: MdeModulePkg/Universal/DriverHealthManagerDxe/
F: MdeModulePkg/Universal/LoadFileOnFv2/
F: MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.*
-R: Zhichao Gao <zhichao.gao@intel.com> [ZhichaoGao]
R: Ray Ni <ray.ni@intel.com> [niruiyu]
-MdeModulePkg: Console and Graphics modules
-F: MdeModulePkg/*Logo*/
-F: MdeModulePkg/Include/*Logo*.h
-F: MdeModulePkg/Include/Guid/ConnectConInEvent.h
-F: MdeModulePkg/Include/Guid/Console*.h
-F: MdeModulePkg/Include/Guid/StandardErrorDevice.h
-F: MdeModulePkg/Include/Guid/TtyTerm.h
-F: MdeModulePkg/Include/Library/BmpSupportLib.h
-F: MdeModulePkg/Include/Library/FrameBufferBltLib.h
-F: MdeModulePkg/Library/BaseBmpSupportLib/
-F: MdeModulePkg/Library/FrameBufferBltLib/
-F: MdeModulePkg/Universal/Console/
-R: Zhichao Gao <zhichao.gao@intel.com> [ZhichaoGao]
-
MdeModulePkg: Core services (PEI, DXE and Runtime) modules
F: MdeModulePkg/*Mem*/
F: MdeModulePkg/*SectionExtract*/
@@ -324,7 +302,6 @@ R: Ray Ni <ray.ni@intel.com> [niruiyu]
MdeModulePkg: Disk modules
F: MdeModulePkg/Universal/Disk/
R: Ray Ni <ray.ni@intel.com> [niruiyu]
-R: Zhichao Gao <zhichao.gao@intel.com> [ZhichaoGao]
MdeModulePkg: Firmware Update modules
F: MdeModulePkg/*Capsule*/
@@ -366,22 +343,11 @@ MdeModulePkg: Pei Core
F: MdeModulePkg/Core/Pei/
R: Liming Gao <gaoliming@byosoft.com.cn> [lgao4]
-MdeModulePkg: Reset modules
-F: MdeModulePkg/*Reset*/
-F: MdeModulePkg/Include/*Reset*.h
-R: Zhichao Gao <zhichao.gao@intel.com> [ZhichaoGao]
-
-MdeModulePkg: Serial modules
-F: MdeModulePkg/*Serial*/
-F: MdeModulePkg/Include/*SerialPort*.h
-R: Zhichao Gao <zhichao.gao@intel.com> [ZhichaoGao]
-
MdeModulePkg: SMBIOS modules
F: MdeModulePkg/Universal/Smbios*/
R: Zhiguang Liu <zhiguang.liu@intel.com> [LiuZhiguang001]
R: Dandan Bi <dandan.bi@intel.com> [dandanbi]
R: Star Zeng <star.zeng@intel.com> [lzeng14]
-R: Zhichao Gao <zhichao.gao@intel.com> [ZhichaoGao]
MdeModulePkg: UEFI Variable modules
F: MdeModulePkg/*Var*/
@@ -436,13 +402,13 @@ F: MdePkg/Include/Library/TraceHubDebugSysTLib.h
F: MdePkg/Include/Library/MipiSysTLib.h
M: Gua Guo <gua.guo@intel.com> [gguo11837463]
M: Prakashan Krishnadas Veliyathuparambil <krishnadas.veliyathuparambil.prakashan@intel.com> [kprakas2]
-R: Chan Laura <laura.chan@intel.com> [lauracha]
R: K N Karthik <karthik.k.n@intel.com> [karthikkabbigere1]
MdePkg: FDT related library instance
-F: MdePkg/Library/BaseFdtLib/FdtLib.c
+F: MdePkg/Library/BaseFdtLib/*
F: MdePkg/Include/Library/FdtLib.h
M: Benny Lin <benny.lin@intel.com> [Benny3345678]
+M: Leif Lindholm <quic_llindhol@quicinc.com> [leiflindholm]
R: Gua Guo <gua.guo@intel.com> [gguo11837463]
R: Chasel Chiu <chasel.chiu@intel.com> [ChaselChiu]
R: James Lu <james.lu@intel.com> [jameslu8]
@@ -464,8 +430,7 @@ R: Brit Chesley <brit.chesley@amd.com> [BritChesley]
MdePkg: ARM/AARCH64 standard interfaces
F: MdePkg/Include/Library/ArmLib.h
M: Leif Lindholm <quic_llindhol@quicinc.com> [leiflindholm]
-M: Ard Biesheuvel <ardb+tianocore@kernel.org> [ardbiesheuvel]
-R: Sami Mujawar <sami.mujawar@arm.com> [samimujawar]
+M: Sami Mujawar <sami.mujawar@arm.com> [samimujawar]
NetworkPkg
F: NetworkPkg/
@@ -476,7 +441,6 @@ R: Zachary Clark-williams <zachary.clark-williams@intel.com> [Zclarkwilliams]
OvmfPkg
F: OvmfPkg/
W: http://www.tianocore.org/ovmf/
-M: Ard Biesheuvel <ardb+tianocore@kernel.org> [ardbiesheuvel]
M: Jiewen Yao <jiewen.yao@intel.com> [jyao1]
R: Gerd Hoffmann <kraxel@redhat.com> [kraxel]
S: Maintained
@@ -623,7 +587,6 @@ R: Rahul Kumar <rahul1.kumar@intel.com> [rahul1-kumar]
ShellPkg
F: ShellPkg/
W: https://github.com/tianocore/tianocore.github.io/wiki/ShellPkg
-M: Zhichao Gao <zhichao.gao@intel.com> [ZhichaoGao]
SignedCapsulePkg
F: SignedCapsulePkg/
@@ -635,7 +598,6 @@ W: https://github.com/tianocore/tianocore.github.io/wiki/SourceLevelDebugPkg
StandaloneMmPkg
F: StandaloneMmPkg/
-M: Ard Biesheuvel <ardb+tianocore@kernel.org> [ardbiesheuvel]
M: Sami Mujawar <sami.mujawar@arm.com> [samimujawar]
M: Ray Ni <ray.ni@intel.com> [niruiyu]
R: Jiaxin Wu <jiaxin.wu@intel.com> [jiaxinwu]
@@ -648,11 +610,6 @@ R: Rahul Kumar <rahul1.kumar@intel.com> [rahul1-kumar]
R: Gerd Hoffmann <kraxel@redhat.com> [kraxel]
R: Jiaxin Wu <jiaxin.wu@intel.com> [jiaxinwu]
-UefiCpuPkg: Sec related modules
-F: UefiCpuPkg/SecCore/
-F: UefiCpuPkg/ResetVector/
-R: Catharine West <catharine.west@intel.com> [catharine-intl]
-
UefiCpuPkg: AMD related files
F: UefiCpuPkg/Library/MmSaveStateLib/*Amd*.*
F: UefiCpuPkg/Library/SmmCpuFeaturesLib/*Amd*.*
diff --git a/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c
index 69baf1c..68c2e35 100644
--- a/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c
+++ b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c
@@ -667,7 +667,7 @@ SmiHandlerProfileInfoEntrypoint (
//
// Dump all image
//
- Print (L"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+ Print (L"<?xml version=\"1.0\" encoding=\"utf-16\"?>\n");
Print (L"<SmiHandlerProfile>\n");
Print (L"<ImageDatabase>\n");
Print (L" <!-- SMM image loaded -->\n");
diff --git a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c
index e31c38d..4daf517 100644
--- a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c
+++ b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceIo.c
@@ -1111,6 +1111,8 @@ NonCoherentPciIoAllocateBuffer (
NON_DISCOVERABLE_DEVICE_UNCACHED_ALLOCATION *Alloc;
VOID *AllocAddress;
+ MemType = EFI_MEMORY_XP;
+
if (HostAddress == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -1152,9 +1154,9 @@ NonCoherentPciIoAllocateBuffer (
// Use write combining if it was requested, or if it is the only
// type supported by the region.
//
- MemType = EFI_MEMORY_WC;
+ MemType |= EFI_MEMORY_WC;
} else {
- MemType = EFI_MEMORY_UC;
+ MemType |= EFI_MEMORY_UC;
}
Alloc = AllocatePool (sizeof *Alloc);
@@ -1172,6 +1174,34 @@ NonCoherentPciIoAllocateBuffer (
//
InsertHeadList (&Dev->UncachedAllocationList, &Alloc->List);
+ //
+ // Ensure that EFI_MEMORY_XP is in the capability set
+ //
+ if ((GcdDescriptor.Capabilities & EFI_MEMORY_XP) != EFI_MEMORY_XP) {
+ Status = gDS->SetMemorySpaceCapabilities (
+ (PHYSICAL_ADDRESS)(UINTN)AllocAddress,
+ EFI_PAGES_TO_SIZE (Pages),
+ GcdDescriptor.Capabilities | EFI_MEMORY_XP
+ );
+
+ // if we were to fail setting the capability, this would indicate an internal failure of the GCD code. We should
+ // assert here to let a platform know something went crazy, but for a release build we can let the allocation occur
+ // without the EFI_MEMORY_XP bit set, as that was the existing behavior
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a failed to set EFI_MEMORY_XP capability on 0x%llx for length 0x%llx. Attempting to allocate without XP set.\n",
+ __func__,
+ AllocAddress,
+ EFI_PAGES_TO_SIZE (Pages)
+ ));
+
+ ASSERT_EFI_ERROR (Status);
+
+ MemType &= ~EFI_MEMORY_XP;
+ }
+ }
+
Status = gDS->SetMemorySpaceAttributes (
(EFI_PHYSICAL_ADDRESS)(UINTN)AllocAddress,
EFI_PAGES_TO_SIZE (Pages),
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
index dea14f1..c8d8be3 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
@@ -3,6 +3,7 @@
NVM Express specification.
Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -182,6 +183,26 @@ EnumerateNvmeDevNamespace (
InitializeListHead (&Device->AsyncQueue);
//
+ // Create Media Sanitize Protocol instance
+ //
+ Device->MediaSanitize.Revision = MEDIA_SANITIZE_PROTOCOL_REVISION;
+ Device->MediaSanitize.Media = &Device->Media;
+ Device->MediaSanitize.MediaClear = NvmExpressMediaClear;
+ Device->MediaSanitize.MediaPurge = NvmExpressMediaPurge;
+ Device->MediaSanitize.MediaFormat = NvmExpressMediaFormat;
+
+ ASSERT (
+ sizeof (Device->MediaSanitize.SanitizeCapabilities) ==
+ sizeof (Device->Controller->ControllerData->Sanicap)
+ );
+
+ CopyMem (
+ &(Device->MediaSanitize.SanitizeCapabilities),
+ &(Device->Controller->ControllerData->Sanicap),
+ sizeof (Device->MediaSanitize.SanitizeCapabilities)
+ );
+
+ //
// Create StorageSecurityProtocol Instance
//
Device->StorageSecurity.ReceiveData = NvmeStorageSecurityReceiveData;
@@ -241,6 +262,8 @@ EnumerateNvmeDevNamespace (
&Device->BlockIo2,
&gEfiDiskInfoProtocolGuid,
&Device->DiskInfo,
+ &gMediaSanitizeProtocolGuid,
+ &Device->MediaSanitize,
NULL
);
@@ -269,6 +292,8 @@ EnumerateNvmeDevNamespace (
&Device->BlockIo2,
&gEfiDiskInfoProtocolGuid,
&Device->DiskInfo,
+ &gMediaSanitizeProtocolGuid,
+ &Device->MediaSanitize,
NULL
);
goto Exit;
@@ -288,9 +313,9 @@ EnumerateNvmeDevNamespace (
// Dump NvmExpress Identify Namespace Data
//
DEBUG ((DEBUG_INFO, " == NVME IDENTIFY NAMESPACE [%d] DATA ==\n", NamespaceId));
- DEBUG ((DEBUG_INFO, " NSZE : 0x%x\n", NamespaceData->Nsze));
- DEBUG ((DEBUG_INFO, " NCAP : 0x%x\n", NamespaceData->Ncap));
- DEBUG ((DEBUG_INFO, " NUSE : 0x%x\n", NamespaceData->Nuse));
+ DEBUG ((DEBUG_INFO, " NSZE : 0x%lx\n", NamespaceData->Nsze));
+ DEBUG ((DEBUG_INFO, " NCAP : 0x%lx\n", NamespaceData->Ncap));
+ DEBUG ((DEBUG_INFO, " NUSE : 0x%lx\n", NamespaceData->Nuse));
DEBUG ((DEBUG_INFO, " LBAF0.LBADS : 0x%x\n", (NamespaceData->LbaFormat[0].Lbads)));
//
@@ -300,7 +325,7 @@ EnumerateNvmeDevNamespace (
Sn[20] = 0;
CopyMem (Mn, Private->ControllerData->Mn, sizeof (Private->ControllerData->Mn));
Mn[40] = 0;
- UnicodeSPrintAsciiFormat (Device->ModelName, sizeof (Device->ModelName), "%a-%a-%x", Sn, Mn, NamespaceData->Eui64);
+ UnicodeSPrintAsciiFormat (Device->ModelName, sizeof (Device->ModelName), "%a-%a-%lx", Sn, Mn, NamespaceData->Eui64);
AddUnicodeString2 (
"eng",
@@ -468,6 +493,8 @@ UnregisterNvmeNamespace (
&Device->BlockIo2,
&gEfiDiskInfoProtocolGuid,
&Device->DiskInfo,
+ &gMediaSanitizeProtocolGuid,
+ &Device->MediaSanitize,
NULL
);
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h
index 4c26b2e..11207af 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h
@@ -4,6 +4,7 @@
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -29,6 +30,7 @@
#include <Protocol/DriverSupportedEfiVersion.h>
#include <Protocol/StorageSecurityCommand.h>
#include <Protocol/ResetNotification.h>
+#include <Protocol/MediaSanitize.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
@@ -41,12 +43,15 @@
#include <Library/UefiDriverEntryPoint.h>
#include <Library/ReportStatusCodeLib.h>
+#include <Guid/NVMeEventGroup.h>
+
typedef struct _NVME_CONTROLLER_PRIVATE_DATA NVME_CONTROLLER_PRIVATE_DATA;
typedef struct _NVME_DEVICE_PRIVATE_DATA NVME_DEVICE_PRIVATE_DATA;
#include "NvmExpressBlockIo.h"
#include "NvmExpressDiskInfo.h"
#include "NvmExpressHci.h"
+#include "NvmExpressMediaSanitize.h"
extern EFI_DRIVER_BINDING_PROTOCOL gNvmExpressDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gNvmExpressComponentName;
@@ -75,6 +80,30 @@ extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gNvmExpressDriverSupportedEfiV
#define NVME_MAX_QUEUES 3 // Number of queues supported by the driver
+//
+// FormatNVM Admin Command LBA Format (LBAF) Mask
+//
+#define NVME_LBA_FORMATNVM_LBAF_MASK 0xF
+
+//
+// NVMe Completion Queue Entry Bits, Fields, Masks
+//
+#define NVME_CQE_STATUS_FIELD_MASK 0xFFFF0000
+#define NVME_CQE_STATUS_FIELD_OFFSET 16
+#define NVME_CQE_STATUS_FIELD_SCT_MASK 0x0E00
+#define NVME_CQE_STATUS_FIELD_SCT_OFFSET 0x9
+#define NVME_CQE_STATUS_FIELD_SC_MASK 0x1FE
+#define NVME_CQE_STATUS_FIELD_SC_OFFSET 0x01
+#define NVME_CQE_SCT_GENERIC_CMD_STATUS 0x0
+#define NVME_CQE_SCT_CMD_SPECIFIC_STATUS 0x1
+#define NVME_CQE_SCT_MEDIA_DATA_INTEGRITY_ERRORS_STATUS 0x2
+#define NVME_CQE_SCT_PATH_RELATED_STATUS 0x3
+#define NVME_CQE_SC_SUCCESSFUL_COMPLETION 0x00
+#define NVME_CQE_SC_INVALID_CMD_OPCODE 0x01
+#define NVME_CQE_SC_INVALID_FIELD_IN_CMD 0x02
+
+#define NVME_ALL_NAMESPACES 0xFFFFFFFF
+
#define NVME_CONTROLLER_ID 0
//
@@ -200,6 +229,8 @@ struct _NVME_DEVICE_PRIVATE_DATA {
EFI_DISK_INFO_PROTOCOL DiskInfo;
EFI_STORAGE_SECURITY_COMMAND_PROTOCOL StorageSecurity;
+ MEDIA_SANITIZE_PROTOCOL MediaSanitize;
+
LIST_ENTRY AsyncQueue;
EFI_LBA NumBlocks;
@@ -241,6 +272,13 @@ struct _NVME_DEVICE_PRIVATE_DATA {
NVME_DEVICE_PRIVATE_DATA_SIGNATURE \
)
+#define NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE(a) \
+ CR (a, \
+ NVME_DEVICE_PRIVATE_DATA, \
+ MediaSanitize, \
+ NVME_DEVICE_PRIVATE_DATA_SIGNATURE \
+ )
+
//
// Nvme block I/O 2 request.
//
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
index dc1990c..5fd0e46 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
@@ -5,7 +5,7 @@
# NVM Express specification.
#
# Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved.<BR>
-#
+# Copyright (c) Microsoft Corporation.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -40,9 +40,16 @@
NvmExpressHci.c
NvmExpressHci.h
NvmExpressPassthru.c
+ NvmExpressMediaSanitize.c
+ NvmExpressMediaSanitize.h
+
+[Guids]
+ gNVMeEnableStartEventGroupGuid
+ gNVMeEnableCompleteEventGroupGuid
[Packages]
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseMemoryLib
@@ -67,6 +74,7 @@
gEfiDiskInfoProtocolGuid ## BY_START
gEfiStorageSecurityCommandProtocolGuid ## BY_START
gEfiDriverSupportedEfiVersionProtocolGuid ## PRODUCES
+ gMediaSanitizeProtocolGuid ## PRODUCES
gEfiResetNotificationProtocolGuid ## CONSUMES
# [Event]
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c
index b90c487..e1b0ee6 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c
@@ -8,6 +8,7 @@
**/
#include "NvmExpress.h"
+#include <Guid/NVMeEventGroup.h>
#define NVME_SHUTDOWN_PROCESS_TIMEOUT 45
@@ -399,6 +400,8 @@ NvmeEnableController (
UINT32 Index;
UINT8 Timeout;
+ EfiEventGroupSignal (&gNVMeEnableStartEventGroupGuid);
+
//
// Enable the controller.
// CC.AMS, CC.MPS and CC.CSS are all set to 0.
@@ -410,7 +413,7 @@ NvmeEnableController (
Status = WriteNvmeControllerConfiguration (Private, &Cc);
if (EFI_ERROR (Status)) {
- return Status;
+ goto Cleanup;
}
//
@@ -432,7 +435,7 @@ NvmeEnableController (
Status = ReadNvmeControllerStatus (Private, &Csts);
if (EFI_ERROR (Status)) {
- return Status;
+ goto Cleanup;
}
if (Csts.Rdy) {
@@ -449,6 +452,9 @@ NvmeEnableController (
}
DEBUG ((DEBUG_INFO, "NVMe controller is enabled with status [%r].\n", Status));
+
+Cleanup:
+ EfiEventGroupSignal (&gNVMeEnableCompleteEventGroupGuid);
return Status;
}
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.c
new file mode 100644
index 0000000..8632924
--- /dev/null
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.c
@@ -0,0 +1,582 @@
+/** @file -- NvmExpressMediaSanitize.c
+ This driver will implement sanitize operations on all NVMe mass storage devices
+ based on NIST purge and clear operations. These operations will then be mapped to
+ one of two NVMe admin commands:
+
+ -Format NVM
+ -Sanitize
+
+ Implementation based off NVMe spec revision 1.4c.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "NvmExpress.h"
+
+/**
+ Send NVM Express FormatNVM Admin Command
+
+ The Format NVM command is used to low level format the NVM media. This command is used by
+ the host to change the LBA data size and/or metadata size.
+
+ A low level format may destroy all data and metadata associated with all namespaces or only
+ the specific namespace associated with the command (refer to the Format NVM Attributes field
+ in the Identify Controller data structure).
+
+ After the Format NVM command successfully completes, the controller shall not return any user
+ data that was previously contained in an affected namespace.
+
+ @param[in] This Indicates a pointer to the calling context (Block IO Protocol)
+ @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be
+ allocated and built. Caller must set the NamespaceId to zero if the
+ device path node will contain a valid UUID.
+ @param[in] Ses Secure Erase Setting (SES) value
+ - 000b: No secure erase operation requested
+ - 001b: User Data Erase
+ - 010b: Cryptographic Erase
+ - 011b to 111b: Reserved
+ @param[in] Flbas New LBA size (in terms of LBA Format size Index (bits 3:0) in NamespaceData).
+ If this param is 0 (NULL), then use existing LBA size.
+
+ @retval EFI_SUCCESS The device formatted correctly.
+ @retval EFI_WRITE_PROTECTED The device can not be formatted due to write protection.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the format.
+ @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_INVALID_PARAMETER The format request contains parameters that are not valid.
+
+ **/
+EFI_STATUS
+NvmExpressFormatNvm (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 NamespaceId,
+ IN UINT32 Ses,
+ IN UINT32 Flbas
+ )
+{
+ NVME_DEVICE_PRIVATE_DATA *Device;
+ EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;
+ EFI_NVM_EXPRESS_COMMAND Command;
+ EFI_NVM_EXPRESS_COMPLETION Completion;
+ NVME_ADMIN_FORMAT_NVM FormatNvmCdw10;
+ NVME_ADMIN_NAMESPACE_DATA *NewNamespaceData;
+ UINT32 Lbads;
+ UINT32 NewFlbas;
+ UINT32 LbaFmtIdx;
+ EFI_STATUS Status;
+ UINT32 LbaFormat;
+ UINT16 StatusField;
+ UINT16 Sct;
+ UINT16 Sc;
+
+ Status = EFI_NOT_STARTED;
+ LbaFormat = 0;
+ Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This);
+
+ ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
+ ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND));
+ ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION));
+ ZeroMem (&FormatNvmCdw10, sizeof (NVME_ADMIN_FORMAT_NVM));
+
+ NewNamespaceData = NULL;
+ Lbads = 0;
+ NewFlbas = 0;
+ LbaFmtIdx = 0;
+ StatusField = 0;
+ Sct = 0;
+ Sc = 0;
+
+ CommandPacket.NvmeCmd = &Command;
+ CommandPacket.NvmeCompletion = &Completion;
+ CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
+ CommandPacket.QueueType = NVME_ADMIN_QUEUE;
+ Command.Cdw0.Opcode = NVME_ADMIN_FORMAT_NVM_CMD;
+ Command.Nsid = NamespaceId;
+
+ //
+ // SES (Secure Erase Settings)
+ //
+ FormatNvmCdw10.Ses = Ses;
+
+ //
+ // Change LBA size/format if LbaFormat param != NULL, otherwise keep same LBA format.
+ // Current supported LBA format size in Identify Namespace LBA Format Table, indexed by
+ // FLBAS (bits 3:0).
+ //
+ LbaFormat = (Flbas == 0 ? Device->NamespaceData.Flbas : Flbas);
+ FormatNvmCdw10.Lbaf = LbaFormat & NVME_LBA_FORMATNVM_LBAF_MASK;
+ CopyMem (&CommandPacket.NvmeCmd->Cdw10, &FormatNvmCdw10, sizeof (NVME_ADMIN_FORMAT_NVM));
+
+ //
+ // Send Format NVM command via passthru and wait for completion
+ //
+ // If LBA size changed successfully, then update private data structures and Block IO
+ // and Media protocols to reflect new LBA size.
+ //
+ Status = Device->Controller->Passthru.PassThru (
+ &(Device->Controller->Passthru),
+ NamespaceId,
+ &CommandPacket,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ StatusField = (UINT16)((CommandPacket.NvmeCompletion->DW3 & NVME_CQE_STATUS_FIELD_MASK) >>
+ NVME_CQE_STATUS_FIELD_OFFSET);
+
+ Sc = (StatusField & NVME_CQE_STATUS_FIELD_SC_MASK) >> NVME_CQE_STATUS_FIELD_SC_OFFSET;
+ Sct = (StatusField & NVME_CQE_STATUS_FIELD_SCT_MASK) >> NVME_CQE_STATUS_FIELD_SCT_OFFSET;
+
+ DEBUG ((DEBUG_ERROR, "%a: NVMe FormatNVM admin command failed SCT = 0x%x, SC = 0x%x\n", __func__, Sct, Sc));
+ } else {
+ //
+ // Update Block IO and Media Protocols only if Flbas parameter was not NULL.
+ // Call Identify Namespace again and update all protocols fields and local
+ // cached copies of fields related to block size.
+ //
+ if (Flbas != 0) {
+ NewNamespaceData = AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA));
+ if (NewNamespaceData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ Status = NvmeIdentifyNamespace (
+ Device->Controller,
+ NamespaceId,
+ (VOID *)NewNamespaceData
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Update all fields related to LBA size, allocation, and alignment
+ //
+ NewFlbas = NewNamespaceData->Flbas;
+ LbaFmtIdx = NewFlbas & NVME_LBA_FORMATNVM_LBAF_MASK;
+ Lbads = NewNamespaceData->LbaFormat[LbaFmtIdx].Lbads;
+ Device->Media.BlockSize = (UINT32)1 << Lbads;
+ Device->Media.LastBlock = NewNamespaceData->Nsze - 1;
+
+ CopyMem (&Device->NamespaceData, NewNamespaceData, sizeof (NVME_ADMIN_NAMESPACE_DATA));
+ }
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Send NVM Express Sanitize Admin Command
+
+ The Sanitize command is used to start a sanitize operation or to recover from a previously
+ failed sanitize operation. The sanitize operation types that may be supported are Block
+ Erase, Crypto Erase, and Overwrite.
+
+ All sanitize operations are processed in the background (i.e., completion of the Sanitize
+ command does not indicate completion of the sanitize operation).
+
+ @param[in] This Indicates a pointer to the calling context (Block IO Protocol)
+ @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be
+ allocated and built. Caller must set the NamespaceId to zero if the
+ device path node will contain a valid UUID.
+ @param[in] SanitizeAction Sanitize action
+ @param[in] NoDeallocAfterSanitize No deallocate after sanitize option
+ @param[in] OverwritePattern Pattern to overwrite old user data
+
+ @retval EFI_SUCCESS The media was sanitized successfully on the device.
+ @retval EFI_WRITE_PROTECTED The device can not be sanitized due to write protection.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the sanitize.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device.
+ @retval EFI_INVALID_PARAMETER The sanitize request contains parameters that are not valid.
+
+ **/
+EFI_STATUS
+NvmExpressSanitize (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 NamespaceId,
+ IN UINT32 SanitizeAction,
+ IN UINT32 NoDeallocAfterSanitize,
+ IN UINT32 OverwritePattern
+ )
+{
+ NVME_DEVICE_PRIVATE_DATA *Device;
+ EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;
+ EFI_NVM_EXPRESS_COMMAND Command;
+ EFI_NVM_EXPRESS_COMPLETION Completion;
+ NVME_ADMIN_SANITIZE SanitizeCdw10Cdw11;
+ EFI_STATUS Status;
+ UINT16 StatusField;
+ UINT16 Sct;
+ UINT16 Sc;
+ UINT32 FnvmSes;
+
+ Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This);
+
+ ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
+ ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND));
+ ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION));
+ ZeroMem (&SanitizeCdw10Cdw11, sizeof (NVME_ADMIN_SANITIZE));
+
+ StatusField = 0;
+ Sct = 0;
+ Sc = 0;
+ FnvmSes = 0;
+
+ CommandPacket.NvmeCmd = &Command;
+ CommandPacket.NvmeCompletion = &Completion;
+ CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
+ CommandPacket.QueueType = NVME_ADMIN_QUEUE;
+ Command.Cdw0.Opcode = NVME_ADMIN_SANITIZE_CMD;
+ Command.Nsid = NamespaceId;
+
+ SanitizeCdw10Cdw11.Nodas = NoDeallocAfterSanitize;
+ SanitizeCdw10Cdw11.Sanact = SanitizeAction;
+ SanitizeCdw10Cdw11.Ovrpat = OverwritePattern;
+ CopyMem (&CommandPacket.NvmeCmd->Cdw10, &SanitizeCdw10Cdw11, sizeof (NVME_ADMIN_SANITIZE));
+
+ //
+ // Send Format NVM command via passthru and wait for completion
+ //
+ Status = Device->Controller->Passthru.PassThru (
+ &(Device->Controller->Passthru),
+ NamespaceId,
+ &CommandPacket,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ StatusField = (UINT16)((CommandPacket.NvmeCompletion->DW3 & NVME_CQE_STATUS_FIELD_MASK) >>
+ NVME_CQE_STATUS_FIELD_OFFSET);
+
+ Sc = (StatusField & NVME_CQE_STATUS_FIELD_SC_MASK) >> NVME_CQE_STATUS_FIELD_SC_OFFSET;
+ Sct = (StatusField & NVME_CQE_STATUS_FIELD_SCT_MASK) >> NVME_CQE_STATUS_FIELD_SCT_OFFSET;
+
+ DEBUG ((DEBUG_ERROR, "%a: NVMe Sanitize admin command failed SCT = 0x%x, SC = 0x%x\n", __func__, Sct, Sc));
+
+ //
+ // Check for an error status code of "Invalid Command Opcode" in case
+ // the NVM Express controller does not support Sanitize. If the NVM
+ // Exress Controller does not support Sanitize, then send a Format NVM
+ // admin command instead to perform the Purge operation.
+ //
+ if ((Sct == NVME_CQE_SCT_GENERIC_CMD_STATUS) &&
+ (Sc == NVME_CQE_SC_INVALID_CMD_OPCODE))
+ {
+ switch (SanitizeCdw10Cdw11.Sanact) {
+ case SANITIZE_ACTION_BLOCK_ERASE:
+ FnvmSes = SES_USER_DATA_ERASE; // User Data Erase (LBAs indeterminate after)
+ break;
+ case SANITIZE_ACTION_CRYPTO_ERASE:
+ FnvmSes = SES_CRYPTO_ERASE; // Crypto Erase
+ break;
+ case SANITIZE_ACTION_OVERWRITE:
+ case SANITIZE_ACTION_EXIT_FAILURE_MODE:
+ default:
+ //
+ // Cannot perform an equivalent FormatNVM action/operation
+ //
+ FnvmSes = SES_NO_SECURE_ERASE;
+ break;
+ }
+
+ if ((FnvmSes == SES_USER_DATA_ERASE) || (FnvmSes == SES_CRYPTO_ERASE)) {
+ Status = NvmExpressFormatNvm (
+ This,
+ NVME_ALL_NAMESPACES,
+ FnvmSes,
+ 0 // Pass in NULL so existing LBA size is used in Format NVM
+ );
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Clear Media utilizes transport native WRITE commands to write a fixed pattern
+ of non-sensitive data to the media.
+
+ NOTE: The caller shall send buffer of one sector/LBA size with overwrite data.
+ NOTE: This operation is a blocking call.
+ NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK.
+
+ Functions are defined to erase and purge data at a block level from mass
+ storage devices as well as to manage such devices in the EFI boot services
+ environment.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId The media ID that the write request is for.
+ @param[in] PassCount The number of passes to write over media.
+ @param[in] SectorOwBuffer A pointer to the overwrite buffer.
+
+ @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_INVALID_PARAMETER The write request contains LBAs that are not valid,
+ or the buffer is not on proper alignment.
+
+**/
+EFI_STATUS
+EFIAPI
+NvmExpressMediaClear (
+ IN MEDIA_SANITIZE_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT32 PassCount,
+ IN VOID *SectorOwBuffer
+ )
+{
+ NVME_DEVICE_PRIVATE_DATA *Device;
+ EFI_BLOCK_IO_MEDIA *Media;
+ EFI_LBA SectorOffset;
+ UINT32 TotalPassCount;
+ EFI_STATUS Status;
+
+ //
+ // Check parameters.
+ //
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Device = NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE (This);
+ Media = &Device->Media;
+ SectorOffset = 0;
+
+ if ((MediaId != Media->MediaId) || (!Media->MediaPresent)) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ //
+ // If an invalid buffer or buffer size is sent, the Media Clear operation
+ // cannot be performed as it requires a native WRITE command. The overwrite
+ // buffer must have granularity of a namespace block size.
+ //
+ if (SectorOwBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Per NIST 800-88r1, one or more pass of writes may be alteratively used.
+ //
+ for (TotalPassCount = 0; TotalPassCount < PassCount; TotalPassCount++) {
+ for (SectorOffset = 0; SectorOffset < Media->LastBlock; SectorOffset++ ) {
+ Status = Device->BlockIo.WriteBlocks (
+ &Device->BlockIo,
+ MediaId,
+ SectorOffset, // Sector/LBA offset (increment each pass)
+ 1, // Write one sector per write
+ SectorOwBuffer // overwrite buffer
+ );
+ }
+
+ //
+ // Reset SectorOffset back to zero if another pass on namespace is needed
+ //
+ SectorOffset = 0;
+ }
+
+ return Status;
+}
+
+/**
+ Purge Media utilizes transport native Sanitize operations. Sanitize specific
+ purge actions include: overwrite, block erase, or crypto erase.
+
+ Functions are defined to erase and purge data at a block level from mass
+ storage devices as well as to manage such devices in the EFI boot services
+ environment. Sanitization refers to a process that renders access to target
+ data on the media infeasible for a given level of effort.
+
+ NOTE: This operation is a blocking call.
+ NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId The media ID that the write request is for.
+ @param[in] PurgeAction The purage action (overwrite, crypto erase, block erase).
+ @param[in] OverwritePattern 32-bit pattern to overwrite on media (for overwrite).
+
+ @retval EFI_SUCCESS The media was purged successfully on the device.
+ @retval EFI_WRITE_PROTECTED The device can not be purged due to write protection.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the purge.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device.
+ @retval EFI_INVALID_PARAMETER The purge request contains parameters that are not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+NvmExpressMediaPurge (
+ IN MEDIA_SANITIZE_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT32 PurgeAction,
+ IN UINT32 OverwritePattern
+ )
+{
+ NVME_DEVICE_PRIVATE_DATA *Device;
+ EFI_BLOCK_IO_MEDIA *Media;
+ NVME_SANICAP SaniCap;
+ UINT32 SanitizeAction;
+ UINT32 NoDeallocate;
+ UINT32 NamespaceId;
+ EFI_STATUS Status;
+
+ //
+ // Check parameters.
+ //
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Device = NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE (This);
+ NamespaceId = Device->NamespaceId;
+ Media = &Device->Media;
+ SaniCap = Device->Controller->ControllerData->Sanicap;
+ NoDeallocate = 0;
+
+ if ((MediaId != Media->MediaId) || (!Media->MediaPresent)) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ //
+ // Purge action will directly map to sanitize action. If no valid purge
+ // action is selected, then default to no action and let the NVMe SSD handle
+ // the no-op sanitize action (as there may be other contingencies).
+ //
+ if (((PurgeAction & PURGE_ACTION_OVERWRITE) == PURGE_ACTION_OVERWRITE) && (SaniCap.Ows)) {
+ SanitizeAction = SANITIZE_ACTION_OVERWRITE;
+ } else if (((PurgeAction & PURGE_ACTION_BLOCK_ERASE) == PURGE_ACTION_BLOCK_ERASE) && (SaniCap.Bes)) {
+ SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE;
+ } else if (((PurgeAction & PURGE_ACTION_CRYPTO_ERASE) == PURGE_ACTION_CRYPTO_ERASE) && (SaniCap.Ces)) {
+ SanitizeAction = SANITIZE_ACTION_CRYPTO_ERASE;
+ } else {
+ SanitizeAction = SANITIZE_ACTION_NO_ACTION;
+ }
+
+ if ((PurgeAction & PURGE_ACTION_NO_DEALLOCATE) == PURGE_ACTION_NO_DEALLOCATE) {
+ NoDeallocate = NVME_NO_DEALLOCATE_AFTER_SANITZE;
+ }
+
+ //
+ // Call NVM Express Admin command Sanitize (blocking call).
+ //
+ Status = NvmExpressSanitize (
+ &Device->BlockIo,
+ NamespaceId,
+ SanitizeAction,
+ NoDeallocate,
+ OverwritePattern
+ );
+
+ return Status;
+}
+
+/**
+ Format Media utilizes native format operations to modify sector/LBA size.
+ Secure erase actions are used to define how latent user data is erased.
+
+ NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId The media ID that the clear request is for.
+ @param[in] LbaSize Size of LBA (in terms of power of two: 2^n).
+ @param[in] SecureEraseAction Secure erase action, if any, to apply to format.
+ - 000b: No secure erase operation requested
+ - 001b: User Data Erase
+ - 010b: Cryptographic Erase
+ - 011b to 111b: Reserved
+
+ @retval EFI_SUCCESS The media format request comopleted successfully on the device.
+ @retval EFI_WRITE_PROTECTED The device can't be formatted due to write protection.
+ @retval EFI_DEVICE_ERROR The device reported an error while attempting to perform the format operation.
+ @retval EFI_INVALID_PARAMETER The format request contains parameters that are not valid.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
+
+ **/
+EFI_STATUS
+EFIAPI
+NvmExpressMediaFormat (
+ IN MEDIA_SANITIZE_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT32 LbaSize,
+ IN UINT32 SecureEraseAction
+ )
+{
+ NVME_DEVICE_PRIVATE_DATA *Device;
+ EFI_BLOCK_IO_MEDIA *Media;
+ UINT32 NamespaceId;
+ UINT32 SecureEraseSettings;
+ UINT32 FlbaIndex;
+ BOOLEAN LbaSizeIsSupported;
+ EFI_STATUS Status;
+
+ //
+ // Check parameters.
+ //
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Device = NVME_DEVICE_PRIVATE_DATA_FROM_MEDIA_SANITIZE (This);
+ NamespaceId = Device->NamespaceId;
+ Media = &Device->Media;
+ SecureEraseSettings = FORMAT_SES_NO_SECURE_ERASE_REQUESTED;
+ FlbaIndex = 0;
+
+ if ((MediaId != Media->MediaId) || (!Media->MediaPresent)) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ //
+ // Convert secure erase action to NVMe secure erase setting
+ //
+ switch (SecureEraseAction) {
+ case FORMAT_SES_USER_DATA_ERASE:
+ SecureEraseSettings = SES_USER_DATA_ERASE;
+ break;
+ case FORMAT_SES_CRYPTOGRAPHIC_ERASE:
+ SecureEraseSettings = SES_CRYPTO_ERASE;
+ break;
+ case FORMAT_SES_NO_SECURE_ERASE_REQUESTED:
+ default:
+ //
+ // Cannot perform an equivalent FormatNVM action/operation
+ //
+ SecureEraseSettings = SES_NO_SECURE_ERASE;
+ break;
+ }
+
+ //
+ // The requested LBA size must be supported by the NVMe SSD as defined in Identify
+ // Namespace structure.
+ //
+ // Current supported LBA format sizes is in Identify Namespace LBA Format Table,
+ // indexed by FLBAS (bits 3:0). Loop through all supported LBADF sizes and check
+ // to see if requested LBA size is supported. If yes, send FormatNVM command.
+ //
+ LbaSizeIsSupported = FALSE;
+ for (FlbaIndex = 0; FlbaIndex < Device->NamespaceData.Nlbaf; FlbaIndex++) {
+ if (Device->NamespaceData.LbaFormat[FlbaIndex].Lbads == LbaSize) {
+ LbaSizeIsSupported = TRUE;
+ break;
+ }
+ }
+
+ if (LbaSizeIsSupported) {
+ Status = NvmExpressFormatNvm (
+ &Device->BlockIo,
+ NamespaceId,
+ SecureEraseSettings,
+ FlbaIndex
+ );
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ return Status;
+}
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.h b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.h
new file mode 100644
index 0000000..197b923
--- /dev/null
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressMediaSanitize.h
@@ -0,0 +1,191 @@
+/** @file
+ Header file for MEDIA_SANITIZE_PROTOCOL interface.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef NVME_MEDIA_SANITIZE_H_
+#define NVME_MEDIA_SANITIZE_H_
+
+#define NVME_NO_DEALLOCATE_AFTER_SANITZE 0x1
+
+/**
+ Send NVM Express FormatNVM Admin Command
+
+ The Format NVM command is used to low level format the NVM media. This command is used by
+ the host to change the LBA data size and/or metadata size.
+
+ A low level format may destroy all data and metadata associated with all namespaces or only
+ the specific namespace associated with the command (refer to the Format NVM Attributes field
+ in the Identify Controller data structure).
+
+ After the Format NVM command successfully completes, the controller shall not return any user
+ data that was previously contained in an affected namespace.
+
+ @param[in] This Indicates a pointer to the calling context (Block IO Protocol)
+ @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be
+ allocated and built. Caller must set the NamespaceId to zero if the
+ device path node will contain a valid UUID.
+ @param[in] Ses Secure Erase Setting (SES) value
+ - 000b: No secure erase operation requested
+ - 001b: User Data Erase
+ - 010b: Cryptographic Erase
+ - 011b to 111b: Reserved
+ @param[in] Flbas New LBA size (in terms of LBA Format size Index (bits 3:0) in NamespaceData).
+ If this param is 0 (NULL), then use existing LBA size.
+
+ @retval EFI_SUCCESS The device formatted correctly.
+ @retval EFI_WRITE_PROTECTED The device can not be formatted due to write protection.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the format.
+ @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_INVALID_PARAMETER The format request contains parameters that are not valid.
+
+**/
+EFI_STATUS
+NvmExpressFormatNvm (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 NamespaceId,
+ IN UINT32 Ses,
+ IN UINT32 Flbas
+ );
+
+/**
+ Send NVM Express Sanitize Admin Command
+
+ The Sanitize command is used to start a sanitize operation or to recover from a previously
+ failed sanitize operation. The sanitize operation types that may be supported are Block
+ Erase, Crypto Erase, and Overwrite.
+
+ All sanitize operations are processed in the background (i.e., completion of the Sanitize
+ command does not indicate completion of the sanitize operation).
+
+ @param[in] This Indicates a pointer to the calling context (Block IO Protocol)
+ @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be
+ allocated and built. Caller must set the NamespaceId to zero if the
+ device path node will contain a valid UUID.
+ @param[in] SanitizeAction Sanitize action
+ @param[in] NoDeallocAfterSanitize No deallocate after sanitize option
+ @param[in] OverwritePattern Pattern to overwrite old user data
+
+ @retval EFI_SUCCESS The media was sanitized successfully on the device.
+ @retval EFI_WRITE_PROTECTED The device can not be sanitized due to write protection.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the sanitize.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device.
+ @retval EFI_INVALID_PARAMETER The sanitize request contains parameters that are not valid.
+
+**/
+EFI_STATUS
+NvmExpressSanitize (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 NamespaceId,
+ IN UINT32 SanitizeAction,
+ IN UINT32 NoDeallocAfterSanitize,
+ IN UINT32 OverwritePattern
+ );
+
+/**
+ Clear Media utilizes transport native WRITE commands to write a fixed pattern
+ of non-sensitive data to the media.
+
+ NOTE: The caller shall send buffer of one sector/LBA size with overwrite data.
+ NOTE: This operation is a blocking call.
+ NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK.
+
+ Functions are defined to erase and purge data at a block level from mass
+ storage devices as well as to manage such devices in the EFI boot services
+ environment.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId The media ID that the write request is for.
+ @param[in] PassCount The number of passes to write over media.
+ @param[in] SectorOwBuffer A pointer to the overwrite buffer.
+
+ @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_INVALID_PARAMETER The write request contains LBAs that are not valid,
+ or the buffer is not on proper alignment.
+
+**/
+EFI_STATUS
+EFIAPI
+NvmExpressMediaClear (
+ IN MEDIA_SANITIZE_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT32 PassCount,
+ IN VOID *SectorOwBuffer
+ );
+
+/**
+ Purge Media utilizes transport native Sanitize operations. Sanitize specific
+ purge actions include: overwrite, block erase, or crypto erase.
+
+ Functions are defined to erase and purge data at a block level from mass
+ storage devices as well as to manage such devices in the EFI boot services
+ environment. Sanitization refers to a process that renders access to target
+ data on the media infeasible for a given level of effort.
+
+ NOTE: This operation is a blocking call.
+ NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId The media ID that the write request is for.
+ @param[in] PurgeAction The purage action (overwrite, crypto erase, block erase).
+ @param[in] OverwritePattern 32-bit pattern to overwrite on media (for overwrite).
+
+ @retval EFI_SUCCESS The media was purged successfully on the device.
+ @retval EFI_WRITE_PROTECTED The device can not be purged due to write protection.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the purge.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHNAGED The MediaId does not match the current device.
+ @retval EFI_INVALID_PARAMETER The purge request contains parameters that are not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+NvmExpressMediaPurge (
+ IN MEDIA_SANITIZE_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT32 PurgeAction,
+ IN UINT32 OverwritePattern
+ );
+
+/**
+ Format Media utilizes native format operations to modify sector/LBA size.
+ Secure erase actions are used to define how latent user data is erased.
+
+ NOTE: This function must be called from TPL_APPLICATION or TPL_CALLBACK.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId The media ID that the clear request is for.
+ @param[in] LbaSize Size of LBA (in terms of power of two: 2^n).
+ @param[in] SecureEraseAction Secure erase action, if any, to apply to format.
+ - 000b: No secure erase operation requested
+ - 001b: User Data Erase
+ - 010b: Cryptographic Erase
+ - 011b to 111b: Reserved
+
+ @retval EFI_SUCCESS The media format request completed successfully on the device.
+ @retval EFI_WRITE_PROTECTED The device can't be formatted due to write protection.
+ @retval EFI_DEVICE_ERROR The device reported an error while attempting to perform the format operation.
+ @retval EFI_INVALID_PARAMETER The format request contains parameters that are not valid.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
+
+ **/
+EFI_STATUS
+EFIAPI
+NvmExpressMediaFormat (
+ IN MEDIA_SANITIZE_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT32 LbaSize,
+ IN UINT32 SecureEraseAction
+ );
+
+#endif
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
index 2ff2cb0..f818e48 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
@@ -824,6 +824,8 @@ NvmExpressPassThru (
//
CopyMem (Packet->NvmeCompletion, (VOID *)Cq, sizeof (EFI_NVM_EXPRESS_COMPLETION));
} else {
+ ReportStatusCode ((EFI_ERROR_MAJOR | EFI_ERROR_CODE), (EFI_IO_BUS_SCSI | EFI_IOB_EC_INTERFACE_ERROR));
+
//
// Timeout occurs for an NVMe command. Reset the controller to abort the
// outstanding commands.
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTest.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTest.c
new file mode 100644
index 0000000..b872858
--- /dev/null
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTest.c
@@ -0,0 +1,1128 @@
+/** @file -- MediaSanitizeUnitTest.c
+ Placeholder/framework for developing a Media Sanitize unit test package.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UnitTestLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/NvmExpressPassthru.h>
+#include <Protocol/MediaSanitize.h>
+
+#include "../NvmExpress.h"
+#include "../NvmExpressBlockIo.h"
+#include "../NvmExpressMediaSanitize.h"
+#include "../NvmExpressHci.h"
+
+/**
+ Helper function for Nvme pass thru.
+
+ @param[in] This Private Data.
+ @param[in] NamespaceId Name Space Id.
+ @param[in,out] Packet Transfer Buffer.
+ @param[in] Event Event handle.
+
+ **/
+EFI_STATUS
+EFIAPI
+NvmeDeviceUnitTestPassthru (
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,
+ IN UINT32 NamespaceId,
+ IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet,
+ IN EFI_EVENT Event OPTIONAL
+ )
+{
+ //
+ // Parse command packet for unit testing
+ //
+ EFI_NVM_EXPRESS_COMMAND *Command;
+ EFI_NVM_EXPRESS_COMPLETION *Completion;
+ NVME_CQ *Cqe;
+ NVME_ADMIN_FORMAT_NVM FormatNvmCdw10;
+ NVME_ADMIN_SANITIZE SanitizeCdw1011;
+
+ ASSERT (This);
+ ASSERT (Packet);
+
+ Command = Packet->NvmeCmd;
+ Completion = Packet->NvmeCompletion;
+ Cqe = (NVME_CQ *)Completion;
+
+ ZeroMem (&FormatNvmCdw10, sizeof (NVME_ADMIN_FORMAT_NVM));
+ ZeroMem (&SanitizeCdw1011, sizeof (NVME_ADMIN_SANITIZE));
+
+ switch (Command->Cdw0.Opcode) {
+ case NVME_ADMIN_FORMAT_NVM_CMD:
+ UT_LOG_VERBOSE ("%a: Opcode = NVME_ADMIN_FORMAT_NVM_CMD\n", __func__);
+
+ CopyMem (&FormatNvmCdw10, &Command->Cdw10, sizeof (NVME_ADMIN_FORMAT_NVM));
+
+ //
+ // FormatNVM Check 1: Validate SES parameter
+ //
+ if (FormatNvmCdw10.Ses > 0x2) {
+ Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS;
+ Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD;
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // FormatNVM Check 2: Validate LbaIndex parameter
+ //
+ if (FormatNvmCdw10.Lbaf > 0x1) {
+ Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS;
+ Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD;
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ break;
+ case NVME_ADMIN_SANITIZE_CMD:
+ UT_LOG_VERBOSE ("%a: Opcode = NVME_ADMIN_SANITIZE_CMD\n", __func__);
+
+ CopyMem (&SanitizeCdw1011, &Command->Cdw10, sizeof (NVME_ADMIN_SANITIZE));
+
+ //
+ // Sanitize Check 1: Validate Sanitize Action parameter
+ //
+ if (SanitizeCdw1011.Sanact > 0x4) {
+ Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS;
+ Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD;
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Sanitize Check 2: Validate overwrite action with non-NULL overwrite pattern
+ //
+ if (((SanitizeCdw1011.Sanact == SANITIZE_ACTION_OVERWRITE) && (SanitizeCdw1011.Ovrpat != 0xDEADBEEF)) ||
+ ((SanitizeCdw1011.Sanact != SANITIZE_ACTION_OVERWRITE) && (SanitizeCdw1011.Ovrpat != 0)))
+ {
+ Cqe->Sct = NVME_CQE_SCT_GENERIC_CMD_STATUS;
+ Cqe->Sc = NVME_CQE_SC_INVALID_FIELD_IN_CMD;
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ break;
+ default:
+ UT_LOG_VERBOSE ("%a: Invalid Opcode = 0x%x!!!\n", __func__, Command->Cdw0.Opcode);
+ break;
+ }
+
+ //
+ // Populate CQE (completion queue entry based on opcode and parameters
+ //
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Helper function to simulate read.
+
+ @param[in] Private Private Data.
+ @param[in] NamespaceId Name Space Id.
+ @param[in] Buffer Transfer Buffer.
+
+ **/
+EFI_STATUS
+NvmeIdentifyNamespace (
+ IN NVME_CONTROLLER_PRIVATE_DATA *Private,
+ IN UINT32 NamespaceId,
+ IN VOID *Buffer
+ )
+{
+ EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket;
+ EFI_NVM_EXPRESS_COMMAND Command;
+ EFI_NVM_EXPRESS_COMPLETION Completion;
+
+ ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
+ ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND));
+ ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION));
+
+ CommandPacket.NvmeCmd = &Command;
+ CommandPacket.NvmeCompletion = &Completion;
+ Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD;
+ Command.Nsid = NamespaceId;
+ CommandPacket.TransferBuffer = Buffer;
+ CommandPacket.TransferLength = sizeof (NVME_ADMIN_NAMESPACE_DATA);
+ CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT;
+ CommandPacket.QueueType = NVME_ADMIN_QUEUE;
+
+ //
+ // Set bit 0 (Cns bit) to 1 to identify a namespace
+ //
+ CommandPacket.NvmeCmd->Cdw10 = 0;
+ CommandPacket.NvmeCmd->Flags = CDW10_VALID;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Helper function to simulate read.
+
+ @param[in] Device Private Data.
+ @param[out] Buffer Buffer to read into.
+ @param[in] Lba Logical Block Addess to read from.
+ @param[in] Blocks Number of blocks.
+
+ **/
+EFI_STATUS
+NvmeUnitTestRead (
+ IN NVME_DEVICE_PRIVATE_DATA *Device,
+ OUT VOID *Buffer,
+ IN UINT64 Lba,
+ IN UINTN Blocks
+ )
+{
+ UT_ASSERT_NOT_NULL (Device);
+ Buffer = NULL;
+ Lba = 0;
+ Blocks = 0;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Helper function to simulate write.
+
+ @param[in] Device Private Data.
+ @param[in] Buffer Buffer to write.
+ @param[in] Lba Logical Block Addess to write.
+ @param[in] Blocks Number of blocks.
+
+ **/
+EFI_STATUS
+NvmeUnitTestWrite (
+ IN NVME_DEVICE_PRIVATE_DATA *Device,
+ IN VOID *Buffer,
+ IN UINT64 Lba,
+ IN UINTN Blocks
+ )
+{
+ UT_ASSERT_NOT_NULL (Device);
+ Buffer = NULL;
+ Lba = 0;
+ Blocks = 0;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Simulated BlockIo read block function.
+
+ @param[in] This BlockIo Protocol.
+ @param[in] MediaId Id of the media.
+ @param[in] Lba Logical Block Address.
+ @param[in] BufferSize Size of Buffer.
+ @param[out] Buffer Actual buffer to use to read.
+
+ **/
+EFI_STATUS
+EFIAPI
+NvmeBlockIoReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ NVME_DEVICE_PRIVATE_DATA *Device;
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_MEDIA *Media;
+ UINTN BlockSize;
+ UINTN NumberOfBlocks;
+ UINTN IoAlign;
+
+ //
+ // Check parameters.
+ //
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Media = This->Media;
+
+ if (MediaId != Media->MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BufferSize == 0) {
+ return EFI_SUCCESS;
+ }
+
+ BlockSize = Media->BlockSize;
+ if ((BufferSize % BlockSize) != 0) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ NumberOfBlocks = BufferSize / BlockSize;
+ if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IoAlign = Media->IoAlign;
+ if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This);
+ Status = NvmeUnitTestRead (Device, Buffer, Lba, NumberOfBlocks);
+
+ return Status;
+}
+
+/**
+ Simulated BlockIo write block function.
+
+ @param[in] This BlockIo Protocol.
+ @param[in] MediaId Id of the media.
+ @param[in] Lba Logical Block Address.
+ @param[in] BufferSize Size of Buffer.
+ @param[in] Buffer Actual buffer to use to write.
+
+ **/
+EFI_STATUS
+EFIAPI
+NvmeBlockIoWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ NVME_DEVICE_PRIVATE_DATA *Device;
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_MEDIA *Media;
+ UINTN BlockSize;
+ UINTN NumberOfBlocks;
+ UINTN IoAlign;
+
+ //
+ // Check parameters.
+ //
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Media = This->Media;
+
+ if (MediaId != Media->MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BufferSize == 0) {
+ return EFI_SUCCESS;
+ }
+
+ BlockSize = Media->BlockSize;
+ if ((BufferSize % BlockSize) != 0) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ NumberOfBlocks = BufferSize / BlockSize;
+ if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IoAlign = Media->IoAlign;
+ if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This);
+ Status = NvmeUnitTestWrite (Device, Buffer, Lba, NumberOfBlocks);
+
+ return Status;
+}
+
+/**
+ Simulated BlockIo read block ex function.
+
+ @param[in] This BlockIo2 Protocol.
+ @param[in] MediaId Id of the media.
+ @param[in] Lba Logical Block Address.
+ @param[in,out] Token Block Io2 token.
+
+ @param[in] BufferSize Size of Buffer.
+ @param[out] Buffer Actual buffer to use to read.
+
+ **/
+EFI_STATUS
+EFIAPI
+NvmeBlockIoReadBlocksEx (
+ 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
+ )
+{
+ NVME_DEVICE_PRIVATE_DATA *Device;
+ EFI_BLOCK_IO_MEDIA *Media;
+ UINTN BlockSize;
+ UINTN NumberOfBlocks;
+ UINTN IoAlign;
+ EFI_STATUS Status;
+
+ //
+ // Check parameters.
+ //
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Media = This->Media;
+
+ if (MediaId != Media->MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BlockSize = Media->BlockSize;
+ if ((BufferSize % BlockSize) != 0) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ NumberOfBlocks = BufferSize / BlockSize;
+ if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IoAlign = Media->IoAlign;
+ if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This);
+ Status = NvmeUnitTestRead (Device, Buffer, Lba, NumberOfBlocks);
+
+ return Status;
+}
+
+/**
+ Simulated BlockIo write block ex function.
+
+ @param[in] This BlockIo2 Protocol.
+ @param[in] MediaId Id of the media.
+ @param[in] Lba Logical Block Address.
+ @param[in,out] Token Block Io2 token.
+ @param[in] BufferSize Size of Buffer.
+
+ @param[in] Buffer Actual buffer to use to write.
+
+ **/
+EFI_STATUS
+EFIAPI
+NvmeBlockIoWriteBlocksEx (
+ 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
+ )
+{
+ NVME_DEVICE_PRIVATE_DATA *Device;
+ EFI_BLOCK_IO_MEDIA *Media;
+ UINTN BlockSize;
+ UINTN NumberOfBlocks;
+ UINTN IoAlign;
+ EFI_STATUS Status;
+
+ //
+ // Check parameters.
+ //
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Media = This->Media;
+
+ if (MediaId != Media->MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BlockSize = Media->BlockSize;
+ if ((BufferSize % BlockSize) != 0) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ NumberOfBlocks = BufferSize / BlockSize;
+ if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IoAlign = Media->IoAlign;
+ if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO2 (This);
+ Status = NvmeUnitTestWrite (Device, Buffer, Lba, NumberOfBlocks);
+
+ return Status;
+}
+
+/**
+ MediaSanitizePurgeUnitTest to initialize a Private Namespace instance.
+
+ @param[in] ppDevice Nvme Private Data structure to destory and free.
+ **/
+UNIT_TEST_STATUS
+EFIAPI
+NvmeDestroyDeviceInstance (
+ NVME_DEVICE_PRIVATE_DATA **ppDevice
+ )
+{
+ //
+ // Free in following order to to avoid dangling pointers:
+ //
+ // 1 - NVME_ADMIN_CONTROLLER_DATA
+ // 2 - NVME_CONTROLLER_PRIVATE_DATA
+ // 3 - NVME_DEVICE_PRIVATE_DATA
+ //
+ FreePool ((*ppDevice)->Controller->ControllerData);
+ (*ppDevice)->Controller->ControllerData = NULL;
+
+ FreePool ((*ppDevice)->Controller);
+ (*ppDevice)->Controller = NULL;
+
+ FreePool ((*ppDevice));
+ *ppDevice = NULL;
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ MediaSanitizePurgeUnitTest to initialize a Private Namespace instance.
+
+ @param[in] ppDevice Nvme Private Data structure to initialize.
+ **/
+UNIT_TEST_STATUS
+EFIAPI
+NvmeCreateDeviceInstance (
+ NVME_DEVICE_PRIVATE_DATA **ppDevice
+ )
+{
+ NVME_ADMIN_NAMESPACE_DATA *NamespaceData;
+ NVME_CONTROLLER_PRIVATE_DATA *Private;
+ NVME_DEVICE_PRIVATE_DATA *Device;
+
+ Private = AllocateZeroPool (sizeof (NVME_CONTROLLER_PRIVATE_DATA));
+
+ Private->Signature = NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE;
+ Private->Cid[0] = 0;
+ Private->Cid[1] = 0;
+ Private->Cid[2] = 0;
+ Private->Pt[0] = 0;
+ Private->Pt[1] = 0;
+ Private->Pt[2] = 0;
+ Private->SqTdbl[0].Sqt = 0;
+ Private->SqTdbl[1].Sqt = 0;
+ Private->SqTdbl[2].Sqt = 0;
+ Private->CqHdbl[0].Cqh = 0;
+ Private->CqHdbl[1].Cqh = 0;
+ Private->CqHdbl[2].Cqh = 0;
+ Private->AsyncSqHead = 0;
+
+ Private->ControllerData = (NVME_ADMIN_CONTROLLER_DATA *)AllocateZeroPool (sizeof (NVME_ADMIN_CONTROLLER_DATA));
+
+ UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_CONTROLLER_PRIVATE_DATA\n", __func__);
+ UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_ADMIN_CONTROLLER_DATA\n", __func__);
+
+ Private->ControllerData->Nn = 1; // One namespace
+ Private->ControllerData->Sanicap.Bes = 1; // Block Erase Supported
+ Private->ControllerData->Sanicap.Ces = 1; // Crypto Erase Supported
+ Private->ControllerData->Sanicap.Ows = 1; // Overwrite Supported
+
+ NamespaceData = AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA));
+ UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_ADMIN_NAMESPACE_DATA\n", __func__);
+
+ Device = (NVME_DEVICE_PRIVATE_DATA *)(AllocateZeroPool (sizeof (NVME_DEVICE_PRIVATE_DATA)));
+
+ //
+ // Initialize SSD namespace instance data
+ //
+ Device->Signature = NVME_DEVICE_PRIVATE_DATA_SIGNATURE;
+ Device->NamespaceId = 0;
+ Device->NamespaceUuid = 1;
+
+ Device->Controller = Private;
+
+ //
+ // Build BlockIo media structure
+ //
+ Device->Media.MediaId = 0;
+ Device->Media.RemovableMedia = FALSE;
+ Device->Media.MediaPresent = TRUE;
+ Device->Media.LogicalPartition = FALSE;
+ Device->Media.ReadOnly = FALSE;
+ Device->Media.WriteCaching = FALSE;
+ Device->Media.BlockSize = (UINT32)(1 << 9); // 512 byte sector size
+
+ Device->Media.LastBlock = 0x4000; // NamespaceData=>Nsze
+ Device->Media.LogicalBlocksPerPhysicalBlock = 1;
+ Device->Media.LowestAlignedLba = 1;
+
+ Device->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2;
+ Device->BlockIo.Media = &Device->Media;
+ Device->BlockIo.ReadBlocks = NvmeBlockIoReadBlocks;
+ Device->BlockIo.WriteBlocks = NvmeBlockIoWriteBlocks;
+
+ Device->BlockIo2.Media = &Device->Media;
+ Device->BlockIo2.ReadBlocksEx = NvmeBlockIoReadBlocksEx;
+ Device->BlockIo2.WriteBlocksEx = NvmeBlockIoWriteBlocksEx;
+
+ Device->MediaSanitize.Revision = MEDIA_SANITIZE_PROTOCOL_REVISION;
+ Device->MediaSanitize.Media = &Device->Media;
+ Device->MediaSanitize.MediaClear = NvmExpressMediaClear;
+ Device->MediaSanitize.MediaPurge = NvmExpressMediaPurge;
+ Device->MediaSanitize.MediaFormat = NvmExpressMediaFormat;
+
+ Device->Controller->Passthru.Mode = 0;
+ Device->Controller->Passthru.PassThru = NvmeDeviceUnitTestPassthru;
+ Device->Controller->Passthru.BuildDevicePath = NULL;
+ Device->Controller->Passthru.GetNamespace = NULL;
+ Device->Controller->Passthru.GetNextNamespace = NULL;
+
+ CopyMem (&Device->NamespaceData, NamespaceData, sizeof (NVME_ADMIN_NAMESPACE_DATA));
+ *ppDevice = Device;
+
+ UT_LOG_VERBOSE ("%a: Allocated and Initialized NVME_DEVICE_PRIVATE_DATA\n", __func__);
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ MediaSanitizePurgeUnitTest to Test calls to NvmExpressMediaPurge.
+
+ @param[in] Context Unit test case context
+ **/
+UNIT_TEST_STATUS
+EFIAPI
+MediaSanitizePurgeUnitTest (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ UINT32 PurgeAction;
+ UINT32 OverwritePattern;
+ UNIT_TEST_STATUS UnitTestStatus;
+ NVME_DEVICE_PRIVATE_DATA *NvmeDevice;
+ EFI_STATUS Status;
+
+ UnitTestStatus = UNIT_TEST_PASSED;
+ NvmeDevice = NULL;
+ Status = EFI_SUCCESS;
+
+ UnitTestStatus = NvmeCreateDeviceInstance (&NvmeDevice);
+
+ UT_ASSERT_STATUS_EQUAL (UnitTestStatus, UNIT_TEST_PASSED);
+ UT_ASSERT_NOT_NULL (NvmeDevice);
+
+ UT_LOG_VERBOSE ("%a: Create Device Instance Status = 0x%x\n", __func__, UnitTestStatus);
+ UT_LOG_VERBOSE ("%a: Device = 0x%x\n", __func__, NvmeDevice);
+ UT_LOG_VERBOSE ("%a: Device->BlockIo = 0x%x\n", __func__, NvmeDevice->BlockIo);
+ UT_LOG_VERBOSE ("%a: Device->Signature = 0x%x\n", __func__, NvmeDevice->Signature);
+
+ //
+ // Case 1: Block Erase
+ //
+ PurgeAction = SANITIZE_ACTION_BLOCK_ERASE;
+ OverwritePattern = 0;
+
+ Status = NvmExpressMediaPurge (
+ &NvmeDevice->MediaSanitize,
+ NvmeDevice->Media.MediaId,
+ PurgeAction,
+ OverwritePattern
+ );
+
+ UT_ASSERT_NOT_EFI_ERROR (Status);
+
+ UnitTestStatus = NvmeDestroyDeviceInstance (&NvmeDevice);
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ NvmeSanitizeUnitTest to Test calls to NvmExpressSanitize.
+
+ @param[in] Context Unit test case context
+ **/
+UNIT_TEST_STATUS
+EFIAPI
+NvmeSanitizeUnitTest (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ UINT32 NamespaceId;
+ UINT32 SanitizeAction;
+ UINT32 NoDeallocateAfterSanitize;
+ UINT32 OverwritePattern;
+ UNIT_TEST_STATUS UnitTestStatus;
+ NVME_DEVICE_PRIVATE_DATA *NvmeDevice;
+ EFI_STATUS Status;
+
+ NamespaceId = 0;
+ UnitTestStatus = UNIT_TEST_PASSED;
+ NvmeDevice = NULL;
+ Status = EFI_SUCCESS;
+ SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE;
+ NoDeallocateAfterSanitize = 0;
+ OverwritePattern = 0;
+
+ UnitTestStatus = NvmeCreateDeviceInstance (&NvmeDevice);
+
+ UT_ASSERT_STATUS_EQUAL (UnitTestStatus, UNIT_TEST_PASSED);
+ UT_ASSERT_NOT_NULL (NvmeDevice);
+
+ UT_LOG_VERBOSE ("%a: Create Device Instance Status = 0x%x\n", __func__, UnitTestStatus);
+ UT_LOG_VERBOSE ("%a: Device = 0x%x\n", __func__, NvmeDevice);
+ UT_LOG_VERBOSE ("%a: Device->BlockIo = 0x%x\n", __func__, NvmeDevice->BlockIo);
+ UT_LOG_VERBOSE ("%a: Device->Signature = 0x%x\n", __func__, NvmeDevice->Signature);
+
+ //
+ // Case 1: Block Erase
+ //
+ SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE;
+ NoDeallocateAfterSanitize = 0;
+ OverwritePattern = 0;
+
+ Status = NvmExpressSanitize (
+ &NvmeDevice->BlockIo,
+ NamespaceId,
+ SanitizeAction,
+ NoDeallocateAfterSanitize,
+ OverwritePattern
+ );
+
+ UT_ASSERT_NOT_EFI_ERROR (Status);
+
+ //
+ // Case 2: Crypto Erase
+ //
+ SanitizeAction = SANITIZE_ACTION_CRYPTO_ERASE;
+ NoDeallocateAfterSanitize = 0;
+ OverwritePattern = 0;
+
+ Status = NvmExpressSanitize (
+ &NvmeDevice->BlockIo,
+ NamespaceId,
+ SanitizeAction,
+ NoDeallocateAfterSanitize,
+ OverwritePattern
+ );
+
+ UT_ASSERT_NOT_EFI_ERROR (Status);
+
+ //
+ // Case 3: Overwrite
+ //
+ SanitizeAction = SANITIZE_ACTION_OVERWRITE;
+ NoDeallocateAfterSanitize = 0;
+ OverwritePattern = 0xDEADBEEF;
+
+ Status = NvmExpressSanitize (
+ &NvmeDevice->BlockIo,
+ NamespaceId,
+ SanitizeAction,
+ NoDeallocateAfterSanitize,
+ OverwritePattern
+ );
+
+ UT_ASSERT_NOT_EFI_ERROR (Status);
+
+ //
+ // Case 4: Block Erase (invalid overwrite pattern)
+ //
+ SanitizeAction = SANITIZE_ACTION_BLOCK_ERASE;
+ NoDeallocateAfterSanitize = 0;
+ OverwritePattern = 0xDEADBEEF;
+
+ Status = NvmExpressSanitize (
+ &NvmeDevice->BlockIo,
+ NamespaceId,
+ SanitizeAction,
+ NoDeallocateAfterSanitize,
+ OverwritePattern
+ );
+
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);
+
+ //
+ // Case 5: Overwrite (invalid overwrite pattern)
+ //
+ SanitizeAction = SANITIZE_ACTION_OVERWRITE;
+ NoDeallocateAfterSanitize = 0;
+ OverwritePattern = 0;
+
+ Status = NvmExpressSanitize (
+ &NvmeDevice->BlockIo,
+ NamespaceId,
+ SanitizeAction,
+ NoDeallocateAfterSanitize,
+ OverwritePattern
+ );
+
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);
+
+ UnitTestStatus = NvmeDestroyDeviceInstance (&NvmeDevice);
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ NvmeFormatNvmUnitTest to Test calls to NvmExpressFormatNvm.
+
+ @param[in] Context Unit test case context
+ **/
+UNIT_TEST_STATUS
+EFIAPI
+NvmeFormatNvmUnitTest (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ UINT32 NamespaceId;
+ UINT32 Ses;
+ UINT32 Flbas;
+ NVME_DEVICE_PRIVATE_DATA *NvmeDevice;
+ UNIT_TEST_STATUS UnitTestStatus;
+ EFI_STATUS Status;
+
+ NamespaceId = 0;
+ NvmeDevice = NULL;
+ UnitTestStatus = UNIT_TEST_PASSED;
+ Status = EFI_SUCCESS;
+
+ UnitTestStatus = NvmeCreateDeviceInstance (&NvmeDevice);
+
+ UT_ASSERT_STATUS_EQUAL (UnitTestStatus, UNIT_TEST_PASSED);
+ UT_ASSERT_NOT_NULL (NvmeDevice);
+
+ UT_LOG_VERBOSE ("%a: Create Device Instance Status = 0x%x\n", __func__, UnitTestStatus);
+ UT_LOG_VERBOSE ("%a: Device = 0x%x\n", __func__, NvmeDevice);
+ UT_LOG_VERBOSE ("%a: Device->BlockIo = 0x%x\n", __func__, NvmeDevice->BlockIo);
+ UT_LOG_VERBOSE ("%a: Device->Signature = 0x%x\n", __func__, NvmeDevice->Signature);
+
+ //
+ // Case 1: User Data Erase (Flbas = 0)
+ //
+ Ses = SES_USER_DATA_ERASE;
+ Flbas = 0;
+ Status = NvmExpressFormatNvm (
+ &NvmeDevice->BlockIo,
+ NamespaceId,
+ Ses,
+ Flbas
+ );
+
+ UT_ASSERT_NOT_EFI_ERROR (Status);
+
+ //
+ // Case 2: Crypto Erase (Flbas = 0)
+ //
+ Ses = SES_CRYPTO_ERASE;
+ Flbas = 0;
+ Status = NvmExpressFormatNvm (
+ &NvmeDevice->BlockIo,
+ NamespaceId,
+ Ses,
+ Flbas
+ );
+
+ UT_ASSERT_NOT_EFI_ERROR (Status);
+
+ //
+ // Case 3: User Data Erase (Invalid Flbas = 3)
+ //
+ Ses = SES_USER_DATA_ERASE;
+ Flbas = 3;
+ Status = NvmExpressFormatNvm (
+ &NvmeDevice->BlockIo,
+ NamespaceId,
+ Ses,
+ Flbas
+ );
+
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);
+
+ //
+ // Case 4: Invalid SES (Flba = 0)
+ //
+ Ses = 0xFF;
+ Flbas = 0;
+ Status = NvmExpressFormatNvm (
+ &NvmeDevice->BlockIo,
+ NamespaceId,
+ Ses,
+ Flbas
+ );
+
+ UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER);
+
+ UnitTestStatus = NvmeDestroyDeviceInstance (&NvmeDevice);
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ Baseline Unit Test.
+
+ @param[in] Context Unit test case context
+ **/
+UNIT_TEST_STATUS
+EFIAPI
+UnitTestBaseline (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ UINT32 A;
+ UINT32 B;
+ UINT32 C;
+
+ A = 1;
+ B = 1;
+ C = A + B;
+
+ UT_ASSERT_EQUAL (C, 2);
+ UT_ASSERT_NOT_EQUAL (0, 1);
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ Test Case that locks a variable using the Variable Policy Protocol with a
+ policy other than LOCK_NOW then attempts to lock the same variable using the
+ Variable Lock Protocol. The call to Variable Policy is expected to succeed
+ and the call to Variable Lock is expected to fail.
+
+ @retval EFI_SUCCES Success
+ @retval Other Error
+ **/
+EFI_STATUS
+EFIAPI
+MediaSanitizeUnitTestEntry (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UNIT_TEST_FRAMEWORK_HANDLE Framework;
+ UNIT_TEST_SUITE_HANDLE NvmeFormatNvmTestSuite;
+ UNIT_TEST_SUITE_HANDLE NvmeSanitizeTestSuite;
+ UNIT_TEST_SUITE_HANDLE MediaSanitizeProtocolTestSuite;
+
+ Framework = NULL;
+
+ #define UNIT_TEST_NAME "Media Sanitize Protocol Unit Test"
+ #define UNIT_TEST_VERSION "1.0"
+
+ DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION));
+
+ //
+ // Start setting up the test framework for running the tests.
+ //
+ Status = InitUnitTestFramework (
+ &Framework,
+ UNIT_TEST_NAME,
+ gEfiCallerBaseName,
+ UNIT_TEST_VERSION
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
+ goto EXIT;
+ }
+
+ //
+ // Populate the NVM Express Format NVM Unit Test Suite.
+ //
+ Status = CreateUnitTestSuite (
+ &NvmeFormatNvmTestSuite,
+ Framework,
+ "NVM Express Format NVM Test Suite",
+ "Nvm.Express.Format.Nvm",
+ NULL,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for NvmeFormatNvmTestSuite. Status = %r\n", Status));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ //
+ // Add baseline sanity test case
+ //
+ AddTestCase (
+ NvmeFormatNvmTestSuite, // Test Suite Handle
+ "Baseline Format NVM Unit Test", // Test Description
+ "FormatNVM", // Test Class
+ UnitTestBaseline, // UNIT_TEST_FUNCTION()
+ NULL, // (Optional) UNIT_TEST_PREREQUISITE()
+ NULL, // (Optional) UNIT_TEST_CLEANUP()
+ NULL // (Optional) UNIT_TEST_CONTEXT
+ );
+
+ //
+ // Add test case for NvmExpressFormatNvm()
+ //
+ AddTestCase (
+ NvmeFormatNvmTestSuite, // Test Suite Handle
+ "Admin Format NVM Command Unit Test", // Test Description
+ "FormatNVM", // Test Class
+ NvmeFormatNvmUnitTest, // UNIT_TEST_FUNCTION()
+ NULL, // (Optional) UNIT_TEST_PREREQUISITE()
+ NULL, // (Optional) UNIT_TEST_CLEANUP()
+ NULL // (Optional) UNIT_TEST_CONTEXT
+ );
+
+ //
+ // Populate the NVM Express Sanitize Unit Test Suite.
+ //
+ Status = CreateUnitTestSuite (
+ &NvmeSanitizeTestSuite,
+ Framework,
+ "NVM Express Sanitize Test Suite",
+ "Nvm.Express.Sanitize",
+ NULL,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for NvmeSanitizTestSuite. Status = %r\n", Status));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ //
+ // Add baseline sanity test
+ //
+ AddTestCase (
+ NvmeSanitizeTestSuite, // Test Suite Handle
+ "Baseline Sanitize Unit Test", // Test Description
+ "Sanitize", // Test Class
+ UnitTestBaseline, // UNIT_TEST_FUNCTION()
+ NULL, // (Optional) UNIT_TEST_PREREQUISITE()
+ NULL, // (Optional) UNIT_TEST_CLEANUP()
+ NULL // (Optional) UNIT_TEST_CONTEXT
+ );
+
+ //
+ // Add test case for NvmExressSanitize()
+ //
+ AddTestCase (
+ NvmeSanitizeTestSuite, // Test Suite Handle
+ "Admin Sanitize Command Unit Test", // Test Description
+ "Sanitize", // Test Class
+ NvmeSanitizeUnitTest, // UNIT_TEST_FUNCTION()
+ NULL, // (Optional) UNIT_TEST_PREREQUISITE()
+ NULL, // (Optional) UNIT_TEST_CLEANUP()
+ NULL // (Optional) UNIT_TEST_CONTEXT
+ );
+
+ //
+ // Populate the Media Sanitize Protocol Unit Test Suite.
+ //
+ Status = CreateUnitTestSuite (
+ &MediaSanitizeProtocolTestSuite,
+ Framework,
+ "Media Sanitize Protocol Test Suite",
+ "Media.Sanitize.Protocol",
+ NULL,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MediaSanitizeProtocolTestSuite. Status = %r\n", Status));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto EXIT;
+ }
+
+ //
+ // Add test case for Media Purge
+ //
+ AddTestCase (
+ MediaSanitizeProtocolTestSuite, // Test Suite Handle
+ "Baseline MediaSanitize Unit Test", // Test Description
+ "MediaSanitize", // Test Class
+ UnitTestBaseline, // UNIT_TEST_FUNCTION()
+ NULL, // (Optional) UNIT_TEST_PREREQUISITE()
+ NULL, // (Optional) UNIT_TEST_CLEANUP()
+ NULL // (Optional) UNIT_TEST_CONTEXT
+ );
+
+ //
+ // Add test case for Media Purge
+ //
+ AddTestCase (
+ MediaSanitizeProtocolTestSuite, // Test Suite Handle
+ "Protocol Media Sanitize Unit Test", // Test Description
+ "MediaPurge", // Test Class
+ MediaSanitizePurgeUnitTest, // UNIT_TEST_FUNCTION()
+ NULL, // (Optional) UNIT_TEST_PREREQUISITE()
+ NULL, // (Optional) UNIT_TEST_CLEANUP()
+ NULL // (Optional) UNIT_TEST_CONTEXT
+ );
+
+ //
+ // Execute the tests.
+ //
+ Status = RunAllTestSuites (Framework);
+
+EXIT:
+ if (Framework) {
+ FreeUnitTestFramework (Framework);
+ }
+
+ return Status;
+}
+
+///
+/// Avoid ECC error for function name that starts with lower case letter
+///
+#define MediaSanitizeUnitTestMain main
+
+/**
+ Standard POSIX C entry point for host based unit test execution.
+
+ @param[in] Argc Number of arguments
+ @param[in] Argv Array of pointers to arguments
+
+ @retval 0 Success
+ @retval other Error
+**/
+INT32
+MediaSanitizeUnitTestMain (
+ IN INT32 Argc,
+ IN CHAR8 *Argv[]
+ )
+{
+ return MediaSanitizeUnitTestEntry ();
+}
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf b/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf
new file mode 100644
index 0000000..feeeea3
--- /dev/null
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf
@@ -0,0 +1,37 @@
+## @file
+# Unit tests for MEDIA_SANITIZE_PROTOCOL and mapping to NVM Express native commands (Sanitize and FormatNVM)
+#
+# Copyright (C) Microsoft Corporation.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = MediaSanitizeUnitTestHost
+ FILE_GUID = AAE328E9-37C3-4F4A-A2C0-0BE0E681ADA6
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ MediaSanitizeUnitTest.c
+ ../NvmExpressMediaSanitize.c
+ ../NvmExpressMediaSanitize.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ UnitTestLib
+ PrintLib
+ MemoryAllocationLib
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
index cf6b329..a9d7e36 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
@@ -2077,7 +2077,12 @@ XhcDriverBindingStart (
XhcSetBiosOwnership (Xhc);
- XhcResetHC (Xhc, XHC_RESET_TIMEOUT);
+ Status = XhcResetHC (Xhc, XHC_RESET_TIMEOUT);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: failed to reset HC\n", __func__));
+ goto FREE_POOL;
+ }
+
ASSERT (XhcIsHalt (Xhc));
//
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
index 525942a..dc8228b 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
@@ -29,6 +29,8 @@ XhcReadCapReg8 (
UINT8 Data;
EFI_STATUS Status;
+ Data = 0;
+
Status = Xhc->PciIo->Mem.Read (
Xhc->PciIo,
EfiPciIoWidthUint8,
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
index a97ed44..3caa060 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -2165,6 +2165,7 @@ XhcInitializeDeviceSlot (
DEVICE_CONTEXT *ParentDeviceContext;
EFI_PHYSICAL_ADDRESS PhyAddr;
+ EvtTrb = NULL;
ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT));
CmdTrb.CycleBit = 1;
CmdTrb.Type = TRB_TYPE_EN_SLOT;
@@ -2175,7 +2176,7 @@ XhcInitializeDeviceSlot (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcInitializeDeviceSlot: Enable Slot Failed, Status = %r\n", Status));
return Status;
}
@@ -2390,6 +2391,7 @@ XhcInitializeDeviceSlot64 (
DEVICE_CONTEXT_64 *ParentDeviceContext;
EFI_PHYSICAL_ADDRESS PhyAddr;
+ EvtTrb = NULL;
ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT));
CmdTrb.CycleBit = 1;
CmdTrb.Type = TRB_TYPE_EN_SLOT;
@@ -2400,7 +2402,7 @@ XhcInitializeDeviceSlot64 (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcInitializeDeviceSlot64: Enable Slot Failed, Status = %r\n", Status));
return Status;
}
@@ -2602,6 +2604,8 @@ XhcDisableSlotCmd (
UINT8 Index;
VOID *RingSeg;
+ EvtTrb = NULL;
+
//
// Disable the device slots occupied by these devices on its downstream ports.
// Entry 0 is reserved.
@@ -2637,7 +2641,7 @@ XhcDisableSlotCmd (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status));
return Status;
}
@@ -2713,6 +2717,8 @@ XhcDisableSlotCmd64 (
UINT8 Index;
VOID *RingSeg;
+ EvtTrb = NULL;
+
//
// Disable the device slots occupied by these devices on its downstream ports.
// Entry 0 is reserved.
@@ -2748,7 +2754,7 @@ XhcDisableSlotCmd64 (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status));
return Status;
}
@@ -3240,6 +3246,8 @@ XhcSetConfigCmd (
DEVICE_CONTEXT *OutputContext;
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
+ EvtTrb = NULL;
+
//
// 4.6.6 Configure Endpoint
//
@@ -3290,7 +3298,7 @@ XhcSetConfigCmd (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status));
} else {
Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue;
@@ -3331,6 +3339,8 @@ XhcSetConfigCmd64 (
DEVICE_CONTEXT_64 *OutputContext;
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
+ EvtTrb = NULL;
+
//
// 4.6.6 Configure Endpoint
//
@@ -3381,7 +3391,7 @@ XhcSetConfigCmd64 (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status));
} else {
Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue;
@@ -3417,6 +3427,8 @@ XhcStopEndpoint (
DEBUG ((DEBUG_VERBOSE, "XhcStopEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));
+ EvtTrb = NULL;
+
//
// When XhcCheckUrbResult waits for the Stop_Endpoint completion, it also checks
// the PendingUrb completion status, because it's possible that the PendingUrb is
@@ -3454,7 +3466,7 @@ XhcStopEndpoint (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcStopEndpoint: Stop Endpoint Failed, Status = %r\n", Status));
}
@@ -3488,6 +3500,8 @@ XhcResetEndpoint (
DEBUG ((DEBUG_INFO, "XhcResetEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci));
+ EvtTrb = NULL;
+
//
// Send stop endpoint command to transit Endpoint from running to stop state
//
@@ -3502,7 +3516,7 @@ XhcResetEndpoint (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcResetEndpoint: Reset Endpoint Failed, Status = %r\n", Status));
}
@@ -3538,6 +3552,8 @@ XhcSetTrDequeuePointer (
DEBUG ((DEBUG_VERBOSE, "XhcSetTrDequeuePointer: Slot = 0x%x, Dci = 0x%x, Urb = 0x%x\n", SlotId, Dci, Urb));
+ EvtTrb = NULL;
+
//
// Send stop endpoint command to transit Endpoint from running to stop state
//
@@ -3555,7 +3571,7 @@ XhcSetTrDequeuePointer (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcSetTrDequeuePointer: Set TR Dequeue Pointer Failed, Status = %r\n", Status));
}
@@ -3604,6 +3620,7 @@ XhcSetInterface (
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
Status = EFI_SUCCESS;
+ EvtTrb = NULL;
InputContext = Xhc->UsbDevContext[SlotId].InputContext;
OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
@@ -3755,7 +3772,7 @@ XhcSetInterface (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "SetInterface: Config Endpoint Failed, Status = %r\n", Status));
} else {
//
@@ -3810,6 +3827,7 @@ XhcSetInterface64 (
EVT_TRB_COMMAND_COMPLETION *EvtTrb;
Status = EFI_SUCCESS;
+ EvtTrb = NULL;
InputContext = Xhc->UsbDevContext[SlotId].InputContext;
OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
@@ -3961,7 +3979,7 @@ XhcSetInterface64 (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "SetInterface64: Config Endpoint Failed, Status = %r\n", Status));
} else {
//
@@ -4001,6 +4019,8 @@ XhcEvaluateContext (
ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
+ EvtTrb = NULL;
+
//
// 4.6.7 Evaluate Context
//
@@ -4028,7 +4048,7 @@ XhcEvaluateContext (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcEvaluateContext: Evaluate Context Failed, Status = %r\n", Status));
}
@@ -4062,6 +4082,8 @@ XhcEvaluateContext64 (
ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
+ EvtTrb = NULL;
+
//
// 4.6.7 Evaluate Context
//
@@ -4089,7 +4111,7 @@ XhcEvaluateContext64 (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcEvaluateContext64: Evaluate Context Failed, Status = %r\n", Status));
}
@@ -4125,6 +4147,7 @@ XhcConfigHubContext (
EFI_PHYSICAL_ADDRESS PhyAddr;
ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0);
+ EvtTrb = NULL;
InputContext = Xhc->UsbDevContext[SlotId].InputContext;
OutputContext = Xhc->UsbDevContext[SlotId].OutputContext;
@@ -4158,7 +4181,7 @@ XhcConfigHubContext (
XHC_GENERIC_TIMEOUT,
(TRB_TEMPLATE **)(UINTN)&EvtTrb
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || (EvtTrb == NULL)) {
DEBUG ((DEBUG_ERROR, "XhcConfigHubContext: Config Endpoint Failed, Status = %r\n", Status));
}
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c
index b8651ff..e04a93d 100644
--- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c
+++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -1017,6 +1017,55 @@ UfsEndOfPei (
}
/**
+ Finishes device initialization by setting fDeviceInit flag and waiting until device responds by
+ clearing it.
+
+ @param[in] Private Pointer to the UFS_PEIM_HC_PRIVATE_DATA.
+
+ @retval EFI_SUCCESS The operation succeeds.
+ @retval Others The operation fails.
+
+**/
+EFI_STATUS
+UfsFinishDeviceInitialization (
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ UINT8 DeviceInitStatus;
+ UINT32 Timeout;
+
+ DeviceInitStatus = 0xFF;
+ Timeout = PcdGet32 (PcdUfsInitialCompletionTimeout);
+
+ //
+ // The host enables the device initialization completion by setting fDeviceInit flag.
+ //
+ Status = UfsSetFlag (Private, UfsFlagDevInit);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ do {
+ Status = UfsReadFlag (Private, UfsFlagDevInit, &DeviceInitStatus);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MicroSecondDelay (1);
+ Timeout--;
+ } while (DeviceInitStatus != 0 && Timeout != 0);
+
+ if (Timeout == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: DeviceInitStatus = %x EFI_TIMEOUT \n", __func__, DeviceInitStatus));
+ return EFI_TIMEOUT;
+ } else {
+ DEBUG ((DEBUG_INFO, "%a: Timeout left = %x EFI_SUCCESS \n", __func__, Timeout));
+ return EFI_SUCCESS;
+ }
+}
+
+/**
The user code starts with this function.
@param FileHandle Handle of the file being invoked.
@@ -1116,11 +1165,11 @@ InitializeUfsBlockIoPeim (
}
//
- // The host enables the device initialization completion by setting fDeviceInit flag.
+ // Check the UFS device is initialized completed.
//
- Status = UfsSetFlag (Private, UfsFlagDevInit);
+ Status = UfsFinishDeviceInitialization (Private);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Ufs Set fDeviceInit Flag Error, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "Device failed to finish initialization, Status = %r\n", Status));
Controller++;
continue;
}
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h
index ed4776f..869332f 100644
--- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h
+++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -22,6 +22,7 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/IoLib.h>
#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
#include <Library/PeiServicesLib.h>
#include <IndustryStandard/Scsi.h>
@@ -227,6 +228,25 @@ UfsSetFlag (
);
/**
+ Read specified flag from a UFS device.
+
+ @param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.
+ @param[in] FlagId The ID of flag to be read.
+ @param[out] Value The flag's value.
+
+ @retval EFI_SUCCESS The flag was read successfully.
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to read the flag.
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of reading the flag.
+
+**/
+EFI_STATUS
+UfsReadFlag (
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private,
+ IN UINT8 FlagId,
+ OUT UINT8 *Value
+ );
+
+/**
Read or write specified device descriptor of a UFS device.
@param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf
index 6e1cbfd..5da906e 100644
--- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf
+++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf
@@ -41,6 +41,7 @@
IoLib
TimerLib
BaseMemoryLib
+ PcdLib
PeimEntryPoint
PeiServicesLib
DebugLib
@@ -52,9 +53,11 @@
gEdkiiIoMmuPpiGuid ## CONSUMES
gEfiEndOfPeiSignalPpiGuid ## CONSUMES
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUfsInitialCompletionTimeout ## CONSUMES
+
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid AND gEdkiiPeiUfsHostControllerPpiGuid
[UserExtensions.TianoCore."ExtraFiles"]
UfsBlockIoPeiExtra.uni
-
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c
index d19a7fe..360b642 100644
--- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c
+++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -1066,6 +1066,32 @@ UfsSetFlag (
}
/**
+ Read specified flag from a UFS device.
+
+ @param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.
+ @param[in] FlagId The ID of flag to be read.
+ @param[out] Value The flag's value.
+
+ @retval EFI_SUCCESS The flag was read successfully.
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to read the flag.
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of reading the flag.
+
+**/
+EFI_STATUS
+UfsReadFlag (
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private,
+ IN UINT8 FlagId,
+ OUT UINT8 *Value
+ )
+{
+ EFI_STATUS Status;
+
+ Status = UfsRwFlags (Private, TRUE, FlagId, Value);
+
+ return Status;
+}
+
+/**
Sends NOP IN cmd to a UFS device for initialization process request.
For more details, please refer to UFS 2.0 spec Figure 13.3.
diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c
index 880e7d8..816532d 100644
--- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c
+++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c
@@ -759,6 +759,7 @@ UfsFinishDeviceInitialization (
UINT32 Timeout;
DeviceInitStatus = 0xFF;
+ Timeout = PcdGet32 (PcdUfsInitialCompletionTimeout);
//
// The host enables the device initialization completion by setting fDeviceInit flag.
@@ -768,10 +769,6 @@ UfsFinishDeviceInitialization (
return Status;
}
- //
- // There are cards that can take upto 600ms to clear fDeviceInit flag.
- //
- Timeout = UFS_INIT_COMPLETION_TIMEOUT;
do {
Status = UfsReadFlag (Private, UfsFlagDevInit, &DeviceInitStatus);
if (EFI_ERROR (Status)) {
diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h
index bc1139d..d380650 100644
--- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h
+++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.h
@@ -24,6 +24,7 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
#include <Library/TimerLib.h>
#include "UfsPassThruHci.h"
@@ -38,9 +39,8 @@
// Lun 10: BOOT
// Lun 11: RPMB
//
-#define UFS_MAX_LUNS 12
-#define UFS_WLUN_PREFIX 0xC1
-#define UFS_INIT_COMPLETION_TIMEOUT 600000
+#define UFS_MAX_LUNS 12
+#define UFS_WLUN_PREFIX 0xC1
typedef struct {
UINT8 Lun[UFS_MAX_LUNS];
diff --git a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf
index 92dc257..0e12b7a 100644
--- a/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf
+++ b/MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruDxe.inf
@@ -48,6 +48,7 @@
UefiDriverEntryPoint
DebugLib
DevicePathLib
+ PcdLib
TimerLib
[Protocols]
@@ -56,5 +57,8 @@
gEdkiiUfsHostControllerProtocolGuid ## TO_START
gEdkiiUfsHcPlatformProtocolGuid ## SOMETIMES_CONSUMES
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUfsInitialCompletionTimeout ## CONSUMES
+
[UserExtensions.TianoCore."ExtraFiles"]
UfsPassThruExtra.uni
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c
index c25f3cc..2826ac1 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c
@@ -3,6 +3,7 @@
Usb Bus Driver Binding and Bus IO Protocol.
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -821,6 +822,7 @@ UsbIoPortReset (
EFI_TPL OldTpl;
EFI_STATUS Status;
UINT8 DevAddress;
+ UINT8 Config;
OldTpl = gBS->RaiseTPL (USB_BUS_TPL);
@@ -882,8 +884,26 @@ UsbIoPortReset (
// is in CONFIGURED state.
//
if (Dev->ActiveConfig != NULL) {
- Status = UsbSetConfig (Dev, Dev->ActiveConfig->Desc.ConfigurationValue);
+ UsbFreeDevDesc (Dev->DevDesc);
+ Status = UsbRemoveConfig (Dev);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "UsbIoPortReset: Failed to remove configuration - %r\n", Status));
+ }
+
+ Status = UsbGetMaxPacketSize0 (Dev);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "UsbIoPortReset: Failed to get max packet size - %r\n", Status));
+ }
+
+ Status = UsbBuildDescTable (Dev);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "UsbIoPortReset: Failed to build descriptor table - %r\n", Status));
+ }
+
+ Config = Dev->DevDesc->Configs[0]->Desc.ConfigurationValue;
+
+ Status = UsbSetConfig (Dev, Config);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
@@ -892,6 +912,11 @@ UsbIoPortReset (
Status
));
}
+
+ Status = UsbSelectConfig (Dev, Config);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "UsbIoPortReset: Failed to set configuration - %r\n", Status));
+ }
}
ON_EXIT:
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h
index 53e2670..cd3940d 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.h
+++ b/MdeModulePkg/Core/Dxe/DxeMain.h
@@ -84,6 +84,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/DxeServicesLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/CpuExceptionHandlerLib.h>
+#include <Library/OrderedCollectionLib.h>
//
// attributes for reserved memory before it is promoted to system memory
@@ -2790,4 +2791,15 @@ MergeMemoryMap (
IN UINTN DescriptorSize
);
+/**
+ Initializes "handle" support.
+
+ @return Status code.
+
++**/
+EFI_STATUS
+CoreInitializeHandleServices (
+ VOID
+ );
+
#endif
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index 090970a..cc315ac 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -95,6 +95,7 @@
CpuExceptionHandlerLib
PcdLib
ImagePropertiesRecordLib
+ OrderedCollectionLib
[Guids]
gEfiEventMemoryMapChangeGuid ## PRODUCES ## Event
diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
index 17d510a..8a87733 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
+++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
@@ -277,6 +277,12 @@ DxeMain (
MemoryProfileInit (HobStart);
//
+ // Start the Handle Services.
+ //
+ Status = CoreInitializeHandleServices ();
+ ASSERT_EFI_ERROR (Status);
+
+ //
// Start the Image Services.
//
Status = CoreInitializeImageServices (HobStart);
diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
index 9936450..6ea89fb 100644
--- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
+++ b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
@@ -989,6 +989,20 @@ CoreConvertSpace (
//
case GCD_SET_CAPABILITIES_MEMORY_OPERATION:
Entry->Capabilities = Capabilities;
+
+ // Only SystemMemory and MoreReliable memory is in gMemoryMap
+ // so only attempt to update the attributes there if this is
+ // a relevant GCD type
+ if ((Entry->GcdMemoryType == EfiGcdMemoryTypeSystemMemory) ||
+ (Entry->GcdMemoryType == EfiGcdMemoryTypeMoreReliable))
+ {
+ CoreUpdateMemoryAttributes (
+ BaseAddress,
+ RShiftU64 (Length, EFI_PAGE_SHIFT),
+ Capabilities & (~EFI_MEMORY_RUNTIME)
+ );
+ }
+
break;
}
@@ -1700,17 +1714,10 @@ CoreSetMemorySpaceCapabilities (
IN UINT64 Capabilities
)
{
- EFI_STATUS Status;
-
DEBUG ((DEBUG_GCD, "GCD:CoreSetMemorySpaceCapabilities(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
DEBUG ((DEBUG_GCD, " Capabilities = %016lx\n", Capabilities));
- Status = CoreConvertSpace (GCD_SET_CAPABILITIES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, Capabilities, 0);
- if (!EFI_ERROR (Status)) {
- CoreUpdateMemoryAttributes (BaseAddress, RShiftU64 (Length, EFI_PAGE_SHIFT), Capabilities & (~EFI_MEMORY_RUNTIME));
- }
-
- return Status;
+ return CoreConvertSpace (GCD_SET_CAPABILITIES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE)0, (EFI_GCD_IO_TYPE)0, BaseAddress, Length, Capabilities, 0);
}
/**
diff --git a/MdeModulePkg/Core/Dxe/Hand/Handle.c b/MdeModulePkg/Core/Dxe/Hand/Handle.c
index 24e4fbf..b5ff3fd 100644
--- a/MdeModulePkg/Core/Dxe/Hand/Handle.c
+++ b/MdeModulePkg/Core/Dxe/Hand/Handle.c
@@ -15,10 +15,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
// gProtocolDatabaseLock - Lock to protect the mProtocolDatabase
// gHandleDatabaseKey - The Key to show that the handle has been created/modified
//
-LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);
-LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
-EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
-UINT64 gHandleDatabaseKey = 0;
+LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);
+LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
+EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
+UINT64 gHandleDatabaseKey = 0;
+ORDERED_COLLECTION *gOrderedHandleList = NULL;
/**
Acquire lock on gProtocolDatabaseLock.
@@ -45,6 +46,60 @@ CoreReleaseProtocolLock (
}
/**
+ Comparator function for two opaque pointers, ordering on (unsigned) pointer
+ value itself.
+ Can be used as both Key and UserStruct comparator.
+
+ @param[in] Pointer1 First pointer.
+
+ @param[in] Pointer2 Second pointer.
+
+ @retval <0 If Pointer1 compares less than Pointer2.
+
+ @retval 0 If Pointer1 compares equal to Pointer2.
+
+ @retval >0 If Pointer1 compares greater than Pointer2.
+**/
+STATIC
+INTN
+EFIAPI
+PointerCompare (
+ IN CONST VOID *Pointer1,
+ IN CONST VOID *Pointer2
+ )
+{
+ if (Pointer1 == Pointer2) {
+ return 0;
+ }
+
+ if ((UINTN)Pointer1 < (UINTN)Pointer2) {
+ return -1;
+ }
+
+ return 1;
+}
+
+/**
+ Initializes "handle" support.
+
+ @return Status code.
+
+**/
+EFI_STATUS
+CoreInitializeHandleServices (
+ VOID
+ )
+{
+ gOrderedHandleList = OrderedCollectionInit (PointerCompare, PointerCompare);
+
+ if (gOrderedHandleList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
Check whether a handle is a valid EFI_HANDLE
The gProtocolDatabaseLock must be owned
@@ -59,8 +114,7 @@ CoreValidateHandle (
IN EFI_HANDLE UserHandle
)
{
- IHANDLE *Handle;
- LIST_ENTRY *Link;
+ ORDERED_COLLECTION_ENTRY *Entry;
if (UserHandle == NULL) {
return EFI_INVALID_PARAMETER;
@@ -68,11 +122,9 @@ CoreValidateHandle (
ASSERT_LOCKED (&gProtocolDatabaseLock);
- for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) {
- Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
- if (Handle == (IHANDLE *)UserHandle) {
- return EFI_SUCCESS;
- }
+ Entry = OrderedCollectionFind (gOrderedHandleList, UserHandle);
+ if (Entry != NULL) {
+ return EFI_SUCCESS;
}
return EFI_INVALID_PARAMETER;
@@ -453,6 +505,16 @@ CoreInstallProtocolInterfaceNotify (
}
//
+ // Add this handle to the ordered list of all handles
+ // in the system
+ //
+ Status = OrderedCollectionInsert (gOrderedHandleList, NULL, Handle);
+ if (EFI_ERROR (Status)) {
+ CoreFreePool (Handle);
+ goto Done;
+ }
+
+ //
// Initialize new handler structure
//
Handle->Signature = EFI_HANDLE_SIGNATURE;
@@ -825,6 +887,11 @@ CoreUninstallProtocolInterface (
//
if (IsListEmpty (&Handle->Protocols)) {
Handle->Signature = 0;
+ OrderedCollectionDelete (
+ gOrderedHandleList,
+ OrderedCollectionFind (gOrderedHandleList, Handle),
+ NULL
+ );
RemoveEntryList (&Handle->AllHandles);
CoreFreePool (Handle);
}
diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c
index 37fc74d..8d12f93 100644
--- a/MdeModulePkg/Core/Dxe/Image/Image.c
+++ b/MdeModulePkg/Core/Dxe/Image/Image.c
@@ -1725,7 +1725,9 @@ CoreStartImage (
// Image has completed. Verify the tpl is the same
//
ASSERT (Image->Tpl == gEfiCurrentTpl);
- CoreRestoreTpl (Image->Tpl);
+ if (Image->Tpl != gEfiCurrentTpl) {
+ CoreRestoreTpl (Image->Tpl);
+ }
CoreFreePool (Image->JumpBuffer);
diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c
index 0c0ca61..4071053 100644
--- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c
+++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c
@@ -1406,34 +1406,39 @@ GuardAllFreedPages (
TableEntry = ((UINT64 *)(UINTN)(Tables[Level]))[Indices[Level]];
Address = Addresses[Level];
- if (Level < GUARDED_HEAP_MAP_TABLE_DEPTH - 1) {
- Level += 1;
- Tables[Level] = TableEntry;
- Addresses[Level] = Address;
- Indices[Level] = 0;
-
- continue;
+ if (TableEntry == 0) {
+ GuardPageNumber = 0;
+ GuardPage = (UINT64)-1;
} else {
- BitIndex = 1;
- while (BitIndex != 0) {
- if ((TableEntry & BitIndex) != 0) {
- if (GuardPage == (UINT64)-1) {
- GuardPage = Address;
+ if (Level < GUARDED_HEAP_MAP_TABLE_DEPTH - 1) {
+ Level += 1;
+ Tables[Level] = TableEntry;
+ Addresses[Level] = Address;
+ Indices[Level] = 0;
+
+ continue;
+ } else {
+ BitIndex = 1;
+ while (BitIndex != 0) {
+ if ((TableEntry & BitIndex) != 0) {
+ if (GuardPage == (UINT64)-1) {
+ GuardPage = Address;
+ }
+
+ ++GuardPageNumber;
+ } else if (GuardPageNumber > 0) {
+ GuardFreedPages (GuardPage, GuardPageNumber);
+ GuardPageNumber = 0;
+ GuardPage = (UINT64)-1;
}
- ++GuardPageNumber;
- } else if (GuardPageNumber > 0) {
- GuardFreedPages (GuardPage, GuardPageNumber);
- GuardPageNumber = 0;
- GuardPage = (UINT64)-1;
- }
+ if (TableEntry == 0) {
+ break;
+ }
- if (TableEntry == 0) {
- break;
+ Address += EFI_PAGES_TO_SIZE (1);
+ BitIndex = LShiftU64 (BitIndex, 1);
}
-
- Address += EFI_PAGES_TO_SIZE (1);
- BitIndex = LShiftU64 (BitIndex, 1);
}
}
}
diff --git a/MdeModulePkg/Core/Dxe/Mem/Imem.h b/MdeModulePkg/Core/Dxe/Mem/Imem.h
index 2f0bf2b..84027d6 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Imem.h
+++ b/MdeModulePkg/Core/Dxe/Mem/Imem.h
@@ -10,22 +10,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define _IMEM_H_
//
-// +---------------------------------------------------+
-// | 0..(EfiMaxMemoryType - 1) - Normal memory type |
-// +---------------------------------------------------+
-// | EfiMaxMemoryType..0x6FFFFFFF - Invalid |
-// +---------------------------------------------------+
-// | 0x70000000..0x7FFFFFFF - OEM reserved |
-// +---------------------------------------------------+
-// | 0x80000000..0xFFFFFFFF - OS reserved |
-// +---------------------------------------------------+
-//
-#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000
-#define MEMORY_TYPE_OS_RESERVED_MAX 0xFFFFFFFF
-#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000
-#define MEMORY_TYPE_OEM_RESERVED_MAX 0x7FFFFFFF
-
-//
// MEMORY_MAP_ENTRY
//
diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
index e9343a2..a11c455 100644
--- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
+++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
@@ -395,11 +395,14 @@ MergeMemoryMap (
NewMemoryMapEntry = MemoryMap;
MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize);
while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
- CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
+ CopyMem (NewMemoryMapEntry, MemoryMapEntry, DescriptorSize);
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
do {
- MergeGuardPages (NewMemoryMapEntry, NextMemoryMapEntry->PhysicalStart);
+ if ((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) {
+ MergeGuardPages (NewMemoryMapEntry, NextMemoryMapEntry->PhysicalStart);
+ }
+
MemoryBlockLength = LShiftU64 (NewMemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT);
if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&
(NewMemoryMapEntry->Type == NextMemoryMapEntry->Type) &&
@@ -426,7 +429,7 @@ MergeMemoryMap (
/**
Enforce memory map attributes.
- This function will set EfiRuntimeServicesData/EfiMemoryMappedIO/EfiMemoryMappedIOPortSpace to be EFI_MEMORY_XP.
+ This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP.
@param MemoryMap A pointer to the buffer in which firmware places
the current memory map.
@@ -447,18 +450,23 @@ EnforceMemoryMapAttribute (
MemoryMapEntry = MemoryMap;
MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
- switch (MemoryMapEntry->Type) {
- case EfiRuntimeServicesCode:
- // do nothing
- break;
- case EfiRuntimeServicesData:
- case EfiMemoryMappedIO:
- case EfiMemoryMappedIOPortSpace:
- MemoryMapEntry->Attribute |= EFI_MEMORY_XP;
- break;
- case EfiReservedMemoryType:
- case EfiACPIMemoryNVS:
- break;
+ if ((MemoryMapEntry->Attribute & EFI_MEMORY_ACCESS_MASK) == 0) {
+ switch (MemoryMapEntry->Type) {
+ case EfiRuntimeServicesCode:
+ // If at this point the attributes have not been set on an EfiRuntimeServicesCode
+ // region, the memory range must not contain a loaded image. It's possible these
+ // non-image EfiRuntimeServicesCode regions are part of the unused memory bucket.
+ // It could also be that this region was explicitly allocated outside of the PE
+ // loader but the UEFI spec requires that all EfiRuntimeServicesCode regions contain
+ // EFI modules. In either case, set the attributes to RO and XP.
+ MemoryMapEntry->Attribute |= (EFI_MEMORY_RO | EFI_MEMORY_XP);
+ break;
+ case EfiRuntimeServicesData:
+ MemoryMapEntry->Attribute |= EFI_MEMORY_XP;
+ break;
+ default:
+ break;
+ }
}
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
index 2c19f1a..933b245 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
@@ -3,7 +3,7 @@
Responsibility of this module is to load the DXE Core from a Firmware Volume.
Copyright (c) 2016 HP Development Company, L.P.
-Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -487,10 +487,10 @@ DxeIplFindDxeCore (
//
if (EFI_ERROR (Status)) {
REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT));
+ ASSERT_EFI_ERROR (Status);
+ break;
}
- ASSERT_EFI_ERROR (Status);
-
//
// Find the DxeCore file type from the beginning in this firmware volume.
//
@@ -509,6 +509,13 @@ DxeIplFindDxeCore (
//
Instance++;
}
+
+ //
+ // DxeCore cannot find in any firmware volume.
+ //
+ CpuDeadLoop ();
+
+ return NULL;
}
/**
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index ca37bde..79ff8d1 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -1205,16 +1205,21 @@ EvacuateTempRam (
PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE)SecCoreData->BootFirmwareVolumeBase;
}
- for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) {
- if (Private->Fv[FvIndex].FvHandle == PeiCoreFvHandle.FvHandle) {
- CopyMem (&PeiCoreFvHandle, &Private->Fv[FvIndex], sizeof (PEI_CORE_FV_HANDLE));
- break;
+ if (Private->PeimDispatcherReenter) {
+ //
+ // PEI_CORE should be migrated after dispatcher re-enters from main memory.
+ //
+ for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) {
+ if (Private->Fv[FvIndex].FvHandle == PeiCoreFvHandle.FvHandle) {
+ CopyMem (&PeiCoreFvHandle, &Private->Fv[FvIndex], sizeof (PEI_CORE_FV_HANDLE));
+ break;
+ }
}
- }
- Status = EFI_SUCCESS;
+ Status = EFI_SUCCESS;
- ConvertPeiCorePpiPointers (Private, &PeiCoreFvHandle);
+ ConvertPeiCorePpiPointers (Private, &PeiCoreFvHandle);
+ }
Hob.Raw = GetFirstGuidHob (&gEdkiiMigrationInfoGuid);
if (Hob.Raw != NULL) {
@@ -1237,6 +1242,14 @@ EvacuateTempRam (
)
{
if ((MigrationInfo == NULL) || (MigrationInfo->MigrateAll == TRUE)) {
+ if (!Private->PeimDispatcherReenter) {
+ //
+ // Migration before dispatcher reentery is supported only when gEdkiiMigrationInfoGuid
+ // HOB is built for selective FV migration.
+ //
+ return EFI_SUCCESS;
+ }
+
//
// Migrate all FVs and copy raw data
//
@@ -1253,10 +1266,18 @@ EvacuateTempRam (
}
}
- if (Index == MigrationInfo->ToMigrateFvCount) {
+ if ((Index == MigrationInfo->ToMigrateFvCount) ||
+ ((!Private->PeimDispatcherReenter) &&
+ (((FvMigrationFlags & FLAGS_FV_MIGRATE_BEFORE_PEI_CORE_REENTRY) == 0) ||
+ (FvHeader == PeiCoreFvHandle.FvHandle))))
+ {
//
// This FV is not expected to migrate
//
+ // FV should not be migrated before dispatcher reentry if any of the below condition is true:
+ // a. MigrationInfo HOB is not built with flag FLAGS_FV_MIGRATE_BEFORE_PEI_CORE_REENTRY.
+ // b. FV contains currently executing PEI Core.
+ //
continue;
}
}
diff --git a/MdeModulePkg/Core/Pei/FwVol/FwVol.c b/MdeModulePkg/Core/Pei/FwVol/FwVol.c
index f7cc94c..04bec98 100644
--- a/MdeModulePkg/Core/Pei/FwVol/FwVol.c
+++ b/MdeModulePkg/Core/Pei/FwVol/FwVol.c
@@ -819,6 +819,10 @@ ProcessSection (
if (!IsFfs3Fv) {
DEBUG ((DEBUG_ERROR, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));
SectionLength = SECTION2_SIZE (Section);
+ if (SectionLength == 0) {
+ break;
+ }
+
//
// SectionLength is adjusted it is 4 byte aligned.
// Go to the next section
@@ -854,6 +858,10 @@ ProcessSection (
SectionLength = SECTION_SIZE (Section);
}
+ if (SectionLength == 0) {
+ break;
+ }
+
//
// SectionLength is adjusted it is 4 byte aligned.
// Go to the next section
@@ -991,6 +999,10 @@ ProcessSection (
SectionLength = SECTION_SIZE (Section);
}
+ if (SectionLength == 0) {
+ break;
+ }
+
//
// SectionLength is adjusted it is 4 byte aligned.
// Go to the next section
diff --git a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
index 52f37c9..59613e5 100644
--- a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
+++ b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
@@ -862,8 +862,6 @@ PeiAllocatePool (
(UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),
(VOID **)&Hob
);
- ASSERT_EFI_ERROR (Status);
-
if (EFI_ERROR (Status)) {
*Buffer = NULL;
} else {
diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
index 0e3d9a8..61f5699 100644
--- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
+++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
@@ -323,6 +323,21 @@ PeiCore (
//
OldCoreData->PeiMemoryInstalled = TRUE;
+ if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {
+ DEBUG ((DEBUG_VERBOSE, "Early Migration - PPI lists before temporary RAM evacuation:\n"));
+ DumpPpiList (OldCoreData);
+
+ //
+ // Migrate installed content from Temporary RAM to Permanent RAM at this
+ // stage when PEI core still runs from a cached location.
+ // FVs that doesn't contain PEI_CORE should be migrated here.
+ //
+ EvacuateTempRam (OldCoreData, SecCoreData);
+
+ DEBUG ((DEBUG_VERBOSE, "Early Migration - PPI lists after temporary RAM evacuation:\n"));
+ DumpPpiList (OldCoreData);
+ }
+
//
// Indicate that PeiCore reenter
//
@@ -451,6 +466,7 @@ PeiCore (
//
// Migrate installed content from Temporary RAM to Permanent RAM
+ // FVs containing PEI_CORE should be migrated here.
//
EvacuateTempRam (&PrivateData, SecCoreData);
diff --git a/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c b/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c
index 27da289..e48532c 100644
--- a/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c
+++ b/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c
@@ -2,6 +2,7 @@
SMI handler profile support.
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -48,6 +49,14 @@ RegisterSmiHandlerProfileHandler (
);
/**
+ Build SMI handler profile database.
+**/
+VOID
+BuildSmiHandlerProfileDatabase (
+ VOID
+ );
+
+/**
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.
@@ -495,6 +504,8 @@ SmmReadyToLockInSmiHandlerProfile (
IN EFI_HANDLE Handle
)
{
+ RegisterSmiHandlerProfileHandler ();
+
//
// Dump all image
//
@@ -528,7 +539,7 @@ SmmReadyToLockInSmiHandlerProfile (
DEBUG ((DEBUG_INFO, "\n"));
- RegisterSmiHandlerProfileHandler ();
+ BuildSmiHandlerProfileDatabase ();
if (mImageStruct != NULL) {
FreePool (mImageStruct);
@@ -860,7 +871,7 @@ GetSmiHandlerProfileDatabaseData (
}
/**
- build SMI handler profile database.
+ Build SMI handler profile database.
**/
VOID
BuildSmiHandlerProfileDatabase (
@@ -1074,8 +1085,6 @@ RegisterSmiHandlerProfileHandler (
&DispatchHandle
);
ASSERT_EFI_ERROR (Status);
-
- BuildSmiHandlerProfileDatabase ();
}
/**
diff --git a/MdeModulePkg/Include/Guid/MigratedFvInfo.h b/MdeModulePkg/Include/Guid/MigratedFvInfo.h
index 255e278..99681fb 100644
--- a/MdeModulePkg/Include/Guid/MigratedFvInfo.h
+++ b/MdeModulePkg/Include/Guid/MigratedFvInfo.h
@@ -18,7 +18,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
// 1: FV raw data will be copied to permanent memory for later phase use (such as
// FV measurement).
//
-#define FLAGS_FV_RAW_DATA_COPY BIT0
+#define FLAGS_FV_RAW_DATA_COPY BIT0
+#define FLAGS_FV_MIGRATE_BEFORE_PEI_CORE_REENTRY BIT1
///
/// In real use cases, not all FVs need migrate to permanent memory before TempRam tears
diff --git a/MdeModulePkg/Include/Guid/MmCommBuffer.h b/MdeModulePkg/Include/Guid/MmCommBuffer.h
new file mode 100644
index 0000000..df4ea31
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/MmCommBuffer.h
@@ -0,0 +1,63 @@
+/** @file
+ MM Communication buffer data.
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_COMM_BUFFER_H_
+#define MM_COMM_BUFFER_H_
+
+///
+/// The GUID of the MM Communication buffer HOB.
+///
+#define MM_COMM_BUFFER_HOB_GUID \
+ { 0x6c2a2520, 0x0131, 0x4aee, { 0xa7, 0x50, 0xcc, 0x38, 0x4a, 0xac, 0xe8, 0xc6 }}
+
+///
+/// The MM communicate buffer facilitates data sharing between non-MM and MM code.
+/// The MM IPL code allocates a "fixed" runtime type memory as the MM communication buffer,
+/// and communicates its address and size to MM Core via MmCommBuffer GUIDed HOB.
+/// Here, "fixed" implies that the buffer's location remains constant throughout the boot process.
+/// Data is exchanged between the MM Communication PPI/Protocol and a software MMI handler
+/// using this fixed MM communication buffer.
+///
+typedef struct {
+ ///
+ /// The address of the 4-KiB aligned fixed MM communication buffer.
+ ///
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+
+ ///
+ /// Size of the fixed MM communication buffer, in 4KiB pages.
+ ///
+ UINT64 NumberOfPages;
+
+ ///
+ /// Point to MM_COMM_BUFFER_STATUS structure.
+ ///
+ EFI_PHYSICAL_ADDRESS Status;
+} MM_COMM_BUFFER;
+
+typedef struct {
+ ///
+ /// Whether the data in the fixed MM communication buffer is valid when entering from non-MM to MM.
+ ///
+ BOOLEAN IsCommBufferValid;
+
+ ///
+ /// The return status when returning from MM to non-MM.
+ ///
+ UINT64 ReturnStatus;
+
+ ///
+ /// The size in bytes of the output buffer when returning from MM to non-MM.
+ ///
+ UINT64 ReturnBufferSize;
+} MM_COMM_BUFFER_STATUS;
+
+extern EFI_GUID gMmCommBufferHobGuid;
+
+#endif
diff --git a/MdeModulePkg/Include/Guid/NVMeEventGroup.h b/MdeModulePkg/Include/Guid/NVMeEventGroup.h
new file mode 100644
index 0000000..bd59b0c
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/NVMeEventGroup.h
@@ -0,0 +1,16 @@
+/** @file
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef NVME_EVENT_GROUP_GUID_
+#define NVME_EVENT_GROUP_GUID_
+
+// gNVMeEnableStartEventGroupGuid is used to signal the start of enabling the NVMe controller
+extern EFI_GUID gNVMeEnableStartEventGroupGuid;
+// gNVMeEnableCompleteEventGroupGuid is used to signal that the NVMe controller enable has finished
+extern EFI_GUID gNVMeEnableCompleteEventGroupGuid;
+
+#endif
diff --git a/MdeModulePkg/Include/Library/HobPrintLib.h b/MdeModulePkg/Include/Library/HobPrintLib.h
new file mode 100644
index 0000000..40bb035
--- /dev/null
+++ b/MdeModulePkg/Include/Library/HobPrintLib.h
@@ -0,0 +1,46 @@
+/** @file
+ The library to print all the HOBs.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef HOB_PRINT_LIB_H_
+#define HOB_PRINT_LIB_H_
+
+/**
+ HOB Print Handler to print HOB information.
+
+ @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_GUID_EXTENSION.
+ @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_GUID_EXTENSION.
+
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval EFI_UNSUPPORTED If the HOB type is not supported.
+
+**/
+typedef
+EFI_STATUS
+(*HOB_PRINT_HANDLER)(
+ IN VOID *Hob,
+ IN UINT16 HobLength
+ );
+
+/**
+ Print all HOBs info from the HOB list.
+ If the input PrintHandler is not NULL, the PrintHandler will be processed first.
+ If PrintHandler returns EFI_SUCCESS, default HOB info print logic in PrintHobList
+ will be skipped.
+
+ @param[in] HobStart A pointer to the HOB list.
+ @param[in] PrintHandler A custom handler to print HOB info.
+
+**/
+VOID
+EFIAPI
+PrintHobList (
+ IN CONST VOID *HobStart,
+ IN HOB_PRINT_HANDLER PrintHandler OPTIONAL
+ );
+
+#endif
diff --git a/MdeModulePkg/Include/Protocol/MediaSanitize.h b/MdeModulePkg/Include/Protocol/MediaSanitize.h
new file mode 100644
index 0000000..029b135
--- /dev/null
+++ b/MdeModulePkg/Include/Protocol/MediaSanitize.h
@@ -0,0 +1,173 @@
+/** @file
+ This file defines the Media Sanitize Protocol.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MEDIA_SANITIZE_PROTOCOL_H_
+#define MEDIA_SANITIZE_PROTOCOL_H_
+
+#define MEDIA_SANITIZE_PROTOCOL_GUID \
+ { \
+ 0x0d799a99, 0x25af, 0x429e, { 0x92, 0x72, 0xd0, 0xb2, 0x7d, 0x6d, 0x5f, 0x14 } \
+ }
+
+typedef struct _MEDIA_SANITIZE_PROTOCOL MEDIA_SANITIZE_PROTOCOL;
+
+#define MEDIA_SANITIZE_PROTOCOL_REVISION 0x00010000
+
+///
+/// Sanitize actions for purge operation.
+///
+/// NOTE: First four actions (no action, overwrite, block erase, crypto erase) cannot
+/// be overlapped. All other fields may be overlapped as they apply.
+///
+#define PURGE_ACTION_NO_ACTION 0x00000000 // No purge action requested
+#define PURGE_ACTION_OVERWRITE 0x00000001 // Overwrite with 32-bit pattern
+#define PURGE_ACTION_BLOCK_ERASE 0x00000002 // Erase Blocks with indeterminate pattern
+#define PURGE_ACTION_CRYPTO_ERASE 0x00000004 // Delete encryption keys only
+#define PURGE_ACTION_RESET_REQUIRED 0x00000008 // Reset required after purge
+#define PURGE_ACTION_NO_DEALLOCATE 0x00000010 // Do no deallocate (trim) flash medai after sanitize
+#define PURGE_ACTION_INVERT_OW_PATTERN 0x00000020 // Invert overwrite pattern between passes
+#define PURGE_ACTION_ALLOW_UNRESTRICTED_SANITIZE_EXIT 0x00000040 // Allow exit without restrictions
+
+///
+/// Secure erase action for media format operation
+///
+#define FORMAT_SES_NO_SECURE_ERASE_REQUESTED 0x0 // No secure erase operation requested
+#define FORMAT_SES_USER_DATA_ERASE 0x1 // User Data Erase
+#define FORMAT_SES_CRYPTOGRAPHIC_ERASE 0x2 // Cryptographic Erase
+
+/**
+ Clear Media utilizes transport native WRITE commands to write a fixed pattern
+ of non-sensitive data. The size of the overwrite buffer shall be equal to the
+ one sector/LBA (in bytes).
+
+ NOTE: This function must be called from TPL aaplication or callback.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId The media ID that the clear request is for.
+ @param[in] PassCount Number of passes to write over the media.
+ @param[in] SectorOwBuffer Pointer to overwrite pattern buffer.
+
+ @retval EFI_SUCCESS The media clear request completed successfully
+ on the device.
+ @retval EFI_WRITE_PROTECTED The device can't be cleared due to write
+ protection.
+ @retval EFI_DEVICE_ERROR The device reported an error while attempting
+ to perform the clear operation.
+ @retval EFI_INVALID_PARAMETER The clear request contains parameters that
+ are not valid.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *BLOCK_MEDIA_CLEAR)(
+ IN MEDIA_SANITIZE_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT32 PassCount,
+ IN VOID *SectorOwBuffer
+ );
+
+/**
+ Purge Media utilizes native Sanitize operations. Transport specific
+ overwrite, block erase, or crypto erase functions shall be invoked based
+ on transport.
+
+ NOTE: This function must be called from TPL aaplication or callback.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId The media ID that the clear request is for.
+ @param[in] PurgeAction Purge action: overwrite, crypto or block erase.
+ @param[in] OverwritePattern 32-bit pattern to overwrite on media.
+
+ @retval EFI_SUCCESS The media purge request completed successfully
+ on the device.
+ @retval EFI_WRITE_PROTECTED The device can't be purged due to write
+ protection.
+ @retval EFI_DEVICE_ERROR The device reported an error while attempting
+ to perform the purge operation.
+ @retval EFI_INVALID_PARAMETER The purge request contains parameters that
+ are not valid.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *BLOCK_MEDIA_PURGE)(
+ IN MEDIA_SANITIZE_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT32 PurgeAction,
+ IN UINT32 OverwritePattern
+ );
+
+/**
+ Format Media utilizes native format operations to modify sector/LBA size.
+ Secure erase actions are used to define how latent user data is erased.
+
+ NOTE: This function must be called from TPL aaplication or callback.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId The media ID that the clear request is for.
+ @param[in] LbaSize Size of LBA (in terms of power of two: 2^n).
+ @param[in] SecureEraseAction Secure erase action, if any, to apply to format.
+
+ @retval EFI_SUCCESS The media format request comopleted
+ successfully on the device.
+ @retval EFI_WRITE_PROTECTED The device can't be formatted due to write
+ protection.
+ @retval EFI_DEVICE_ERROR The device reported an error while attempting
+ to perform the format operation.
+ @retval EFI_INVALID_PARAMETER The format request contains parameters that
+ are not valid.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
+
+ **/
+typedef
+EFI_STATUS
+(EFIAPI *BLOCK_MEDIA_FORMAT)(
+ IN MEDIA_SANITIZE_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT32 LbaSize,
+ IN UINT32 SecureEraseAction
+ );
+
+///
+/// The Media Sanitize Protocol provides the ability for a device to expose
+/// sanitize functionality. This optional protocol is installed on the same handle
+/// as the EFI_BLOCK_IO_PROTOCOL or EFI_BLOCK_IO2_PROTOCOL.
+///
+struct _MEDIA_SANITIZE_PROTOCOL {
+ ///
+ /// The revision to which the MEDIA_SANITIZE_PROTOCOL adheres. All future
+ /// revisions must be backwards compatible. If a future version is not
+ /// backwards compatible, it is not the same GUID.
+ ///
+ UINT64 Revision;
+
+ ///
+ /// A pointer to the EFI_BLOCK_IO_MEDIA data for this device.
+ /// Type EFI_BLOCK_IO_MEDIA is defined in BlockIo.h.
+ ///
+ EFI_BLOCK_IO_MEDIA *Media;
+
+ ///
+ /// SanitizeCapabilities shall which sanitize operations (crypto erase, block
+ /// erase, overwrite) is supported by this Block Io device.
+ ///
+ UINT32 SanitizeCapabilities;
+
+ BLOCK_MEDIA_CLEAR MediaClear;
+ BLOCK_MEDIA_PURGE MediaPurge;
+ BLOCK_MEDIA_FORMAT MediaFormat;
+};
+
+extern EFI_GUID gMediaSanitizeProtocolGuid;
+
+#endif
diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
index 8befbae..edf9276 100644
--- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
+++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
@@ -10,7 +10,7 @@
ValidateFmpCapsule(), and DisplayCapsuleImage() receives untrusted input and
performs basic validation.
- Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -49,7 +49,7 @@ EFI_EVENT mDxeCapsuleLibEndOfDxeEvent = NULL;
EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL *mFmpProgress = NULL;
-BOOLEAN mDxeCapsuleLibReadyToBootEvent = FALSE;
+BOOLEAN mDxeCapsuleLibIsExitBootService = FALSE;
/**
Initialize capsule related variables.
@@ -1396,25 +1396,17 @@ IsNestedFmpCapsule (
EFI_SYSTEM_RESOURCE_ENTRY Entry;
EsrtGuidFound = FALSE;
- if (mEsrtTable != NULL) {
- EsrtEntry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mEsrtTable + 1);
- for (Index = 0; Index < mEsrtTable->FwResourceCount; Index++, EsrtEntry++) {
- if (CompareGuid (&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {
- EsrtGuidFound = TRUE;
- break;
+ if (mDxeCapsuleLibIsExitBootService) {
+ if (mEsrtTable != NULL) {
+ EsrtEntry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mEsrtTable + 1);
+ for (Index = 0; Index < mEsrtTable->FwResourceCount; Index++, EsrtEntry++) {
+ if (CompareGuid (&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {
+ EsrtGuidFound = TRUE;
+ break;
+ }
}
}
} else {
- if (mDxeCapsuleLibReadyToBootEvent) {
- //
- // The ESRT table (mEsrtTable) in the Configuration Table would be located
- // at the ReadyToBoot event if it exists. Hence, it should return here to
- // avoid a crash due to calling gBS->LocateProtocol () at runtime in case
- // there is no ERST table installed.
- //
- return FALSE;
- }
-
//
// Check ESRT protocol
//
diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c
index 855b7a6..34dc595 100644
--- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c
+++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c
@@ -1,7 +1,7 @@
/** @file
Capsule library runtime support.
- Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -22,9 +22,10 @@
#include <Library/MemoryAllocationLib.h>
extern EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable;
+extern BOOLEAN mDxeCapsuleLibIsExitBootService;
EFI_EVENT mDxeRuntimeCapsuleLibVirtualAddressChangeEvent = NULL;
-EFI_EVENT mDxeRuntimeCapsuleLibReadyToBootEvent = NULL;
-extern BOOLEAN mDxeCapsuleLibReadyToBootEvent;
+EFI_EVENT mDxeRuntimeCapsuleLibSystemResourceTableEvent = NULL;
+EFI_EVENT mDxeRuntimeCapsuleLibExitBootServiceEvent = NULL;
/**
Convert EsrtTable physical address to virtual address.
@@ -44,16 +45,16 @@ DxeCapsuleLibVirtualAddressChangeEvent (
}
/**
- Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT.
+ Notify function for event of system resource table installation.
- @param[in] Event The Event that is being processed.
- @param[in] Context The Event Context.
+ @param[in] Event The Event that is being processed.
+ @param[in] Context The Event Context.
**/
STATIC
VOID
EFIAPI
-DxeCapsuleLibReadyToBootEventNotify (
+DxeCapsuleLibSystemResourceTableInstallEventNotify (
IN EFI_EVENT Event,
IN VOID *Context
)
@@ -79,6 +80,14 @@ DxeCapsuleLibReadyToBootEventNotify (
//
if (Index < gST->NumberOfTableEntries) {
//
+ // Free the pool to remove the cached ESRT table.
+ //
+ if (mEsrtTable != NULL) {
+ FreePool ((VOID *)mEsrtTable);
+ mEsrtTable = NULL;
+ }
+
+ //
// Search Esrt to check given capsule is qualified
//
EsrtTable = (EFI_SYSTEM_RESOURCE_TABLE *)ConfigEntry->VendorTable;
@@ -95,12 +104,28 @@ DxeCapsuleLibReadyToBootEventNotify (
//
mEsrtTable->FwResourceCountMax = mEsrtTable->FwResourceCount;
}
+}
+
+/**
+ Notify function for event of exit boot service.
+
+ @param[in] Event The Event that is being processed.
+ @param[in] Context The Event Context.
- mDxeCapsuleLibReadyToBootEvent = TRUE;
+**/
+STATIC
+VOID
+EFIAPI
+DxeCapsuleLibExitBootServiceEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ mDxeCapsuleLibIsExitBootService = TRUE;
}
/**
- The constructor function hook VirtualAddressChange event to use ESRT table as capsule routing table.
+ The constructor function for the file of DxeCapsuleRuntime.
@param ImageHandle The firmware allocated handle for the EFI image.
@param SystemTable A pointer to the EFI System Table.
@@ -130,15 +155,28 @@ DxeRuntimeCapsuleLibConstructor (
ASSERT_EFI_ERROR (Status);
//
- // Register notify function to cache the FMP capsule GUIDs at ReadyToBoot.
+ // Register notify function to cache the FMP capsule GUIDs when system resource table installed.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ DxeCapsuleLibSystemResourceTableInstallEventNotify,
+ NULL,
+ &gEfiSystemResourceTableGuid,
+ &mDxeRuntimeCapsuleLibSystemResourceTableEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register notify function to indicate the event is signaled at ExitBootService.
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
- DxeCapsuleLibReadyToBootEventNotify,
+ DxeCapsuleLibExitBootServiceEventNotify,
NULL,
- &gEfiEventReadyToBootGuid,
- &mDxeRuntimeCapsuleLibReadyToBootEvent
+ &gEfiEventExitBootServicesGuid,
+ &mDxeRuntimeCapsuleLibExitBootServiceEvent
);
ASSERT_EFI_ERROR (Status);
@@ -146,7 +184,7 @@ DxeRuntimeCapsuleLibConstructor (
}
/**
- The destructor function closes the VirtualAddressChange event.
+ The destructor function for the file of DxeCapsuleRuntime.
@param ImageHandle The firmware allocated handle for the EFI image.
@param SystemTable A pointer to the EFI System Table.
@@ -169,9 +207,15 @@ DxeRuntimeCapsuleLibDestructor (
ASSERT_EFI_ERROR (Status);
//
- // Close the ReadyToBoot event.
+ // Close the system resource table installed event.
+ //
+ Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibSystemResourceTableEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Close the ExitBootService event.
//
- Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibReadyToBootEvent);
+ Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibExitBootServiceEvent);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
index bf56f46..ef1fa57 100644
--- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
+++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
@@ -3,7 +3,7 @@
#
# Capsule library instance for DXE_RUNTIME_DRIVER module types.
#
-# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -66,7 +66,7 @@
gEfiCapsuleReportGuid
gEfiCapsuleVendorGuid ## SOMETIMES_CONSUMES ## Variable:L"CapsuleUpdateData"
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
- gEfiEventReadyToBootGuid ## CONSUMES ## Event
+ gEfiEventExitBootServicesGuid ## CONSUMES ## Event
gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event
gEdkiiCapsuleOnDiskNameGuid ## SOMETIMES_CONSUMES ## GUID
diff --git a/MdeModulePkg/Library/HobPrintLib/HobPrintLib.c b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.c
new file mode 100644
index 0000000..d2fa92e
--- /dev/null
+++ b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.c
@@ -0,0 +1,469 @@
+/** @file
+ Prints all the HOBs.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Pi/PiMultiPhase.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/HobPrintLib.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/MemoryAllocationHob.h>
+
+#define ROW_LIMITER 16
+
+typedef struct {
+ UINT16 Type;
+ CHAR8 *Name;
+ HOB_PRINT_HANDLER PrintHandler;
+} HOB_PRINT_HANDLER_TABLE;
+
+CHAR8 *mMemoryTypeStr[] = {
+ "EfiReservedMemoryType",
+ "EfiLoaderCode",
+ "EfiLoaderData",
+ "EfiBootServicesCode",
+ "EfiBootServicesData",
+ "EfiRuntimeServicesCode",
+ "EfiRuntimeServicesData",
+ "EfiConventionalMemory",
+ "EfiUnusableMemory",
+ "EfiACPIReclaimMemory",
+ "EfiACPIMemoryNVS",
+ "EfiMemoryMappedIO",
+ "EfiMemoryMappedIOPortSpace",
+ "EfiPalCode",
+ "EfiPersistentMemory",
+ "EfiMaxMemoryType"
+};
+
+CHAR8 *mResource_Type_List[] = {
+ "EFI_RESOURCE_SYSTEM_MEMORY ", // 0x00000000
+ "EFI_RESOURCE_MEMORY_MAPPED_IO ", // 0x00000001
+ "EFI_RESOURCE_IO ", // 0x00000002
+ "EFI_RESOURCE_FIRMWARE_DEVICE ", // 0x00000003
+ "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT ", // 0x00000004
+ "EFI_RESOURCE_MEMORY_RESERVED ", // 0x00000005
+ "EFI_RESOURCE_IO_RESERVED ", // 0x00000006
+ "EFI_RESOURCE_MAX_MEMORY_TYPE " // 0x00000007
+};
+
+/**
+ Print the Hex value of a given range.
+
+ @param[in] ErrorLevel Error Level to print the Hex value.
+ @param[in] DataStart A pointer to the start of data to be printed.
+ @param[in] DataSize The length of the data to be printed.
+
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintHex (
+ IN UINT32 ErrorLevel,
+ IN UINT8 *DataStart,
+ IN UINT16 DataSize
+ )
+{
+ UINTN Index1;
+ UINTN Index2;
+ UINT8 *StartAddr;
+
+ StartAddr = DataStart;
+ for (Index1 = 0; Index1 * ROW_LIMITER < DataSize; Index1++) {
+ DEBUG ((ErrorLevel, " 0x%04p:", (DataStart - StartAddr)));
+ for (Index2 = 0; (Index2 < ROW_LIMITER) && (Index1 * ROW_LIMITER + Index2 < DataSize); Index2++) {
+ DEBUG ((ErrorLevel, " %02x", *DataStart));
+ DataStart++;
+ }
+
+ DEBUG ((ErrorLevel, "\n"));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Print the Hex value of the Invalid HOB.
+
+ @param[in] HobStart A pointer to the Invalid HOB.
+ @param[in] HobLength The length in bytes of the Invalid HOB.
+
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintInvalidHob (
+ IN VOID *HobStart,
+ IN UINT16 HobLength
+ )
+{
+ DEBUG ((DEBUG_ERROR, " Invalid HOB. Full hex dump in below:\n"));
+ PrintHex (DEBUG_ERROR, HobStart, HobLength);
+ return RETURN_INVALID_PARAMETER;
+}
+
+/**
+ Print the information in HandOffHob.
+
+ @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_HANDOFF.
+ @param[in] HobLength The length in bytes of HOB of type EFI_HOB_TYPE_HANDOFF.
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintHandOffHob (
+ IN VOID *HobStart,
+ IN UINT16 HobLength
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = (UINT8 *)HobStart;
+ if (HobLength < sizeof (*Hob.HandoffInformationTable)) {
+ return PrintInvalidHob (HobStart, HobLength);
+ }
+
+ DEBUG ((DEBUG_INFO, " BootMode = 0x%x\n", Hob.HandoffInformationTable->BootMode));
+ DEBUG ((DEBUG_INFO, " EfiMemoryTop = 0x%lx\n", Hob.HandoffInformationTable->EfiMemoryTop));
+ DEBUG ((DEBUG_INFO, " EfiMemoryBottom = 0x%lx\n", Hob.HandoffInformationTable->EfiMemoryBottom));
+ DEBUG ((DEBUG_INFO, " EfiFreeMemoryTop = 0x%lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop));
+ DEBUG ((DEBUG_INFO, " EfiFreeMemoryBottom = 0x%lx\n", Hob.HandoffInformationTable->EfiFreeMemoryBottom));
+ DEBUG ((DEBUG_INFO, " EfiEndOfHobList = 0x%lx\n", Hob.HandoffInformationTable->EfiEndOfHobList));
+ return EFI_SUCCESS;
+}
+
+/**
+ Print the information in Memory Allocation Hob.
+ @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_MEMORY_ALLOCATION.
+ @param[in] HobLength The length in bytes of HOB of type EFI_HOB_TYPE_MEMORY_ALLOCATION.
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintMemoryAllocationHob (
+ IN VOID *HobStart,
+ IN UINT16 HobLength
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = (UINT8 *)HobStart;
+
+ if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocStackGuid)) {
+ if (HobLength < sizeof (*Hob.MemoryAllocationStack)) {
+ return PrintInvalidHob (HobStart, HobLength);
+ }
+
+ DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_STACK\n"));
+ } else if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocBspStoreGuid)) {
+ if (HobLength < sizeof (*Hob.MemoryAllocationBspStore)) {
+ return PrintInvalidHob (HobStart, HobLength);
+ }
+
+ DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_BSP_STORE\n"));
+ } else if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocModuleGuid)) {
+ if (HobLength < sizeof (*Hob.MemoryAllocationModule)) {
+ return PrintInvalidHob (HobStart, HobLength);
+ }
+
+ DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_MODULE\n"));
+ DEBUG ((DEBUG_INFO, " ModuleName = %g\n", &Hob.MemoryAllocationModule->ModuleName));
+ DEBUG ((DEBUG_INFO, " EntryPoint = 0x%lx\n", Hob.MemoryAllocationModule->EntryPoint));
+ } else {
+ if (HobLength < sizeof (*Hob.MemoryAllocation)) {
+ return PrintInvalidHob (HobStart, HobLength);
+ }
+
+ DEBUG ((DEBUG_INFO, " Type = EFI_HOB_TYPE_MEMORY_ALLOCATION\n"));
+ }
+
+ DEBUG ((DEBUG_INFO, " Name = %g\n", &Hob.MemoryAllocationStack->AllocDescriptor.Name));
+ DEBUG ((DEBUG_INFO, " MemoryBaseAddress = 0x%lx\n", Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress));
+ DEBUG ((DEBUG_INFO, " MemoryLength = 0x%lx\n", Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength));
+ DEBUG ((DEBUG_INFO, " MemoryType = %a \n", mMemoryTypeStr[Hob.MemoryAllocationStack->AllocDescriptor.MemoryType]));
+ return EFI_SUCCESS;
+}
+
+/**
+ Print the information in Resource Discriptor Hob.
+ @param[in] HobStart A pointer to HOB of type EFI_HOB_TYPE_RESOURCE_DESCRIPTOR.
+ @param[in] HobLength The Length in bytes of HOB of type EFI_HOB_TYPE_RESOURCE_DESCRIPTOR.
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintResourceDiscriptorHob (
+ IN VOID *HobStart,
+ IN UINT16 HobLength
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = (UINT8 *)HobStart;
+ ASSERT (HobLength >= sizeof (*Hob.ResourceDescriptor));
+
+ DEBUG ((DEBUG_INFO, " ResourceType = %a\n", mResource_Type_List[Hob.ResourceDescriptor->ResourceType]));
+ if (!IsZeroGuid (&Hob.ResourceDescriptor->Owner)) {
+ DEBUG ((DEBUG_INFO, " Owner = %g\n", &Hob.ResourceDescriptor->Owner));
+ }
+
+ DEBUG ((DEBUG_INFO, " ResourceAttribute = 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
+ DEBUG ((DEBUG_INFO, " PhysicalStart = 0x%lx\n", Hob.ResourceDescriptor->PhysicalStart));
+ DEBUG ((DEBUG_INFO, " ResourceLength = 0x%lx\n", Hob.ResourceDescriptor->ResourceLength));
+ return EFI_SUCCESS;
+}
+
+/**
+ Print the Guid Hob using related print handle function.
+ @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_GUID_EXTENSION.
+ @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_GUID_EXTENSION.
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintGuidHob (
+ IN VOID *HobStart,
+ IN UINT16 HobLength
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINT16 DataLength;
+
+ Hob.Raw = (UINT8 *)HobStart;
+ ASSERT (HobLength >= sizeof (*Hob.Guid));
+
+ DataLength = GET_GUID_HOB_DATA_SIZE (Hob.Raw);
+
+ DEBUG ((DEBUG_INFO, " Name = %g\n", &Hob.Guid->Name));
+ DEBUG ((DEBUG_INFO, " DataLength = 0x%x\n", DataLength));
+ PrintHex (DEBUG_VERBOSE, GET_GUID_HOB_DATA (Hob.Raw), DataLength);
+ return EFI_SUCCESS;
+}
+
+/**
+ Print the information in FV Hob.
+ @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV.
+ @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV.
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintFvHob (
+ IN VOID *HobStart,
+ IN UINT16 HobLength
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = (UINT8 *)HobStart;
+ ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume));
+
+ DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume->BaseAddress));
+ DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume->Length));
+ return EFI_SUCCESS;
+}
+
+/**
+ Print the information in Cpu Hob.
+ @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_CPU.
+ @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_CPU.
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintCpuHob (
+ IN VOID *HobStart,
+ IN UINT16 HobLength
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = (UINT8 *)HobStart;
+ ASSERT (HobLength >= sizeof (*Hob.Cpu));
+
+ DEBUG ((DEBUG_INFO, " SizeOfMemorySpace = 0x%lx\n", Hob.Cpu->SizeOfMemorySpace));
+ DEBUG ((DEBUG_INFO, " SizeOfIoSpace = 0x%lx\n", Hob.Cpu->SizeOfIoSpace));
+ return EFI_SUCCESS;
+}
+
+/**
+ Print the information in MemoryPoolHob.
+ @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_MEMORY_POOL.
+ @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_MEMORY_POOL.
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintMemoryPoolHob (
+ IN VOID *HobStart,
+ IN UINT16 HobLength
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINT16 AllocationSize;
+
+ Hob.Raw = (UINT8 *)HobStart;
+ ASSERT (HobLength >= sizeof (*Hob.Pool));
+
+ AllocationSize = HobLength - sizeof (EFI_HOB_GENERIC_HEADER);
+ DEBUG ((DEBUG_INFO, " AllocationSize = 0x%lx\n", AllocationSize));
+
+ PrintHex (DEBUG_VERBOSE, Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER), AllocationSize);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Print the information in Fv2Hob.
+ @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV2.
+ @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV2.
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintFv2Hob (
+ IN VOID *HobStart,
+ IN UINT16 HobLength
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = (UINT8 *)HobStart;
+ ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume2));
+
+ DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume2->BaseAddress));
+ DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume2->Length));
+ DEBUG ((DEBUG_INFO, " FvName = %g\n", &Hob.FirmwareVolume2->FvName));
+ DEBUG ((DEBUG_INFO, " FileName = %g\n", &Hob.FirmwareVolume2->FileName));
+ return EFI_SUCCESS;
+}
+
+/**
+ Print the information in Capsule Hob.
+ @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_UEFI_CAPSULE.
+ @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_UEFI_CAPSULE.
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintCapsuleHob (
+ IN VOID *HobStart,
+ IN UINT16 HobLength
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = (UINT8 *)HobStart;
+ ASSERT (HobLength >= sizeof (*Hob.Capsule));
+
+ DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.Capsule->BaseAddress));
+ DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.Capsule->Length));
+ return EFI_SUCCESS;
+}
+
+/**
+ Print the information in Fv3 Hob.
+ @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV3.
+ @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV3.
+ @retval EFI_SUCCESS If it completed successfully.
+**/
+EFI_STATUS
+PrintFv3Hob (
+ IN VOID *HobStart,
+ IN UINT16 HobLength
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = (UINT8 *)HobStart;
+ ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume3));
+
+ DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume3->BaseAddress));
+ DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume3->Length));
+ DEBUG ((DEBUG_INFO, " AuthenticationStatus = 0x%x\n", Hob.FirmwareVolume3->AuthenticationStatus));
+ DEBUG ((DEBUG_INFO, " ExtractedFv = %a\n", (Hob.FirmwareVolume3->ExtractedFv ? "True" : "False")));
+ DEBUG ((DEBUG_INFO, " FvName = %g\n", &Hob.FirmwareVolume3->FvName));
+ DEBUG ((DEBUG_INFO, " FileName = %g\n", &Hob.FirmwareVolume3->FileName));
+ return EFI_SUCCESS;
+}
+
+//
+// Mapping table from Hob type to Hob print function.
+//
+HOB_PRINT_HANDLER_TABLE mHobHandles[] = {
+ { EFI_HOB_TYPE_HANDOFF, "EFI_HOB_TYPE_HANDOFF", PrintHandOffHob },
+ { EFI_HOB_TYPE_MEMORY_ALLOCATION, "EFI_HOB_TYPE_MEMORY_ALLOCATION", PrintMemoryAllocationHob },
+ { EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR", PrintResourceDiscriptorHob },
+ { EFI_HOB_TYPE_GUID_EXTENSION, "EFI_HOB_TYPE_GUID_EXTENSION", PrintGuidHob },
+ { EFI_HOB_TYPE_FV, "EFI_HOB_TYPE_FV", PrintFvHob },
+ { EFI_HOB_TYPE_CPU, "EFI_HOB_TYPE_CPU", PrintCpuHob },
+ { EFI_HOB_TYPE_MEMORY_POOL, "EFI_HOB_TYPE_MEMORY_POOL", PrintMemoryPoolHob },
+ { EFI_HOB_TYPE_FV2, "EFI_HOB_TYPE_FV2", PrintFv2Hob },
+ { EFI_HOB_TYPE_UEFI_CAPSULE, "EFI_HOB_TYPE_UEFI_CAPSULE", PrintCapsuleHob },
+ { EFI_HOB_TYPE_FV3, "EFI_HOB_TYPE_FV3", PrintFv3Hob }
+};
+
+/**
+ Print all HOBs info from the HOB list.
+
+ @param[in] HobStart A pointer to the HOB list.
+ @param[in] PrintHandler A custom handler to print HOB info.
+
+**/
+VOID
+EFIAPI
+PrintHobList (
+ IN CONST VOID *HobStart,
+ IN HOB_PRINT_HANDLER PrintHandler
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ UINTN Count;
+ UINTN Index;
+
+ ASSERT (HobStart != NULL);
+
+ Hob.Raw = (UINT8 *)HobStart;
+ DEBUG ((DEBUG_INFO, "Print all Hob information from Hob 0x%p\n", Hob.Raw));
+
+ Status = EFI_SUCCESS;
+ Count = 0;
+ //
+ // Parse the HOB list to see which type it is, and print the information.
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ //
+ // Print HOB generic information
+ //
+ for (Index = 0; Index < ARRAY_SIZE (mHobHandles); Index++) {
+ if (Hob.Header->HobType == mHobHandles[Index].Type) {
+ DEBUG ((DEBUG_INFO, "HOB[%d]: Type = %a, Offset = 0x%p, Length = 0x%x\n", Count, mHobHandles[Index].Name, (Hob.Raw - (UINT8 *)HobStart), Hob.Header->HobLength));
+ break;
+ }
+ }
+
+ if (Index == ARRAY_SIZE (mHobHandles)) {
+ DEBUG ((DEBUG_INFO, "HOB[%d]: Type = %d, Offset = 0x%p, Length = 0x%x\n", Count, Hob.Header->HobType, (Hob.Raw - (UINT8 *)HobStart), Hob.Header->HobLength));
+ }
+
+ //
+ // Process custom HOB print handler first
+ //
+ if (PrintHandler != NULL) {
+ Status = PrintHandler (Hob.Raw, Hob.Header->HobLength);
+ }
+
+ //
+ // Process internal HOB print handler
+ //
+ if ((PrintHandler == NULL) || EFI_ERROR (Status)) {
+ if (Index < ARRAY_SIZE (mHobHandles)) {
+ mHobHandles[Index].PrintHandler (Hob.Raw, Hob.Header->HobLength);
+ } else {
+ DEBUG ((DEBUG_INFO, " Unkown Hob type, full hex dump in below:\n"));
+ PrintHex (DEBUG_INFO, Hob.Raw, Hob.Header->HobLength);
+ }
+ }
+
+ Count++;
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ DEBUG ((DEBUG_INFO, "There are totally %d Hobs, the End Hob address is %p\n", Count, Hob.Raw));
+}
diff --git a/MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf
new file mode 100644
index 0000000..a88cabf
--- /dev/null
+++ b/MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf
@@ -0,0 +1,34 @@
+## @file
+# Library class that prints all HOBs.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = HobPrintLib
+ FILE_GUID = 6b6f69c4-4272-4e8f-9c7f-747e7eed3ba8
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = HobPrintLib
+
+[Sources]
+ HobPrintLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ HobLib
+
+[Guids]
+ gEfiHobMemoryAllocBspStoreGuid
+ gEfiHobMemoryAllocStackGuid
+ gEfiMemoryTypeInformationGuid
diff --git a/MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.c b/MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.c
index 59b5c2b..8e9f632 100644
--- a/MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.c
+++ b/MdeModulePkg/Library/RuntimeResetSystemLib/RuntimeResetSystemLib.c
@@ -12,8 +12,8 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugLib.h>
-EFI_EVENT mRuntimeResetSystemLibVirtualAddressChangeEvent;
-EFI_RUNTIME_SERVICES *mInternalRT;
+EFI_EVENT mRuntimeResetSystemLibVirtualAddressChangeEvent;
+static EFI_RUNTIME_SERVICES *mInternalRT;
/**
This function causes a system-wide reset (cold reset), in which
diff --git a/MdeModulePkg/Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf b/MdeModulePkg/Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf
index 866e092..0843717 100644
--- a/MdeModulePkg/Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf
+++ b/MdeModulePkg/Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf
@@ -18,7 +18,7 @@
MODULE_TYPE = MM_STANDALONE
VERSION_STRING = 1.0
PI_SPECIFICATION_VERSION = 0x00010032
- LIBRARY_CLASS = ReportStatusCodeLib|MM_STANDALONE
+ LIBRARY_CLASS = ReportStatusCodeLib|MM_STANDALONE MM_CORE_STANDALONE
#
# The following information is for reference only and not required by the build tools.
diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
index 7a97f7c..8d62b0c 100644
--- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
+++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
@@ -147,6 +147,12 @@ BmFindBootOptionInVariable (
if (OptionNumber == LoadOptionNumberUnassigned) {
BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
+ // Only assert if the BootOption is non-zero
+ if ((BootOptions == NULL) && (BootOptionCount > 0)) {
+ ASSERT (BootOptions != NULL);
+ return LoadOptionNumberUnassigned;
+ }
+
Index = EfiBootManagerFindLoadOption (OptionToFind, BootOptions, BootOptionCount);
if (Index != -1) {
OptionNumber = BootOptions[Index].OptionNumber;
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h
index 89de54d..59b51e8 100644
--- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHii.h
@@ -1,7 +1,7 @@
/** @file
Include file for Var Check Hii handler and bin.
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -51,7 +51,11 @@ DumpVarCheckHii (
IN UINTN VarCheckHiiBinSize
);
-extern VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin;
-extern UINTN mVarCheckHiiBinSize;
+#define VAR_CHECK_RECEIVED_HII_BIN_HANDLER_GUID \
+ { \
+ 0xe63095c7, 0x2b34, 0x4163, { 0x80, 0x3d, 0xc8, 0x3c, 0x2e, 0xd6, 0xa0, 0x37 } \
+ }
+
+extern EFI_GUID gVarCheckReceivedHiiBinHandlerGuid;
#endif
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c
index ca8227d..abc5fd4 100644
--- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.c
@@ -1,14 +1,17 @@
/** @file
Var Check Hii bin generation.
-Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "VarCheckHiiGen.h"
+#include "VarCheckHii.h"
-LIST_ENTRY mVarCheckHiiList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckHiiList);
+VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin = NULL;
+UINTN mVarCheckHiiBinSize = 0;
+LIST_ENTRY mVarCheckHiiList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckHiiList);
#define VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE SIGNATURE_32 ('V', 'C', 'H', 'V')
@@ -1511,7 +1514,7 @@ DestroyHiiVariableNode (
**/
VOID *
BuildVarCheckHiiBin (
- OUT UINTN *Size
+ IN OUT UINTN *Size
)
{
VAR_CHECK_HII_VARIABLE_NODE *HiiVariableNode;
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h
index c70bf72..ace1fe6 100644
--- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGen.h
@@ -1,7 +1,7 @@
/** @file
Include file for Var Check Hii bin generation.
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -10,6 +10,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define _VAR_CHECK_HII_GEN_H_
#include "VarCheckHii.h"
+extern VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin;
+extern UINTN mVarCheckHiiBinSize;
/**
Dump Hii Package.
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c
index 27d10f8..6f152d4 100644
--- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromHii.c
@@ -65,3 +65,254 @@ VarCheckHiiGenFromHiiDatabase (
gBS->FreePages (BufferAddress, EFI_SIZE_TO_PAGES (BufferSize));
}
}
+
+#ifdef DUMP_VAR_CHECK_HII
+GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mHiiOpCodeStringTable[] = {
+ { EFI_IFR_VARSTORE_EFI_OP, "EfiVarStore" },
+ { EFI_IFR_ONE_OF_OP, "OneOf" },
+ { EFI_IFR_CHECKBOX_OP, "CheckBox" },
+ { EFI_IFR_NUMERIC_OP, "Numeric" },
+ { EFI_IFR_ORDERED_LIST_OP, "OrderedList" },
+};
+
+/**
+ HII opcode to string.
+
+ @param[in] HiiOpCode Hii OpCode.
+
+ @return Pointer to string.
+
+**/
+CHAR8 *
+HiiOpCodeToStr (
+ IN UINT8 HiiOpCode
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < ARRAY_SIZE (mHiiOpCodeStringTable); Index++) {
+ if (mHiiOpCodeStringTable[Index].HiiOpCode == HiiOpCode) {
+ return mHiiOpCodeStringTable[Index].HiiOpCodeStr;
+ }
+ }
+
+ return "<UnknownHiiOpCode>";
+}
+
+/**
+ Dump Hii Question.
+
+ @param[in] HiiQuestion Pointer to Hii Question.
+
+**/
+VOID
+DumpHiiQuestion (
+ IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion
+ )
+{
+ UINT64 Minimum;
+ UINT64 Maximum;
+ UINT64 OneValue;
+ UINT8 *Ptr;
+
+ DEBUG ((DEBUG_INFO, " VAR_CHECK_HII_QUESTION_HEADER\n"));
+ DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a) (%a)\n", HiiQuestion->OpCode, HiiOpCodeToStr (HiiQuestion->OpCode), (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));
+ DEBUG ((DEBUG_INFO, " Length - 0x%02x\n", HiiQuestion->Length));
+ DEBUG ((DEBUG_INFO, " VarOffset - 0x%04x (%a)\n", HiiQuestion->VarOffset, (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));
+ DEBUG ((DEBUG_INFO, " StorageWidth - 0x%02x (%a)\n", HiiQuestion->StorageWidth, (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));
+
+ switch (HiiQuestion->OpCode) {
+ case EFI_IFR_ONE_OF_OP:
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1);
+ while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {
+ OneValue = 0;
+ if (HiiQuestion->BitFieldStore) {
+ //
+ // For OneOf stored in bit field, the value of options are saved as UINT32 type.
+ //
+ CopyMem (&OneValue, Ptr, sizeof (UINT32));
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));
+ } else {
+ CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
+ switch (HiiQuestion->StorageWidth) {
+ case sizeof (UINT8):
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue));
+ break;
+ case sizeof (UINT16):
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue));
+ break;
+ case sizeof (UINT32):
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));
+ break;
+ case sizeof (UINT64):
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue));
+ break;
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+ }
+
+ if (HiiQuestion->BitFieldStore) {
+ Ptr += sizeof (UINT32);
+ } else {
+ Ptr += HiiQuestion->StorageWidth;
+ }
+ }
+
+ break;
+
+ case EFI_IFR_CHECKBOX_OP:
+ break;
+
+ case EFI_IFR_NUMERIC_OP:
+ Minimum = 0;
+ Maximum = 0;
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1);
+ if (HiiQuestion->BitFieldStore) {
+ //
+ // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type.
+ //
+ CopyMem (&Minimum, Ptr, sizeof (UINT32));
+ Ptr += sizeof (UINT32);
+ CopyMem (&Maximum, Ptr, sizeof (UINT32));
+ Ptr += sizeof (UINT32);
+
+ DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));
+ DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));
+ } else {
+ CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);
+ Ptr += HiiQuestion->StorageWidth;
+ CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);
+ Ptr += HiiQuestion->StorageWidth;
+
+ switch (HiiQuestion->StorageWidth) {
+ case sizeof (UINT8):
+ DEBUG ((DEBUG_INFO, " Minimum - 0x%02x\n", Minimum));
+ DEBUG ((DEBUG_INFO, " Maximum - 0x%02x\n", Maximum));
+ break;
+ case sizeof (UINT16):
+ DEBUG ((DEBUG_INFO, " Minimum - 0x%04x\n", Minimum));
+ DEBUG ((DEBUG_INFO, " Maximum - 0x%04x\n", Maximum));
+ break;
+ case sizeof (UINT32):
+ DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));
+ DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));
+ break;
+ case sizeof (UINT64):
+ DEBUG ((DEBUG_INFO, " Minimum - 0x%016lx\n", Minimum));
+ DEBUG ((DEBUG_INFO, " Maximum - 0x%016lx\n", Maximum));
+ break;
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+ }
+
+ break;
+
+ case EFI_IFR_ORDERED_LIST_OP:
+ DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers));
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1);
+ while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {
+ OneValue = 0;
+ CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
+ switch (HiiQuestion->StorageWidth) {
+ case sizeof (UINT8):
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue));
+ break;
+ case sizeof (UINT16):
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue));
+ break;
+ case sizeof (UINT32):
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));
+ break;
+ case sizeof (UINT64):
+ DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue));
+ break;
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+
+ Ptr += HiiQuestion->StorageWidth;
+ }
+
+ break;
+
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+}
+
+/**
+ Dump Hii Variable.
+
+ @param[in] HiiVariable Pointer to Hii Variable.
+
+**/
+VOID
+DumpHiiVariable (
+ IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable
+ )
+{
+ VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
+
+ DEBUG ((DEBUG_INFO, "VAR_CHECK_HII_VARIABLE_HEADER\n"));
+ DEBUG ((DEBUG_INFO, " Revision - 0x%04x\n", HiiVariable->Revision));
+ DEBUG ((DEBUG_INFO, " HeaderLength - 0x%04x\n", HiiVariable->HeaderLength));
+ DEBUG ((DEBUG_INFO, " Length - 0x%08x\n", HiiVariable->Length));
+ DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a)\n", HiiVariable->OpCode, HiiOpCodeToStr (HiiVariable->OpCode)));
+ DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", HiiVariable->Size));
+ DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", HiiVariable->Attributes));
+ DEBUG ((DEBUG_INFO, " Guid - %g\n", &HiiVariable->Guid));
+ DEBUG ((DEBUG_INFO, " Name - %s\n", HiiVariable + 1));
+
+ //
+ // For Hii Question header align.
+ //
+ HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength));
+ while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) {
+ //
+ // Dump Hii Question related to the Hii Variable.
+ //
+ DumpHiiQuestion (HiiQuestion);
+ //
+ // For Hii Question header align.
+ //
+ HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length));
+ }
+}
+
+/**
+ Dump Var Check HII.
+
+ @param[in] VarCheckHiiBin Pointer to VarCheckHiiBin.
+ @param[in] VarCheckHiiBinSize VarCheckHiiBin size.
+
+**/
+VOID
+DumpVarCheckHii (
+ IN VOID *VarCheckHiiBin,
+ IN UINTN VarCheckHiiBinSize
+ )
+{
+ VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
+
+ DEBUG ((DEBUG_INFO, "DumpVarCheckHii\n"));
+
+ //
+ // For Hii Variable header align.
+ //
+ HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (VarCheckHiiBin);
+ while ((UINTN)HiiVariable < ((UINTN)VarCheckHiiBin + VarCheckHiiBinSize)) {
+ DumpHiiVariable (HiiVariable);
+ //
+ // For Hii Variable header align.
+ //
+ HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length));
+ }
+}
+
+#endif
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c
new file mode 100644
index 0000000..22b2755
--- /dev/null
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.c
@@ -0,0 +1,57 @@
+/** @file
+ Var Check Hii handler.
+
+Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "VarCheckHii.h"
+#include "VarCheckHiiGen.h"
+#include "VarCheckHiiLibCommon.h"
+
+/**
+ Sets the variable check handler for HII.
+ @param[in] VariableName Name of Variable to set.
+ @param[in] VendorGuid Variable vendor GUID.
+ @param[in] Attributes Attribute value of the variable.
+ @param[in] DataSize Size of Data to set.
+ @param[in] Data Data pointer.
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_SECURITY_VIOLATION Check fail.
+**/
+EFI_STATUS
+EFIAPI
+SetVariableCheckHandlerHii (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ return CheckHiiVariableCommon (mVarCheckHiiBin, mVarCheckHiiBinSize, VariableName, VendorGuid, Attributes, DataSize, Data);
+}
+
+/**
+ Constructor function of VarCheckHiiLib to register var check HII handler.
+
+ @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 constructor executed correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckHiiLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ VarCheckLibRegisterEndOfDxeCallback (VarCheckHiiGen);
+ VarCheckLibRegisterAddressPointer ((VOID **)&mVarCheckHiiBin);
+ VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerHii);
+
+ return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
index 9e55d20..f25b190 100644
--- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
@@ -1,5 +1,5 @@
## @file
-# NULL class library to register var check HII handler.
+# VarCheckHiiLib library to register var check HII handler.
#
# Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
#
@@ -15,16 +15,18 @@
MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = NULL|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
- CONSTRUCTOR = VarCheckHiiLibNullClassConstructor
+ CONSTRUCTOR = VarCheckHiiLibConstructor
[Sources]
- VarCheckHiiLibNullClass.c
+ VarCheckHiiLib.c
VarCheckHii.h
VarCheckHiiGenFromFv.c
VarCheckHiiGenFromHii.c
VarCheckHiiGen.c
VarCheckHiiGen.h
InternalVarCheckStructure.h
+ VarCheckHiiLibCommon.c
+ VarCheckHiiLibCommon.h
[Packages]
MdePkg/MdePkg.dec
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c
new file mode 100644
index 0000000..00a37df
--- /dev/null
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.c
@@ -0,0 +1,349 @@
+/** @file
+ Var Check Hii Lib Common logic
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+
+#include "VarCheckHii.h"
+#include "VarCheckHiiLibCommon.h"
+EFI_HANDLE mEfiVariableCheckHiiHandle = NULL;
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+/**
+ Dump some hexadecimal data.
+ @param[in] Indent How many spaces to indent the output.
+ @param[in] Offset The offset of the dump.
+ @param[in] DataSize The size in bytes of UserData.
+ @param[in] UserData The data to dump.
+**/
+VOID
+VarCheckHiiInternalDumpHex (
+ IN UINTN Indent,
+ IN UINTN Offset,
+ IN UINTN DataSize,
+ IN VOID *UserData
+ )
+{
+ UINT8 *Data;
+
+ CHAR8 Val[50];
+
+ CHAR8 Str[20];
+
+ UINT8 TempByte;
+ UINTN Size;
+ UINTN Index;
+
+ Data = UserData;
+ while (DataSize != 0) {
+ Size = 16;
+ if (Size > DataSize) {
+ Size = DataSize;
+ }
+
+ for (Index = 0; Index < Size; Index += 1) {
+ TempByte = Data[Index];
+ Val[Index * 3 + 0] = mVarCheckHiiHex[TempByte >> 4];
+ Val[Index * 3 + 1] = mVarCheckHiiHex[TempByte & 0xF];
+ Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' ');
+ Str[Index] = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
+ }
+
+ Val[Index * 3] = 0;
+ Str[Index] = 0;
+ DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));
+
+ Data += Size;
+ Offset += Size;
+ DataSize -= Size;
+ }
+}
+
+/**
+ Var Check Hii Question.
+ @param[in] HiiQuestion Pointer to Hii Question
+ @param[in] Data Data pointer.
+ @param[in] DataSize Size of Data to set.
+ @retval TRUE Check pass
+ @retval FALSE Check fail.
+**/
+BOOLEAN
+VarCheckHiiQuestion (
+ IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion,
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ UINT64 OneData;
+ UINT64 Minimum;
+ UINT64 Maximum;
+ UINT64 OneValue;
+ UINT8 *Ptr;
+ UINT8 Index;
+ UINT8 MaxContainers;
+ UINT8 StartBit;
+ UINT8 EndBit;
+ UINT8 TotalBits;
+ UINT16 VarOffsetByteLevel;
+ UINT8 StorageWidthByteLevel;
+
+ if (HiiQuestion->BitFieldStore) {
+ VarOffsetByteLevel = HiiQuestion->VarOffset / 8;
+ TotalBits = HiiQuestion->VarOffset % 8 + HiiQuestion->StorageWidth;
+ StorageWidthByteLevel = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);
+ } else {
+ VarOffsetByteLevel = HiiQuestion->VarOffset;
+ StorageWidthByteLevel = HiiQuestion->StorageWidth;
+ }
+
+ if (((UINT32)VarOffsetByteLevel + StorageWidthByteLevel) > DataSize) {
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x)) > Size(0x%x)\n", VarOffsetByteLevel, StorageWidthByteLevel, DataSize));
+ return FALSE;
+ }
+
+ OneData = 0;
+ CopyMem (&OneData, (UINT8 *)Data + VarOffsetByteLevel, StorageWidthByteLevel);
+ if (HiiQuestion->BitFieldStore) {
+ //
+ // Get the value from the bit field.
+ //
+ StartBit = HiiQuestion->VarOffset % 8;
+ EndBit = StartBit + HiiQuestion->StorageWidth - 1;
+ OneData = BitFieldRead64 (OneData, StartBit, EndBit);
+ }
+
+ switch (HiiQuestion->OpCode) {
+ case EFI_IFR_ONE_OF_OP:
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1);
+ while ((UINTN)Ptr < (UINTN)HiiQuestion + HiiQuestion->Length) {
+ OneValue = 0;
+ if (HiiQuestion->BitFieldStore) {
+ //
+ // For OneOf stored in bit field, the value of options are saved as UINT32 type.
+ //
+ CopyMem (&OneValue, Ptr, sizeof (UINT32));
+ } else {
+ CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
+ }
+
+ if (OneData == OneValue) {
+ //
+ // Match
+ //
+ break;
+ }
+
+ if (HiiQuestion->BitFieldStore) {
+ Ptr += sizeof (UINT32);
+ } else {
+ Ptr += HiiQuestion->StorageWidth;
+ }
+ }
+
+ if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {
+ //
+ // No match
+ //
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OneOf mismatch (0x%lx)\n", OneData));
+ DEBUG_CODE (
+ VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
+ );
+ return FALSE;
+ }
+
+ break;
+
+ case EFI_IFR_CHECKBOX_OP:
+ if ((OneData != 0) && (OneData != 1)) {
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: CheckBox mismatch (0x%lx)\n", OneData));
+ DEBUG_CODE (
+ VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
+ );
+ return FALSE;
+ }
+
+ break;
+
+ case EFI_IFR_NUMERIC_OP:
+ Minimum = 0;
+ Maximum = 0;
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1);
+ if (HiiQuestion->BitFieldStore) {
+ //
+ // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type.
+ //
+ CopyMem (&Minimum, Ptr, sizeof (UINT32));
+ Ptr += sizeof (UINT32);
+ CopyMem (&Maximum, Ptr, sizeof (UINT32));
+ Ptr += sizeof (UINT32);
+ } else {
+ CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);
+ Ptr += HiiQuestion->StorageWidth;
+ CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);
+ Ptr += HiiQuestion->StorageWidth;
+ }
+
+ //
+ // No need to check Step, because it is ONLY for UI.
+ //
+ if ((OneData < Minimum) || (OneData > Maximum)) {
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: Numeric mismatch (0x%lx)\n", OneData));
+ DEBUG_CODE (
+ VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
+ );
+ return FALSE;
+ }
+
+ break;
+
+ case EFI_IFR_ORDERED_LIST_OP:
+ MaxContainers = ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers;
+ if (((UINT32)HiiQuestion->VarOffset + HiiQuestion->StorageWidth * MaxContainers) > DataSize) {
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x) * MaxContainers(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, MaxContainers, DataSize));
+ return FALSE;
+ }
+
+ for (Index = 0; Index < MaxContainers; Index++) {
+ OneData = 0;
+ CopyMem (&OneData, (UINT8 *)Data + HiiQuestion->VarOffset + HiiQuestion->StorageWidth * Index, HiiQuestion->StorageWidth);
+ if (OneData == 0) {
+ //
+ // The value of 0 is used to determine if a particular "slot" in the array is empty.
+ //
+ continue;
+ }
+
+ Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1);
+ while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {
+ OneValue = 0;
+ CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
+ if (OneData == OneValue) {
+ //
+ // Match
+ //
+ break;
+ }
+
+ Ptr += HiiQuestion->StorageWidth;
+ }
+
+ if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {
+ //
+ // No match
+ //
+ DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OrderedList mismatch\n"));
+ DEBUG_CODE (
+ VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->StorageWidth * MaxContainers, (UINT8 *)Data + HiiQuestion->VarOffset);
+ );
+ DEBUG_CODE (
+ VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
+ );
+ return FALSE;
+ }
+ }
+
+ break;
+
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+
+ return TRUE;
+}
+
+/**
+ SetVariable check handler HII.
+ @param[in] HiiVariableBin Variable BIN.
+ @param[in] HiiVariableBinSize The size of Variable BIN.
+ @param[in] VariableName Name of Variable to set.
+ @param[in] VendorGuid Variable vendor GUID.
+ @param[in] Attributes Attribute value of the variable.
+ @param[in] DataSize Size of Data to set.
+ @param[in] Data Data pointer.
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_SECURITY_VIOLATION Check fail.
+**/
+EFI_STATUS
+EFIAPI
+CheckHiiVariableCommon (
+ IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariableBin,
+ IN UINTN HiiVariableBinSize,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
+ VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
+
+ if (HiiVariableBin == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
+ //
+ // Do not check delete variable.
+ //
+ }
+
+ //
+ // For Hii Variable header align.
+ //
+ HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (HiiVariableBin);
+ while ((UINTN)HiiVariable < ((UINTN)HiiVariableBin + HiiVariableBinSize)) {
+ if ((StrCmp ((CHAR16 *)(HiiVariable + 1), VariableName) == 0) &&
+ (CompareGuid (&HiiVariable->Guid, VendorGuid)))
+ {
+ //
+ // Found the Hii Variable that could be used to do check.
+ //
+ DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));
+ if (HiiVariable->Attributes != Attributes) {
+ DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Attributes - 0x%08x\n", HiiVariable->Attributes));
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ if (DataSize == 0) {
+ DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - CHECK PASS with DataSize == 0 !\n"));
+ return EFI_SUCCESS;
+ }
+
+ if (HiiVariable->Size != DataSize) {
+ DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Size - 0x%x\n", HiiVariable->Size));
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ //
+ // Do the check.
+ // For Hii Question header align.
+ //
+ HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength));
+ while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) {
+ if (!VarCheckHiiQuestion (HiiQuestion, Data, DataSize)) {
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ //
+ // For Hii Question header align.
+ //
+ HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length));
+ }
+
+ DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - ALL CHECK PASS!\n"));
+ return EFI_SUCCESS;
+ }
+
+ //
+ // For Hii Variable header align.
+ //
+ HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length));
+ }
+
+ // Not found, so pass.
+ return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.h b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.h
new file mode 100644
index 0000000..06249f0
--- /dev/null
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibCommon.h
@@ -0,0 +1,43 @@
+/** @file
+ Var Check Hii Lib Common logic
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef VAR_CHECK_HII_LIB_GUID_H_
+#define VAR_CHECK_HII_LIB_GUID_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/MmServicesTableLib.h>
+#include <Protocol/MmCommunication.h>
+#include <Library/VarCheckLib.h>
+
+#include "VarCheckHii.h"
+
+/**
+ SetVariable check handler HII.
+ @param[in] HiiVariableBin Variable BIN.
+ @param[in] HiiVariableBinSize The size of Variable BIN.
+ @param[in] VariableName Name of Variable to set.
+ @param[in] VendorGuid Variable vendor GUID.
+ @param[in] Attributes Attribute value of the variable.
+ @param[in] DataSize Size of Data to set.
+ @param[in] Data Data pointer.
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_SECURITY_VIOLATION Check fail.
+**/
+EFI_STATUS
+EFIAPI
+CheckHiiVariableCommon (
+ IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariableBin,
+ IN UINTN HiiVariableBinSize,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+#endif
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.c
new file mode 100644
index 0000000..9ba75b7
--- /dev/null
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.c
@@ -0,0 +1,138 @@
+/** @file
+ VarCheckHiiLib Dependency library.
+ It sends HII variable checking data to SMM via the MM Communication protocol.
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/MmCommunication.h>
+#include <Guid/PiSmmCommunicationRegionTable.h>
+#include "InternalVarCheckStructure.h"
+#include "VarCheckHiiGen.h"
+#include "VarCheckHii.h"
+#include <Library/UefiLib.h>
+#include <Guid/EventGroup.h>
+
+extern VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin;
+extern UINTN mVarCheckHiiBinSize;
+EFI_GUID gVarCheckReceivedHiiBinHandlerGuid = VAR_CHECK_RECEIVED_HII_BIN_HANDLER_GUID;
+
+/**
+ Sends HII variable checking data to SMM at the end of DXE phase.
+ This function is triggered by the End of DXE. It locates a memory
+ region for MM communication, prepares the communication buffer with HII variable
+ checking data, and communicates with SMM using the MM Communication protocol.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context The pointer to the notification function's context, which
+ is implementation-dependent.
+**/
+VOID
+EFIAPI
+VarCheckHiiLibSmmEndOfDxeNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_MM_COMMUNICATION_PROTOCOL *MmCommunication;
+ EFI_MM_COMMUNICATE_HEADER *CommHeader;
+ EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;
+ EFI_MEMORY_DESCRIPTOR *MmCommMemRegion;
+ UINTN CommBufferSize;
+ UINTN Index;
+ VAR_CHECK_HII_VARIABLE_HEADER *VarCheckHiiVariable;
+
+ DEBUG ((DEBUG_INFO, "%a starts.\n", __func__));
+ VarCheckHiiGen ();
+ if ((mVarCheckHiiBinSize == 0) || (mVarCheckHiiBin == NULL)) {
+ DEBUG ((DEBUG_INFO, "%a: mVarCheckHiiBinSize = 0x%x, mVarCheckHiiBin = 0x%x \n", __func__, mVarCheckHiiBinSize, mVarCheckHiiBin));
+ return;
+ }
+
+ //
+ // Retrieve SMM Communication Region Table
+ //
+ Status = EfiGetSystemConfigurationTable (
+ &gEdkiiPiSmmCommunicationRegionTableGuid,
+ (VOID **)&PiSmmCommunicationRegionTable
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get PiSmmCommunicationRegionTable - %r\n", __func__, Status));
+ return;
+ }
+
+ ASSERT (PiSmmCommunicationRegionTable != NULL);
+ //
+ // Find a memory region for MM communication
+ //
+ CommBufferSize = 0;
+ MmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1);
+ for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {
+ if (MmCommMemRegion->Type == EfiConventionalMemory) {
+ CommBufferSize = EFI_PAGES_TO_SIZE ((UINTN)MmCommMemRegion->NumberOfPages);
+ if (CommBufferSize >= (sizeof (EFI_MM_COMMUNICATE_HEADER) + mVarCheckHiiBinSize)) {
+ break;
+ }
+ }
+
+ MmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MmCommMemRegion + PiSmmCommunicationRegionTable->DescriptorSize);
+ }
+
+ if (Index >= PiSmmCommunicationRegionTable->NumberOfEntries) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to find a suitable memory region for MM communication!\n", __func__));
+ return;
+ }
+
+ //
+ // Prepare the communication buffer
+ //
+ CommHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)MmCommMemRegion->PhysicalStart;
+ CommBufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + mVarCheckHiiBinSize;
+ ZeroMem (CommHeader, CommBufferSize);
+ CopyGuid (&CommHeader->HeaderGuid, &gVarCheckReceivedHiiBinHandlerGuid);
+ CommHeader->MessageLength = mVarCheckHiiBinSize;
+ VarCheckHiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)(CommHeader->Data);
+ CopyMem (VarCheckHiiVariable, mVarCheckHiiBin, mVarCheckHiiBinSize);
+ //
+ // Locate the MM Communication protocol and signal SMI
+ //
+ Status = gBS->LocateProtocol (&gEfiMmCommunicationProtocolGuid, NULL, (VOID **)&MmCommunication);
+
+ if (!EFI_ERROR (Status)) {
+ Status = MmCommunication->Communicate (MmCommunication, CommHeader, &CommBufferSize);
+ DEBUG ((DEBUG_INFO, "%a: Communicate to smm environment = %r\n", __func__, Status));
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to locate MmCommunication protocol - %r\n", __func__, Status));
+ return;
+ }
+
+ DEBUG ((DEBUG_INFO, "%a ends.\n", __func__));
+ return;
+}
+
+/**
+ Constructor function of the VarCheckHiiLibMmDependency.
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the Management mode System Table.
+ @retval EFI_SUCCESS The protocol was successfully installed into the DXE database.
+**/
+EFI_STATUS
+EFIAPI
+VarCheckHiiLibMmDependencyConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ DEBUG ((DEBUG_INFO, "%a starts.\n", __func__));
+ Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, VarCheckHiiLibSmmEndOfDxeNotify, NULL, &gEfiEndOfDxeEventGroupGuid, &Event);
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, "%a ends.\n", __func__));
+ return Status;
+}
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf
new file mode 100644
index 0000000..9798a1b
--- /dev/null
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf
@@ -0,0 +1,53 @@
+## @file
+# VarCheckHiiLib Dependency library.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = VarCheckHiiLibMmDependency
+ FILE_GUID = DF61C3DC-B08C-44B7-B771-9E4BCBBE0811
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = NULL
+ CONSTRUCTOR = VarCheckHiiLibMmDependencyConstructor
+
+[Sources]
+ VarCheckHiiLibMmDependency.c
+ VarCheckHii.h
+ VarCheckHiiGenFromFv.c
+ VarCheckHiiGenFromHii.c
+ VarCheckHiiGen.c
+ VarCheckHiiGen.h
+ InternalVarCheckStructure.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ UefiBootServicesTableLib
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiLib
+ PcdLib
+
+[Guids]
+ gEdkiiIfrBitVarstoreGuid
+ gEfiEndOfDxeEventGroupGuid
+ gEdkiiPiSmmCommunicationRegionTableGuid
+
+[Protocols]
+ gEfiMmEndOfDxeProtocolGuid
+ gEfiMmCommunicationProtocolGuid
+ gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiFirmwareVolumeBlock2ProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiHiiDatabaseProtocolGuid ## SOMETIMES_CONSUMES
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVarCheckVfrDriverGuidArray ## SOMETIMES_CONSUMES
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c
deleted file mode 100644
index ee2d98c..0000000
--- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibNullClass.c
+++ /dev/null
@@ -1,630 +0,0 @@
-/** @file
- Var Check Hii handler.
-
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "VarCheckHii.h"
-
-GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-
-/**
- Dump some hexadecimal data.
-
- @param[in] Indent How many spaces to indent the output.
- @param[in] Offset The offset of the dump.
- @param[in] DataSize The size in bytes of UserData.
- @param[in] UserData The data to dump.
-
-**/
-VOID
-VarCheckHiiInternalDumpHex (
- IN UINTN Indent,
- IN UINTN Offset,
- IN UINTN DataSize,
- IN VOID *UserData
- )
-{
- UINT8 *Data;
-
- CHAR8 Val[50];
-
- CHAR8 Str[20];
-
- UINT8 TempByte;
- UINTN Size;
- UINTN Index;
-
- Data = UserData;
- while (DataSize != 0) {
- Size = 16;
- if (Size > DataSize) {
- Size = DataSize;
- }
-
- for (Index = 0; Index < Size; Index += 1) {
- TempByte = Data[Index];
- Val[Index * 3 + 0] = mVarCheckHiiHex[TempByte >> 4];
- Val[Index * 3 + 1] = mVarCheckHiiHex[TempByte & 0xF];
- Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' ');
- Str[Index] = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
- }
-
- Val[Index * 3] = 0;
- Str[Index] = 0;
- DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));
-
- Data += Size;
- Offset += Size;
- DataSize -= Size;
- }
-}
-
-/**
- Var Check Hii Question.
-
- @param[in] HiiQuestion Pointer to Hii Question
- @param[in] Data Data pointer.
- @param[in] DataSize Size of Data to set.
-
- @retval TRUE Check pass
- @retval FALSE Check fail.
-
-**/
-BOOLEAN
-VarCheckHiiQuestion (
- IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion,
- IN VOID *Data,
- IN UINTN DataSize
- )
-{
- UINT64 OneData;
- UINT64 Minimum;
- UINT64 Maximum;
- UINT64 OneValue;
- UINT8 *Ptr;
- UINT8 Index;
- UINT8 MaxContainers;
- UINT8 StartBit;
- UINT8 EndBit;
- UINT8 TotalBits;
- UINT16 VarOffsetByteLevel;
- UINT8 StorageWidthByteLevel;
-
- if (HiiQuestion->BitFieldStore) {
- VarOffsetByteLevel = HiiQuestion->VarOffset / 8;
- TotalBits = HiiQuestion->VarOffset % 8 + HiiQuestion->StorageWidth;
- StorageWidthByteLevel = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);
- } else {
- VarOffsetByteLevel = HiiQuestion->VarOffset;
- StorageWidthByteLevel = HiiQuestion->StorageWidth;
- }
-
- if (((UINT32)VarOffsetByteLevel + StorageWidthByteLevel) > DataSize) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x)) > Size(0x%x)\n", VarOffsetByteLevel, StorageWidthByteLevel, DataSize));
- return FALSE;
- }
-
- OneData = 0;
- CopyMem (&OneData, (UINT8 *)Data + VarOffsetByteLevel, StorageWidthByteLevel);
- if (HiiQuestion->BitFieldStore) {
- //
- // Get the value from the bit field.
- //
- StartBit = HiiQuestion->VarOffset % 8;
- EndBit = StartBit + HiiQuestion->StorageWidth - 1;
- OneData = BitFieldRead64 (OneData, StartBit, EndBit);
- }
-
- switch (HiiQuestion->OpCode) {
- case EFI_IFR_ONE_OF_OP:
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1);
- while ((UINTN)Ptr < (UINTN)HiiQuestion + HiiQuestion->Length) {
- OneValue = 0;
- if (HiiQuestion->BitFieldStore) {
- //
- // For OneOf stored in bit field, the value of options are saved as UINT32 type.
- //
- CopyMem (&OneValue, Ptr, sizeof (UINT32));
- } else {
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
- }
-
- if (OneData == OneValue) {
- //
- // Match
- //
- break;
- }
-
- if (HiiQuestion->BitFieldStore) {
- Ptr += sizeof (UINT32);
- } else {
- Ptr += HiiQuestion->StorageWidth;
- }
- }
-
- if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {
- //
- // No match
- //
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OneOf mismatch (0x%lx)\n", OneData));
- DEBUG_CODE (
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
- );
- return FALSE;
- }
-
- break;
-
- case EFI_IFR_CHECKBOX_OP:
- if ((OneData != 0) && (OneData != 1)) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: CheckBox mismatch (0x%lx)\n", OneData));
- DEBUG_CODE (
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
- );
- return FALSE;
- }
-
- break;
-
- case EFI_IFR_NUMERIC_OP:
- Minimum = 0;
- Maximum = 0;
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1);
- if (HiiQuestion->BitFieldStore) {
- //
- // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type.
- //
- CopyMem (&Minimum, Ptr, sizeof (UINT32));
- Ptr += sizeof (UINT32);
- CopyMem (&Maximum, Ptr, sizeof (UINT32));
- Ptr += sizeof (UINT32);
- } else {
- CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);
- Ptr += HiiQuestion->StorageWidth;
- CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);
- Ptr += HiiQuestion->StorageWidth;
- }
-
- //
- // No need to check Step, because it is ONLY for UI.
- //
- if ((OneData < Minimum) || (OneData > Maximum)) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: Numeric mismatch (0x%lx)\n", OneData));
- DEBUG_CODE (
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
- );
- return FALSE;
- }
-
- break;
-
- case EFI_IFR_ORDERED_LIST_OP:
- MaxContainers = ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers;
- if (((UINT32)HiiQuestion->VarOffset + HiiQuestion->StorageWidth * MaxContainers) > DataSize) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x) * MaxContainers(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, MaxContainers, DataSize));
- return FALSE;
- }
-
- for (Index = 0; Index < MaxContainers; Index++) {
- OneData = 0;
- CopyMem (&OneData, (UINT8 *)Data + HiiQuestion->VarOffset + HiiQuestion->StorageWidth * Index, HiiQuestion->StorageWidth);
- if (OneData == 0) {
- //
- // The value of 0 is used to determine if a particular "slot" in the array is empty.
- //
- continue;
- }
-
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1);
- while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {
- OneValue = 0;
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
- if (OneData == OneValue) {
- //
- // Match
- //
- break;
- }
-
- Ptr += HiiQuestion->StorageWidth;
- }
-
- if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {
- //
- // No match
- //
- DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OrderedList mismatch\n"));
- DEBUG_CODE (
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->StorageWidth * MaxContainers, (UINT8 *)Data + HiiQuestion->VarOffset);
- );
- DEBUG_CODE (
- VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
- );
- return FALSE;
- }
- }
-
- break;
-
- default:
- ASSERT (FALSE);
- break;
- }
-
- return TRUE;
-}
-
-VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin = NULL;
-UINTN mVarCheckHiiBinSize = 0;
-
-/**
- SetVariable check handler HII.
-
- @param[in] VariableName Name of Variable to set.
- @param[in] VendorGuid Variable vendor GUID.
- @param[in] Attributes Attribute value of the variable.
- @param[in] DataSize Size of Data to set.
- @param[in] Data Data pointer.
-
- @retval EFI_SUCCESS The SetVariable check result was success.
- @retval EFI_SECURITY_VIOLATION Check fail.
-
-**/
-EFI_STATUS
-EFIAPI
-SetVariableCheckHandlerHii (
- IN CHAR16 *VariableName,
- IN EFI_GUID *VendorGuid,
- IN UINT32 Attributes,
- IN UINTN DataSize,
- IN VOID *Data
- )
-{
- VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
- VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
-
- if (mVarCheckHiiBin == NULL) {
- return EFI_SUCCESS;
- }
-
- if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
- //
- // Do not check delete variable.
- //
- return EFI_SUCCESS;
- }
-
- //
- // For Hii Variable header align.
- //
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (mVarCheckHiiBin);
- while ((UINTN)HiiVariable < ((UINTN)mVarCheckHiiBin + mVarCheckHiiBinSize)) {
- if ((StrCmp ((CHAR16 *)(HiiVariable + 1), VariableName) == 0) &&
- (CompareGuid (&HiiVariable->Guid, VendorGuid)))
- {
- //
- // Found the Hii Variable that could be used to do check.
- //
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));
- if (HiiVariable->Attributes != Attributes) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Attributes - 0x%08x\n", HiiVariable->Attributes));
- return EFI_SECURITY_VIOLATION;
- }
-
- if (DataSize == 0) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - CHECK PASS with DataSize == 0 !\n"));
- return EFI_SUCCESS;
- }
-
- if (HiiVariable->Size != DataSize) {
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Size - 0x%x\n", HiiVariable->Size));
- return EFI_SECURITY_VIOLATION;
- }
-
- //
- // Do the check.
- // For Hii Question header align.
- //
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength));
- while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) {
- if (!VarCheckHiiQuestion (HiiQuestion, Data, DataSize)) {
- return EFI_SECURITY_VIOLATION;
- }
-
- //
- // For Hii Question header align.
- //
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length));
- }
-
- DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - ALL CHECK PASS!\n"));
- return EFI_SUCCESS;
- }
-
- //
- // For Hii Variable header align.
- //
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length));
- }
-
- // Not found, so pass.
- return EFI_SUCCESS;
-}
-
-#ifdef DUMP_VAR_CHECK_HII
-GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mHiiOpCodeStringTable[] = {
- { EFI_IFR_VARSTORE_EFI_OP, "EfiVarStore" },
- { EFI_IFR_ONE_OF_OP, "OneOf" },
- { EFI_IFR_CHECKBOX_OP, "CheckBox" },
- { EFI_IFR_NUMERIC_OP, "Numeric" },
- { EFI_IFR_ORDERED_LIST_OP, "OrderedList" },
-};
-
-/**
- HII opcode to string.
-
- @param[in] HiiOpCode Hii OpCode.
-
- @return Pointer to string.
-
-**/
-CHAR8 *
-HiiOpCodeToStr (
- IN UINT8 HiiOpCode
- )
-{
- UINTN Index;
-
- for (Index = 0; Index < ARRAY_SIZE (mHiiOpCodeStringTable); Index++) {
- if (mHiiOpCodeStringTable[Index].HiiOpCode == HiiOpCode) {
- return mHiiOpCodeStringTable[Index].HiiOpCodeStr;
- }
- }
-
- return "<UnknownHiiOpCode>";
-}
-
-/**
- Dump Hii Question.
-
- @param[in] HiiQuestion Pointer to Hii Question.
-
-**/
-VOID
-DumpHiiQuestion (
- IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion
- )
-{
- UINT64 Minimum;
- UINT64 Maximum;
- UINT64 OneValue;
- UINT8 *Ptr;
-
- DEBUG ((DEBUG_INFO, " VAR_CHECK_HII_QUESTION_HEADER\n"));
- DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a) (%a)\n", HiiQuestion->OpCode, HiiOpCodeToStr (HiiQuestion->OpCode), (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));
- DEBUG ((DEBUG_INFO, " Length - 0x%02x\n", HiiQuestion->Length));
- DEBUG ((DEBUG_INFO, " VarOffset - 0x%04x (%a)\n", HiiQuestion->VarOffset, (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));
- DEBUG ((DEBUG_INFO, " StorageWidth - 0x%02x (%a)\n", HiiQuestion->StorageWidth, (HiiQuestion->BitFieldStore ? "bit level" : "byte level")));
-
- switch (HiiQuestion->OpCode) {
- case EFI_IFR_ONE_OF_OP:
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1);
- while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {
- OneValue = 0;
- if (HiiQuestion->BitFieldStore) {
- //
- // For OneOf stored in bit field, the value of options are saved as UINT32 type.
- //
- CopyMem (&OneValue, Ptr, sizeof (UINT32));
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));
- } else {
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
- switch (HiiQuestion->StorageWidth) {
- case sizeof (UINT8):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue));
- break;
- case sizeof (UINT16):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue));
- break;
- case sizeof (UINT32):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));
- break;
- case sizeof (UINT64):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue));
- break;
- default:
- ASSERT (FALSE);
- break;
- }
- }
-
- if (HiiQuestion->BitFieldStore) {
- Ptr += sizeof (UINT32);
- } else {
- Ptr += HiiQuestion->StorageWidth;
- }
- }
-
- break;
-
- case EFI_IFR_CHECKBOX_OP:
- break;
-
- case EFI_IFR_NUMERIC_OP:
- Minimum = 0;
- Maximum = 0;
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1);
- if (HiiQuestion->BitFieldStore) {
- //
- // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type.
- //
- CopyMem (&Minimum, Ptr, sizeof (UINT32));
- Ptr += sizeof (UINT32);
- CopyMem (&Maximum, Ptr, sizeof (UINT32));
- Ptr += sizeof (UINT32);
-
- DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));
- DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));
- } else {
- CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);
- Ptr += HiiQuestion->StorageWidth;
- CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);
- Ptr += HiiQuestion->StorageWidth;
-
- switch (HiiQuestion->StorageWidth) {
- case sizeof (UINT8):
- DEBUG ((DEBUG_INFO, " Minimum - 0x%02x\n", Minimum));
- DEBUG ((DEBUG_INFO, " Maximum - 0x%02x\n", Maximum));
- break;
- case sizeof (UINT16):
- DEBUG ((DEBUG_INFO, " Minimum - 0x%04x\n", Minimum));
- DEBUG ((DEBUG_INFO, " Maximum - 0x%04x\n", Maximum));
- break;
- case sizeof (UINT32):
- DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));
- DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));
- break;
- case sizeof (UINT64):
- DEBUG ((DEBUG_INFO, " Minimum - 0x%016lx\n", Minimum));
- DEBUG ((DEBUG_INFO, " Maximum - 0x%016lx\n", Maximum));
- break;
- default:
- ASSERT (FALSE);
- break;
- }
- }
-
- break;
-
- case EFI_IFR_ORDERED_LIST_OP:
- DEBUG ((DEBUG_INFO, " MaxContainers - 0x%02x\n", ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers));
- Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1);
- while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {
- OneValue = 0;
- CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
- switch (HiiQuestion->StorageWidth) {
- case sizeof (UINT8):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%02x\n", OneValue));
- break;
- case sizeof (UINT16):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%04x\n", OneValue));
- break;
- case sizeof (UINT32):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%08x\n", OneValue));
- break;
- case sizeof (UINT64):
- DEBUG ((DEBUG_INFO, " OneOfOption - 0x%016lx\n", OneValue));
- break;
- default:
- ASSERT (FALSE);
- break;
- }
-
- Ptr += HiiQuestion->StorageWidth;
- }
-
- break;
-
- default:
- ASSERT (FALSE);
- break;
- }
-}
-
-/**
- Dump Hii Variable.
-
- @param[in] HiiVariable Pointer to Hii Variable.
-
-**/
-VOID
-DumpHiiVariable (
- IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable
- )
-{
- VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
-
- DEBUG ((DEBUG_INFO, "VAR_CHECK_HII_VARIABLE_HEADER\n"));
- DEBUG ((DEBUG_INFO, " Revision - 0x%04x\n", HiiVariable->Revision));
- DEBUG ((DEBUG_INFO, " HeaderLength - 0x%04x\n", HiiVariable->HeaderLength));
- DEBUG ((DEBUG_INFO, " Length - 0x%08x\n", HiiVariable->Length));
- DEBUG ((DEBUG_INFO, " OpCode - 0x%02x (%a)\n", HiiVariable->OpCode, HiiOpCodeToStr (HiiVariable->OpCode)));
- DEBUG ((DEBUG_INFO, " Size - 0x%04x\n", HiiVariable->Size));
- DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", HiiVariable->Attributes));
- DEBUG ((DEBUG_INFO, " Guid - %g\n", &HiiVariable->Guid));
- DEBUG ((DEBUG_INFO, " Name - %s\n", HiiVariable + 1));
-
- //
- // For Hii Question header align.
- //
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength));
- while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) {
- //
- // Dump Hii Question related to the Hii Variable.
- //
- DumpHiiQuestion (HiiQuestion);
- //
- // For Hii Question header align.
- //
- HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length));
- }
-}
-
-/**
- Dump Var Check HII.
-
- @param[in] VarCheckHiiBin Pointer to VarCheckHiiBin.
- @param[in] VarCheckHiiBinSize VarCheckHiiBin size.
-
-**/
-VOID
-DumpVarCheckHii (
- IN VOID *VarCheckHiiBin,
- IN UINTN VarCheckHiiBinSize
- )
-{
- VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
-
- DEBUG ((DEBUG_INFO, "DumpVarCheckHii\n"));
-
- //
- // For Hii Variable header align.
- //
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (VarCheckHiiBin);
- while ((UINTN)HiiVariable < ((UINTN)VarCheckHiiBin + VarCheckHiiBinSize)) {
- DumpHiiVariable (HiiVariable);
- //
- // For Hii Variable header align.
- //
- HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length));
- }
-}
-
-#endif
-
-/**
- Constructor function of VarCheckHiiLib to register var check HII handler.
-
- @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 constructor executed correctly.
-
-**/
-EFI_STATUS
-EFIAPI
-VarCheckHiiLibNullClassConstructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- VarCheckLibRegisterEndOfDxeCallback (VarCheckHiiGen);
- VarCheckLibRegisterAddressPointer ((VOID **)&mVarCheckHiiBin);
- VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerHii);
-
- return EFI_SUCCESS;
-}
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c
new file mode 100644
index 0000000..c1ee55b
--- /dev/null
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c
@@ -0,0 +1,152 @@
+/** @file
+
+ Implementation functions and structures for var check services.
+ This file provides functions and structures to register and handle variable checks
+ in the Standalone MM environment, specifically for HII variables.
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/MmServicesTableLib.h>
+#include <Protocol/MmCommunication.h>
+#include <Library/VarCheckLib.h>
+
+#include "VarCheckHii.h"
+#include "VarCheckHiiLibCommon.h"
+
+//
+// In the standalone setup, mVarCheckHiiBin is used for sending, while mVarCheckHiiBinMmReceived is used for receiving,
+// while in the traditional setup, mVarCheckHiiBin is used for both sending and receiving.
+//
+VAR_CHECK_HII_VARIABLE_HEADER *mMmReceivedVarCheckHiiBin = NULL;
+UINTN mMmReceivedVarCheckHiiBinSize = 0;
+EFI_GUID gVarCheckReceivedHiiBinHandlerGuid = VAR_CHECK_RECEIVED_HII_BIN_HANDLER_GUID;
+
+/**
+ Registers a handler for HII variable checks in MM environment.
+ This function is intended to be called to register a handler for checking variables
+ in the Standalone MM environment. It allocates memory for the variable
+ check data and copies the data from the communication buffer.
+
+ @param[in] DispatchHandle The handle of the dispatch function.
+ @param[in] Context Optional context for the handler, not used in this implementation.
+ @param CommBuffer The buffer of data being passed in.
+ @param CommBufferSize The size of the data being passed in.
+ @retval EFI_SUCCESS Registration and memory allocation were successful.
+ @retval EFI_INVALID_PARAMETER The CommBuffer or CommBufferSize is NULL.
+ @retval EFI_ACCESS_DENIED The buffer size is invalid or the buffer is in an invalid location.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation for the variable check data failed.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckHiiLibReceiveHiiBinHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // If input is invalid, stop processing this SMI
+ //
+ if ((CommBuffer == NULL) || (CommBufferSize == NULL)) {
+ return EFI_SUCCESS;
+ }
+
+ mMmReceivedVarCheckHiiBinSize = *CommBufferSize;
+
+ if (mMmReceivedVarCheckHiiBinSize < sizeof (VAR_CHECK_HII_VARIABLE_HEADER)) {
+ DEBUG ((DEBUG_ERROR, "%a: MM Communication buffer size is invalid for this handler!\n", __func__));
+ return EFI_ACCESS_DENIED;
+ }
+
+ mMmReceivedVarCheckHiiBin = AllocateZeroPool (mMmReceivedVarCheckHiiBinSize);
+ if (mMmReceivedVarCheckHiiBin == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to allocate memory for mVarCheckHiiBinMm\n", __func__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (mMmReceivedVarCheckHiiBin, CommBuffer, mMmReceivedVarCheckHiiBinSize);
+ if (DispatchHandle != NULL) {
+ Status = gMmst->MmiHandlerUnRegister (DispatchHandle);
+ }
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to unregister handler - %r!\n", __func__, Status));
+ } else {
+ DEBUG ((DEBUG_INFO, "%a: Handler unregistered successfully.\n", __func__));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Sets the variable check handler for HII.
+ This function registers a handler that will be invoked for variable checks
+ in the HII environment. It allows for custom validation logic to be implemented
+ for setting HII variables.
+ @param[in] VariableName Name of Variable to set.
+ @param[in] VendorGuid Variable vendor GUID.
+ @param[in] Attributes Attribute value of the variable.
+ @param[in] DataSize Size of Data to set.
+ @param[in] Data Data pointer.
+
+**/
+EFI_STATUS
+EFIAPI
+SetVariableCheckHandlerHii (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ return CheckHiiVariableCommon (mMmReceivedVarCheckHiiBin, mMmReceivedVarCheckHiiBinSize, VariableName, VendorGuid, Attributes, DataSize, Data);
+}
+
+/**
+ Constructor function for variable check library in Standalone MM.
+ This function registers a handler for variable checks and sets up the environment
+ for variable checking in the Standalone MM environment.
+ @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 constructor executed successfully.
+ @retval Others An error occurred during execution.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckHiiLibConstructorStandaloneMm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE DispatchHandle;
+
+ DEBUG ((DEBUG_INFO, "%a: starts.\n", __func__));
+ //
+ // Register a handler to recieve the HII variable checking data.
+ //
+ Status = gMmst->MmiHandlerRegister (VarCheckHiiLibReceiveHiiBinHandler, &gVarCheckReceivedHiiBinHandlerGuid, &DispatchHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to register handler - %r!\n", __func__, Status));
+
+ return Status;
+ }
+
+ VarCheckLibRegisterAddressPointer ((VOID **)&mMmReceivedVarCheckHiiBin);
+ VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerHii);
+ DEBUG ((DEBUG_INFO, "%a: ends.\n", __func__));
+ return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf
new file mode 100644
index 0000000..dcef802
--- /dev/null
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf
@@ -0,0 +1,47 @@
+## @file
+# Implementation functions and structures for var check services.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = VarCheckHiiLib
+ MODULE_UNI_FILE = VarCheckHiiLibStandaloneMm.uni
+ FILE_GUID = 8545E553-AF7D-4FA0-B402-9B5A67ABC812
+ MODULE_TYPE = MM_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = VarCheckHiiLib|MM_STANDALONE
+ CONSTRUCTOR = VarCheckHiiLibConstructorStandaloneMm
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ VarCheckHiiLibStandaloneMm.c
+ VarCheckHii.h
+ InternalVarCheckStructure.h
+ VarCheckHiiLibCommon.c
+ VarCheckHiiLibCommon.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ VarCheckLib
+
+[Protocols]
+ gEfiMmEndOfDxeProtocolGuid
diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.uni b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.uni
new file mode 100644
index 0000000..a84a1cc
--- /dev/null
+++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.uni
@@ -0,0 +1,15 @@
+// /** @file
+// Provides variable check services and database management.
+//
+// Provides variable check services and database management.
+//
+// Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides StandaloneMm variable check services and database management"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Provides StandaloneMm variable check services and database management."
diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
index 1448af8..3539206 100644
--- a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
+++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
@@ -2,6 +2,7 @@
This is a NULL library instance that leverages the VarCheck interface
and the business logic behind the VariablePolicy code to make its decisions.
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -105,13 +106,15 @@ VarCheckPolicyLibMmiHandler (
return EFI_INVALID_PARAMETER;
}
- // Make sure that the buffer does not overlap SMM.
+ //
+ // Make sure that the buffer is valid.
// This should be covered by the SmiManage infrastructure, but just to be safe...
+ //
InternalCommBufferSize = *CommBufferSize;
if ((InternalCommBufferSize > VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE) ||
- !VarCheckPolicyIsBufferOutsideValid ((UINTN)CommBuffer, (UINT64)InternalCommBufferSize))
+ !VarCheckPolicyIsPrimaryBufferValid ((UINTN)CommBuffer, (UINT64)InternalCommBufferSize))
{
- DEBUG ((DEBUG_ERROR, "%a - Invalid CommBuffer supplied! 0x%016lX[0x%016lX]\n", __func__, CommBuffer, InternalCommBufferSize));
+ DEBUG ((DEBUG_ERROR, "%a - Invalid Primary Buffer (CommBuffer) supplied! 0x%016lX[0x%016lX]\n", __func__, CommBuffer, InternalCommBufferSize));
return EFI_INVALID_PARAMETER;
}
diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.h b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.h
index 2226c8a..5f89f1e 100644
--- a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.h
+++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.h
@@ -2,6 +2,7 @@
This internal header file defines the common interface of constructor for
VarCheckPolicyLib.
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -24,17 +25,17 @@ VarCheckPolicyLibCommonConstructor (
);
/**
- This function is wrapper function to validate the buffer.
+ This function is wrapper function to validate the Primary Buffer (CommBuffer).
@param Buffer The buffer start address to be checked.
@param Length The buffer length to be checked.
- @retval TRUE This buffer is valid per processor architecture and not overlap with SMRAM/MMRAM.
- @retval FALSE This buffer is not valid per processor architecture or overlap with SMRAM/MMRAM.
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
**/
BOOLEAN
EFIAPI
-VarCheckPolicyIsBufferOutsideValid (
+VarCheckPolicyIsPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
);
diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c
index 784a242..4bfaf1e 100644
--- a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c
+++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibStandaloneMm.c
@@ -1,6 +1,7 @@
/** @file -- VarCheckPolicyLibStandaloneMm.c
This is an instance of a VarCheck lib constructor for Standalone MM.
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -31,20 +32,20 @@ VarCheckPolicyLibStandaloneConstructor (
}
/**
- This function is wrapper function to validate the buffer.
+ This function is wrapper function to validate the Primary Buffer (CommBuffer).
@param Buffer The buffer start address to be checked.
@param Length The buffer length to be checked.
- @retval TRUE This buffer is valid per processor architectureand not overlap with MMRAM.
- @retval FALSE This buffer is not valid per processor architecture or overlap with MMRAM.
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
**/
BOOLEAN
EFIAPI
-VarCheckPolicyIsBufferOutsideValid (
+VarCheckPolicyIsPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
)
{
- return MmIsBufferOutsideMmValid (Buffer, Length);
+ return TRUE;
}
diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibTraditional.c b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibTraditional.c
index 07bead2..36dccef 100644
--- a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibTraditional.c
+++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLibTraditional.c
@@ -1,6 +1,7 @@
/** @file -- VarCheckPolicyLibTraditional.c
This is an instance of a VarCheck lib constructor for traditional SMM.
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -31,7 +32,7 @@ VarCheckPolicyLibTraditionalConstructor (
}
/**
- This function is wrapper function to validate the buffer.
+ This function is wrapper function to validate the Primary Buffer (CommBuffer).
@param Buffer The buffer start address to be checked.
@param Length The buffer length to be checked.
@@ -41,7 +42,7 @@ VarCheckPolicyLibTraditionalConstructor (
**/
BOOLEAN
EFIAPI
-VarCheckPolicyIsBufferOutsideValid (
+VarCheckPolicyIsPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
)
diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
index 7686628..f5b9418 100644
--- a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
+++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
@@ -178,7 +178,7 @@ IsValidVariablePolicyStructure (
WildcardCount = 0;
while (*CheckChar != CHAR_NULL) {
// Make sure there aren't excessive wildcards.
- if (*CheckChar == '#') {
+ if (*CheckChar == L'#') {
WildcardCount++;
if (WildcardCount > MATCH_PRIORITY_MIN) {
return FALSE;
@@ -263,7 +263,7 @@ EvaluatePolicyMatch (
// Keep going until the end of both strings.
while (PolicyName[Index] != CHAR_NULL || VariableName[Index] != CHAR_NULL) {
// If we don't have a match...
- if ((PolicyName[Index] != VariableName[Index]) || (PolicyName[Index] == '#')) {
+ if ((PolicyName[Index] != VariableName[Index]) || (PolicyName[Index] == L'#')) {
// If this is a numerical wildcard, we can consider
// it a match if we alter the priority.
if ((PolicyName[Index] == L'#') &&
@@ -918,7 +918,7 @@ GetLockOnVariableStateVariablePolicyInfo (
LocalLockOnVarStatePolicy = (VARIABLE_LOCK_ON_VAR_STATE_POLICY *)(MatchPolicy + 1);
CopyMem (VariablePolicy, LocalLockOnVarStatePolicy, sizeof (*LocalLockOnVarStatePolicy));
- if ((VariableLockPolicyVariableNameBufferSize == NULL)) {
+ if (VariableLockPolicyVariableNameBufferSize == NULL) {
if (VariableLockPolicyVariableName != NULL) {
return EFI_INVALID_PARAMETER;
}
diff --git a/MdeModulePkg/MdeModulePkg.ci.yaml b/MdeModulePkg/MdeModulePkg.ci.yaml
index a3de60a..34d8b7e 100644
--- a/MdeModulePkg/MdeModulePkg.ci.yaml
+++ b/MdeModulePkg/MdeModulePkg.ci.yaml
@@ -23,6 +23,7 @@
"8005", "UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE.UID",
"8005", "UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE.HID",
"8001", "UefiSortLibUnitTestMain",
+ "8001", "MediaSanitizeUnitTestMain",
],
## Both file path and directory path are accepted.
"IgnoreFiles": [
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 6148025..1324b6d 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -174,6 +174,10 @@
#
SpiHcPlatformLib|Include/Library/SpiHcPlatformLib.h
+ ## @libraryclass Provides services to prints all HOB information.
+ #
+ HobPrintLib|Include/Library/HobPrintLib.h
+
[Guids]
## MdeModule package token space guid
# Include/Guid/MdeModulePkgTokenSpace.h
@@ -409,6 +413,13 @@
## Include/Guid/EndofS3Resume.h
gEdkiiEndOfS3ResumeGuid = { 0x96f5296d, 0x05f7, 0x4f3c, {0x84, 0x67, 0xe4, 0x56, 0x89, 0x0e, 0x0c, 0xb5 } }
+ #
+ # Guids for NVMe Timeout Events
+ # {4754469d-6528-4dfc-84aa-8c8a03a2158b}
+ gNVMeEnableStartEventGroupGuid = { 0x4754469d, 0x6528, 0x4dfc, { 0x84, 0xaa, 0x8c, 0x8a, 0x03, 0xa2, 0x15, 0x8b } }
+ # {da383315-906b-486f-80db-847f268451e4}
+ gNVMeEnableCompleteEventGroupGuid = { 0xda383315, 0x906b, 0x486f, { 0x80, 0xdb, 0x84, 0x7f, 0x26, 0x84, 0x51, 0xe4 } }
+
## Used (similar to Variable Services) to communicate policies to the enforcement engine.
# {DA1B0D11-D1A7-46C4-9DC9-F3714875C6EB}
gVarCheckPolicyLibMmiHandlerGuid = { 0xda1b0d11, 0xd1a7, 0x46c4, { 0x9d, 0xc9, 0xf3, 0x71, 0x48, 0x75, 0xc6, 0xeb }}
@@ -471,6 +482,12 @@
## Include/Guid/VariableRuntimeCacheInfo.h
gEdkiiVariableRuntimeCacheInfoHobGuid = { 0x0f472f7d, 0x6713, 0x4915, { 0x96, 0x14, 0x5d, 0xda, 0x28, 0x40, 0x10, 0x56 }}
+ ## HOB GUID to get ACPI table after FSP is done. The ACPI table that related SOC will be pass by this HOB.
+ gAcpiTableHobGuid = { 0xf9886b57, 0x8a35, 0x455e, { 0xbb, 0xb1, 0x14, 0x65, 0x5e, 0x7b, 0xe7, 0xec }}
+
+ ## Include/Guid/MmCommBuffer.h
+ gMmCommBufferHobGuid = { 0x6c2a2520, 0x0131, 0x4aee, { 0xa7, 0x50, 0xcc, 0x38, 0x4a, 0xac, 0xe8, 0xc6 }}
+
[Ppis]
## Include/Ppi/FirmwareVolumeShadowPpi.h
gEdkiiPeiFirmwareVolumeShadowPpiGuid = { 0x7dfe756c, 0xed8d, 0x4d77, {0x9e, 0xc4, 0x39, 0x9a, 0x8a, 0x81, 0x51, 0x16 } }
@@ -572,6 +589,10 @@
gEfiPrint2ProtocolGuid = { 0xf05976ef, 0x83f1, 0x4f3d, { 0x86, 0x19, 0xf7, 0x59, 0x5d, 0x41, 0xe5, 0x38 } }
gEfiPrint2SProtocolGuid = { 0xcc252d2, 0xc106, 0x4661, { 0xb5, 0xbd, 0x31, 0x47, 0xa4, 0xf8, 0x1f, 0x92 } }
+ ## This protocol defines the Media Clear and Sanitize operations defined by NIST
+ # Include/Protocol/MediaSanitize.h
+ gMediaSanitizeProtocolGuid = { 0x0d799a99, 0x25af, 0x429e, {0x92, 0x72, 0xd0, 0xb2, 0x7d, 0x6d, 0x5f, 0x14 } }
+
## This protocol defines the generic memory test interfaces in Dxe phase.
# Include/Protocol/GenericMemoryTest.h
gEfiGenericMemTestProtocolGuid = { 0x309DE7F1, 0x7F5E, 0x4ACE, { 0xB4, 0x9C, 0x53, 0x1B, 0xE5, 0xAA, 0x95, 0xEF }}
@@ -1173,6 +1194,10 @@
# @Prompt Delay access XHCI register after it issues HCRST (us)
gEfiMdeModulePkgTokenSpaceGuid.PcdDelayXhciHCReset|2000|UINT16|0x30001060
+ ## Specifies the page count allocated for the MM communication buffer.
+ # @Prompt Defines the page allocation for the MM communication buffer; default is 128 pages (512KB).
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages|128|UINT32|0x30001061
+
[PcdsFixedAtBuild, PcdsPatchableInModule]
## Dynamic type PCD can be registered callback function for Pcd setting action.
# PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of callback function
@@ -1690,6 +1715,11 @@
# @Prompt SPI NOR Flash Operation Delay in Microseconds (16 us)
gEfiMdeModulePkgTokenSpaceGuid.PcdSpiNorFlashOperationDelayMicroseconds|0x00000010|UINT32|0x00000035
+ ## Indicate the default timeout value for UFS device initial completetion in microseconds.
+ #
+ # @Prompt UFS device initial completion timoeout (us), default value is 600ms.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUfsInitialCompletionTimeout|600000|UINT32|0x00000036
+
[PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
## This PCD defines the Console output row. The default value is 25 according to UEFI spec.
# This PCD could be set to 0 then console output would be at max column and max row.
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index a1c8e2f..f8204f7 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -2,7 +2,7 @@
# EFI/PI Reference Module Package for All Architectures
#
# (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
-# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation.
# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
#
@@ -109,6 +109,10 @@
IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf
SpiHcPlatformLib|MdeModulePkg/Library/BaseSpiHcPlatformLibNull/BaseSpiHcPlatformLibNull.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.EBC.PEIM]
IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf
@@ -178,23 +182,12 @@
MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxStandaloneMmLib.inf
MemLib|StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
+ VarCheckHiiLibMmDependency|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf
+ VarCheckHiiLib|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf
[LibraryClasses.ARM, LibraryClasses.AARCH64]
LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
- #
- # It is not possible to prevent ARM compiler calls to generic intrinsic functions.
- # This library provides the instrinsic functions generated by a given compiler.
- # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
- #
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- #
- # Since software stack checking may be heuristically enabled by the compiler
- # include BaseStackCheckLib unconditionally.
- #
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
[LibraryClasses.EBC, LibraryClasses.RISCV64, LibraryClasses.LOONGARCH64]
LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
@@ -339,6 +332,8 @@
MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf
+ MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibMmDependency.inf
+ MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.inf
MdeModulePkg/Library/PlatformVarCleanupLib/PlatformVarCleanupLib.inf
MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
MdeModulePkg/Library/DxeFileExplorerProtocol/DxeFileExplorerProtocol.inf
@@ -353,6 +348,7 @@
MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf
MdeModulePkg/Library/DisplayUpdateProgressLibText/DisplayUpdateProgressLibText.inf
MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
+ MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf
MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
diff --git a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
index 198cdd8..5ee5053 100644
--- a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
+++ b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
@@ -60,6 +60,11 @@
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
}
+ MdeModulePkg/Bus/Pci/NvmExpressDxe/UnitTest/MediaSanitizeUnitTestHost.inf {
+ <LibraryClasses>
+ NvmExpressDxe|MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+ }
+
#
# Build HOST_APPLICATION Libraries
#
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h
index 9cfef3d..3caa20d 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h
@@ -127,6 +127,12 @@ typedef struct {
)
//
+// ACPI HOB produced by silicon initialization code will provide the RSDP structure.
+//
+typedef struct {
+ EFI_PHYSICAL_ADDRESS Rsdp;
+} ACPI_SILICON_HOB;
+//
// Protocol Constructor functions
//
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
index be498a5..8d147a3 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
@@ -57,6 +57,7 @@
gEfiAcpi10TableGuid ## PRODUCES ## SystemTable
gEfiAcpiTableGuid ## PRODUCES ## SystemTable
gUniversalPayloadAcpiTableGuid ## SOMETIMES_CONSUMES ## HOB
+ gAcpiTableHobGuid ## SOMETIMES_CONSUMES ## HOB
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol ## CONSUMES
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
index 45c0ae6..f2a7be5 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
@@ -1948,6 +1948,107 @@ InstallAcpiTableFromHob (
}
/**
+ This function is updating the instance with RSDP and RSDT, these are steps in the constructor that will be skipped if this HOB is available.
+
+ @param AcpiTableInstance Protocol instance private data.
+ @param GuidHob GUID HOB header.
+
+ @return EFI_SUCCESS The function completed successfully.
+ @return EFI_NOT_FOUND The function doesn't find the Rsdp from AcpiSiliconHob.
+ @return EFI_ABORTED The function could not complete successfully.
+
+**/
+EFI_STATUS
+InstallAcpiTableFromAcpiSiliconHob (
+ EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
+ EFI_HOB_GUID_TYPE *GuidHob
+ )
+{
+ ACPI_SILICON_HOB *AcpiSiliconHob;
+ EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *SiAcpiHobRsdp;
+ EFI_ACPI_DESCRIPTION_HEADER *SiCommonAcpiTable;
+ EFI_STATUS Status;
+ UINT8 *TempBuffer;
+ UINTN NumOfTblEntries;
+
+ DEBUG ((DEBUG_INFO, "InstallAcpiTableFromAcpiSiliconHob\n"));
+ //
+ // Initial variable.
+ //
+ SiAcpiHobRsdp = NULL;
+ SiCommonAcpiTable = NULL;
+ AcpiSiliconHob = GET_GUID_HOB_DATA (GuidHob);
+ Status = EFI_SUCCESS;
+ //
+ // Got RSDP table from ACPI Silicon Hob.
+ //
+ SiAcpiHobRsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)(AcpiSiliconHob->Rsdp);
+ if (SiAcpiHobRsdp == NULL) {
+ DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromAcpiSiliconHob: Fail to locate RSDP Acpi table!!\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((DEBUG_INFO, "Silicon ACPI RSDP address : 0x%lx\n", SiAcpiHobRsdp));
+ AcpiTableInstance->Rsdp3 = SiAcpiHobRsdp;
+
+ if (SiAcpiHobRsdp->RsdtAddress != 0x00000000) {
+ //
+ // Initial RSDT.
+ //
+ TempBuffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->RsdtAddress);
+ SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)TempBuffer;
+ AcpiTableInstance->Rsdt3 = SiCommonAcpiTable;
+
+ if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
+ DEBUG ((DEBUG_ERROR, "RSDT length is incorrect\n"));
+ return EFI_ABORTED;
+ }
+
+ //
+ // Calcaue 32bit Acpi table number.
+ //
+ NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT32);
+ AcpiTableInstance->NumberOfTableEntries1 = NumOfTblEntries;
+ DEBUG ((DEBUG_INFO, "32bit NumOfTblEntries : 0x%x\n", NumOfTblEntries));
+ //
+ // Enlarge the max table number from mEfiAcpiMaxNumTables to current ACPI tables + EFI_ACPI_MAX_NUM_TABLES
+ //
+ if (AcpiTableInstance->NumberOfTableEntries1 >= EFI_ACPI_MAX_NUM_TABLES) {
+ mEfiAcpiMaxNumTables = AcpiTableInstance->NumberOfTableEntries1 + EFI_ACPI_MAX_NUM_TABLES;
+ DEBUG ((DEBUG_ERROR, "mEfiAcpiMaxNumTables : 0x%x\n", mEfiAcpiMaxNumTables));
+ }
+ } else {
+ //
+ // Initial XSDT.
+ //
+ TempBuffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->XsdtAddress);
+ SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)TempBuffer;
+ AcpiTableInstance->Xsdt = SiCommonAcpiTable;
+
+ if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
+ DEBUG ((DEBUG_ERROR, "XSDT length is incorrect\n"));
+ return EFI_ABORTED;
+ }
+
+ //
+ // Calcaue 64bit Acpi table number.
+ //
+ NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT64);
+ AcpiTableInstance->NumberOfTableEntries3 = NumOfTblEntries;
+ DEBUG ((DEBUG_ERROR, "64bit NumOfTblEntries : 0x%x\n", NumOfTblEntries));
+ //
+ // Enlarge the max table number from mEfiAcpiMaxNumTables to current ACPI tables + EFI_ACPI_MAX_NUM_TABLES
+ //
+ if (AcpiTableInstance->NumberOfTableEntries3 >= EFI_ACPI_MAX_NUM_TABLES) {
+ mEfiAcpiMaxNumTables = AcpiTableInstance->NumberOfTableEntries3 + EFI_ACPI_MAX_NUM_TABLES;
+ DEBUG ((DEBUG_ERROR, "mEfiAcpiMaxNumTables : 0x%x\n", mEfiAcpiMaxNumTables));
+ }
+ }
+
+ return Status;
+}
+
+/**
Constructor for the ACPI table protocol. Initializes instance
data.
@@ -1969,6 +2070,7 @@ AcpiTableAcpiTableConstructor (
UINT8 *Pointer;
EFI_PHYSICAL_ADDRESS PageAddress;
EFI_MEMORY_TYPE AcpiAllocateMemoryType;
+ EFI_HOB_GUID_TYPE *GuidHob;
//
// Check for invalid input parameters
@@ -1996,6 +2098,23 @@ AcpiTableAcpiTableConstructor (
}
//
+ // Check Silicon ACPI Hob.
+ //
+ GuidHob = GetFirstGuidHob (&gAcpiTableHobGuid);
+ if (GuidHob != NULL) {
+ Status = InstallAcpiTableFromAcpiSiliconHob (AcpiTableInstance, GuidHob);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((DEBUG_INFO, "Installed ACPI Table from AcpiSiliconHob.\n"));
+ return EFI_SUCCESS;
+ } else {
+ DEBUG ((DEBUG_ERROR, "Fail to Installed ACPI Table from AcpiSiliconHob!!\n"));
+ ASSERT (Status != EFI_SUCCESS);
+ }
+ } else {
+ DEBUG ((DEBUG_INFO, "Fail to locate AcpiSiliconHob!!\n"));
+ }
+
+ //
// Create RSDP table
//
RsdpTableSize = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
diff --git a/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c b/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c
index 700ea9d..a7f0225 100644
--- a/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c
+++ b/MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatform.c
@@ -27,6 +27,15 @@ EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextOutDriverBinding = {
NULL
};
+//
+// Values from Usb Inteface Association Descriptor Device
+// Class Code and Usage Model specification (iadclasscode_r10.pdf)
+// from Usb.org
+//
+#define USB_BASE_CLASS_MISCELLANEOUS 0xEF
+#define USB_MISCELLANEOUS_SUBCLASS_COMMON 0x02
+#define USB_MISCELLANEOUS_PROTOCOL_IAD 0x01
+
/**
Entrypoint of this module.
@@ -808,10 +817,16 @@ MatchUsbClass (
DeviceClass = DevDesc.DeviceClass;
DeviceSubClass = DevDesc.DeviceSubClass;
DeviceProtocol = DevDesc.DeviceProtocol;
- if (DeviceClass == 0) {
+
+ if ((DeviceClass == 0) ||
+ ((DeviceClass == USB_BASE_CLASS_MISCELLANEOUS) &&
+ (DeviceSubClass == USB_MISCELLANEOUS_SUBCLASS_COMMON) &&
+ (DeviceProtocol == USB_MISCELLANEOUS_PROTOCOL_IAD)))
+ {
//
- // If Class in Device Descriptor is set to 0, use the Class, SubClass and
- // Protocol in Interface Descriptor instead.
+ // If Class in Device Descriptor is set to 0 (Device), or
+ // Class/SubClass/Protocol is 0xEF/0x02/0x01 (IAD), use the Class, SubClass
+ // and Protocol in Interface Descriptor instead.
//
Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc);
if (EFI_ERROR (Status)) {
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
index 7581cda..61fbd80 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
@@ -1216,8 +1216,8 @@ AnsiRawDataToUnicode (
Putty function key map:
+=========+======+===========+=============+=============+=============+=========+
| | EFI | | | | | |
- | | Scan | | | Normal | | |
- | KEY | Code | VT100+ | Xterm R6 | VT400 | Linux | SCO |
+ | | Scan | VT100+ | | Normal | | |
+ | KEY | Code | VTUTF8 | Xterm R6 | VT400 | Linux | SCO |
+=========+======+===========+=============+=============+=============+=========+
| F1 | 0x0B | ESC O P | ESC O P | ESC [ 1 1 ~ | ESC [ [ A | ESC [ M |
| F2 | 0x0C | ESC O Q | ESC O Q | ESC [ 1 2 ~ | ESC [ [ B | ESC [ N |
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
index aafa65f..dd31347 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
@@ -95,6 +95,10 @@ TerminalConInReset (
);
}
+ if (!EFI_ERROR (Status)) {
+ Status = TerminalDevice->SerialIo->SetControl (TerminalDevice->SerialIo, EFI_SERIAL_DATA_TERMINAL_READY|EFI_SERIAL_REQUEST_TO_SEND);
+ }
+
return Status;
}
@@ -1313,8 +1317,8 @@ UnicodeToEfiKeyFlushState (
Putty function key map:
+=========+======+===========+=============+=============+=============+=========+
| | EFI | | | | | |
- | | Scan | | | Normal | | |
- | KEY | Code | VT100+ | Xterm R6 | VT400 | Linux | SCO |
+ | | Scan | VT100+ | | Normal | | |
+ | KEY | Code | VTUTF8 | Xterm R6 | VT400 | Linux | SCO |
+=========+======+===========+=============+=============+=============+=========+
| F1 | 0x0B | ESC O P | ESC O P | ESC [ 1 1 ~ | ESC [ [ A | ESC [ M |
| F2 | 0x0C | ESC O Q | ESC O Q | ESC [ 1 2 ~ | ESC [ [ B | ESC [ N |
@@ -1391,7 +1395,8 @@ UnicodeToEfiKey (
if ((UnicodeChar == 'O') && ((TerminalDevice->TerminalType == TerminalTypeVt100) ||
(TerminalDevice->TerminalType == TerminalTypeTtyTerm) ||
(TerminalDevice->TerminalType == TerminalTypeXtermR6) ||
- (TerminalDevice->TerminalType == TerminalTypeVt100Plus)))
+ (TerminalDevice->TerminalType == TerminalTypeVt100Plus) ||
+ (TerminalDevice->TerminalType == TerminalTypeVtUtf8)))
{
TerminalDevice->InputState |= INPUT_STATE_O;
TerminalDevice->ResetState = RESET_STATE_DEFAULT;
@@ -1565,7 +1570,9 @@ UnicodeToEfiKey (
Key.ScanCode = SCAN_END;
break;
}
- } else if (TerminalDevice->TerminalType == TerminalTypeVt100Plus) {
+ } else if ((TerminalDevice->TerminalType == TerminalTypeVt100Plus) ||
+ (TerminalDevice->TerminalType == TerminalTypeVtUtf8))
+ {
switch (UnicodeChar) {
case 'P':
Key.ScanCode = SCAN_F1;
diff --git a/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c b/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c
index 38af39f..54b634a 100644
--- a/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c
+++ b/MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIo.c
@@ -846,7 +846,8 @@ DiskIo2ReadWriteDisk (
LIST_ENTRY Subtasks;
DISK_IO_SUBTASK *Subtask;
DISK_IO2_TASK *Task;
- EFI_TPL OldTpl;
+ EFI_TPL SubtaskPerformTpl;
+ EFI_TPL SubtaskLockTpl;
BOOLEAN Blocking;
BOOLEAN SubtaskBlocking;
LIST_ENTRY *SubtasksPtr;
@@ -896,7 +897,7 @@ DiskIo2ReadWriteDisk (
ASSERT (!IsListEmpty (SubtasksPtr));
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+ SubtaskPerformTpl = gBS->RaiseTPL (TPL_CALLBACK);
for ( Link = GetFirstNode (SubtasksPtr), NextLink = GetNextNode (SubtasksPtr, Link)
; !IsNull (SubtasksPtr, Link)
; Link = NextLink, NextLink = GetNextNode (SubtasksPtr, NextLink)
@@ -977,7 +978,7 @@ DiskIo2ReadWriteDisk (
}
}
- gBS->RaiseTPL (TPL_NOTIFY);
+ SubtaskLockTpl = gBS->RaiseTPL (TPL_NOTIFY);
//
// Remove all the remaining subtasks when failure.
@@ -1012,7 +1013,8 @@ DiskIo2ReadWriteDisk (
FreePool (Task);
}
- gBS->RestoreTPL (OldTpl);
+ gBS->RestoreTPL (SubtaskLockTpl);
+ gBS->RestoreTPL (SubtaskPerformTpl);
return Status;
}
diff --git a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c
index 60cf3c8..2dac121 100644
--- a/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c
+++ b/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c
@@ -404,7 +404,8 @@ HiiCreateRamDisk (
);
} while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- return EFI_DEVICE_ERROR;
+ Status = EFI_DEVICE_ERROR;
+ goto ErrorExit;
}
}
@@ -431,7 +432,7 @@ HiiCreateRamDisk (
);
} while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- return Status;
+ goto ErrorExit;
}
//
@@ -442,6 +443,10 @@ HiiCreateRamDisk (
PrivateData->CreateMethod = RamDiskCreateHii;
return EFI_SUCCESS;
+
+ErrorExit:
+ gBS->FreePool (StartingAddr);
+ return Status;
}
/**
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
index 8c2d209..676f46d 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
@@ -43,7 +43,7 @@
Caution: This module requires additional review when modified.
This driver need to make sure the CommBuffer is not in the SMRAM range.
-Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -332,8 +332,8 @@ SmmFaultTolerantWriteHandler (
CommBufferPayloadSize = TempCommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE;
- if (!FtwSmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
- DEBUG ((DEBUG_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n"));
+ if (!FtwSmmIsPrimaryBufferValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+ DEBUG ((DEBUG_ERROR, "SmmFtwHandler: SMM Primary(communication buffer) is not valid!\n"));
return EFI_SUCCESS;
}
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h
index f717432..73799d3 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmCommon.h
@@ -2,7 +2,7 @@
The common header file for SMM FTW module and SMM FTW DXE Module.
-Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -85,19 +85,16 @@ MmFaultTolerantWriteInitialize (
);
/**
- This function checks if the buffer is valid per processor architecture and
- does not overlap with SMRAM.
+ This function checks if the Primary Buffer is valid.
@param Buffer The buffer start address to be checked.
@param Length The buffer length to be checked.
- @retval TRUE This buffer is valid per processor architecture and does not
- overlap with SMRAM.
- @retval FALSE This buffer is not valid per processor architecture or overlaps
- with SMRAM.
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
**/
BOOLEAN
-FtwSmmIsBufferOutsideSmmValid (
+FtwSmmIsPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
);
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.c
index 52922a0..af837f0 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.c
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.c
@@ -2,7 +2,7 @@
Parts of the SMM/MM implementation that are specific to standalone MM
-Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -14,19 +14,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "FaultTolerantWriteSmmCommon.h"
/**
- This function checks if the buffer is valid per processor architecture and
- does not overlap with SMRAM.
+ This function checks if the Primary Buffer is valid.
@param Buffer The buffer start address to be checked.
@param Length The buffer length to be checked.
- @retval TRUE This buffer is valid per processor architecture and does not
- overlap with SMRAM.
- @retval FALSE This buffer is not valid per processor architecture or overlaps
- with SMRAM.
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
**/
BOOLEAN
-FtwSmmIsBufferOutsideSmmValid (
+FtwSmmIsPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
)
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c
index a7241e6..d0a2184 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteTraditionalMm.c
@@ -2,7 +2,7 @@
Parts of the SMM/MM implementation that are specific to traditional MM
-Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved. <BR>
Copyright (c) 2018, Linaro, Ltd. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -14,7 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "FaultTolerantWriteSmmCommon.h"
/**
- This function checks if the buffer is valid per processor architecture and
+ This function checks if the Primary Buffer is valid per processor architecture and
does not overlap with SMRAM.
@param Buffer The buffer start address to be checked.
@@ -26,7 +26,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
with SMRAM.
**/
BOOLEAN
-FtwSmmIsBufferOutsideSmmValid (
+FtwSmmIsPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
)
diff --git a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c
index 508184f..d442ccb 100644
--- a/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c
+++ b/MdeModulePkg/Universal/FaultTolerantWriteDxe/FtwMisc.c
@@ -810,12 +810,18 @@ FtwGetLastWriteHeader (
FtwHeader = (EFI_FAULT_TOLERANT_WRITE_HEADER *)(FtwWorkSpaceHeader + 1);
Offset = sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER);
+ if (!CompareGuid (&FtwWorkSpaceHeader->Signature, &gEdkiiWorkingBlockSignatureGuid)) {
+ *FtwWriteHeader = FtwHeader;
+ return EFI_ABORTED;
+ }
+
while (FtwHeader->Complete == FTW_VALID_STATE) {
Offset += FTW_WRITE_TOTAL_SIZE (FtwHeader->NumberOfWrites, FtwHeader->PrivateDataSize);
//
// If Offset exceed the FTW work space boudary, return error.
//
- if (Offset >= FtwWorkSpaceSize) {
+
+ if ((Offset + sizeof (EFI_FAULT_TOLERANT_WRITE_HEADER)) >= FtwWorkSpaceSize) {
*FtwWriteHeader = FtwHeader;
return EFI_ABORTED;
}
diff --git a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.c b/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.c
index 663cfff..a47311c 100644
--- a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.c
+++ b/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.c
@@ -19,7 +19,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
#include <Library/UefiLib.h>
+#include <Guid/MmCommBuffer.h>
#include <Guid/PiSmmCommunicationRegionTable.h>
#define DEFAULT_COMMON_PI_SMM_COMMUNIATION_REGION_PAGES 4
@@ -44,8 +46,11 @@ SmmCommunicationBufferEntryPoint (
UINT32 DescriptorSize;
EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;
EFI_MEMORY_DESCRIPTOR *Entry;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ MM_COMM_BUFFER *MmCommBuffer;
DescriptorSize = sizeof (EFI_MEMORY_DESCRIPTOR);
+
//
// Make sure Size != sizeof(EFI_MEMORY_DESCRIPTOR). This will
// prevent people from having pointer math bugs in their code.
@@ -65,11 +70,21 @@ SmmCommunicationBufferEntryPoint (
PiSmmCommunicationRegionTable->DescriptorSize = DescriptorSize;
Entry = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1);
Entry->Type = EfiConventionalMemory;
- Entry->PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateReservedPages (DEFAULT_COMMON_PI_SMM_COMMUNIATION_REGION_PAGES);
+
+ GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid);
+
+ if (GuidHob == NULL) {
+ Entry->PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateReservedPages (DEFAULT_COMMON_PI_SMM_COMMUNIATION_REGION_PAGES);
+ Entry->NumberOfPages = DEFAULT_COMMON_PI_SMM_COMMUNIATION_REGION_PAGES;
+ } else {
+ MmCommBuffer = GET_GUID_HOB_DATA (GuidHob);
+ Entry->PhysicalStart = MmCommBuffer->PhysicalStart;
+ Entry->NumberOfPages = MmCommBuffer->NumberOfPages;
+ }
+
ASSERT (Entry->PhysicalStart != 0);
- Entry->VirtualStart = 0;
- Entry->NumberOfPages = DEFAULT_COMMON_PI_SMM_COMMUNIATION_REGION_PAGES;
- Entry->Attribute = 0;
+ Entry->VirtualStart = 0;
+ Entry->Attribute = 0;
DEBUG ((DEBUG_INFO, "PiSmmCommunicationRegionTable:(0x%x)\n", PiSmmCommunicationRegionTable));
DEBUG ((DEBUG_INFO, " Version - 0x%x\n", PiSmmCommunicationRegionTable->Version));
diff --git a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.inf b/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.inf
index 5c867ba..1c9bbdc 100644
--- a/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.inf
+++ b/MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.inf
@@ -47,6 +47,7 @@
[Guids]
gEdkiiPiSmmCommunicationRegionTableGuid ## PRODUCES ## SystemTable
+ gMmCommBufferHobGuid ## CONSUMES
[Depex]
TRUE
diff --git a/MdeModulePkg/Universal/Variable/Pei/Variable.c b/MdeModulePkg/Universal/Variable/Pei/Variable.c
index 26f95c6..9f3d434 100644
--- a/MdeModulePkg/Universal/Variable/Pei/Variable.c
+++ b/MdeModulePkg/Universal/Variable/Pei/Variable.c
@@ -1336,6 +1336,7 @@ CalculateHobVariableCacheSize (
VARIABLE_STORE_HEADER *VariableStoreHeader;
VariableStoreHeader = NULL;
+ ZeroMem (&StoreInfo, sizeof (VARIABLE_STORE_INFO));
GetHobVariableStore (&StoreInfo, &VariableStoreHeader);
if (VariableStoreHeader == NULL) {
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h
index 065c75a..969a4f7 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/PrivilegePolymorphic.h
@@ -7,7 +7,7 @@
vs. non-privileged driver code.
Copyright (c) 2017, Red Hat, Inc.<BR>
- Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -123,6 +123,21 @@ MmVariableServiceInitialize (
);
/**
+ This function checks if the Primary Buffer (CommBuffer) is valid.
+
+ @param Buffer The buffer start address to be checked.
+ @param Length The buffer length to be checked.
+
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
+**/
+BOOLEAN
+VariableSmmIsPrimaryBufferValid (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ );
+
+/**
This function checks if the buffer is valid per processor architecture and
does not overlap with SMRAM.
@@ -135,23 +150,19 @@ MmVariableServiceInitialize (
with SMRAM.
**/
BOOLEAN
-VariableSmmIsBufferOutsideSmmValid (
+VariableSmmIsNonPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
);
/**
- Whether the TCG or TCG2 protocols are installed in the UEFI protocol database.
- This information is used by the MorLock code to infer whether an existing
- MOR variable is legitimate or not.
-
- @retval TRUE Either the TCG or TCG2 protocol is installed in the UEFI
- protocol database
- @retval FALSE Neither the TCG nor the TCG2 protocol is installed in the UEFI
- protocol database
+ Whether the MOR variable is legitimate or not.
+
+ @retval TRUE MOR Variable is legitimate.
+ @retval FALSE MOR Variable in not legitimate.
**/
BOOLEAN
-VariableHaveTcgProtocols (
+VariableIsMorVariableLegitimate (
VOID
);
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c
index 28e8cc5..7f8b2a7 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c
@@ -475,7 +475,7 @@ MorLockInitAtEndOfDxe (
// can be deduced from the absence of the TCG / TCG2 protocols, as edk2's
// MOR implementation depends on (one of) those protocols.
//
- if (VariableHaveTcgProtocols ()) {
+ if (VariableIsMorVariableLegitimate ()) {
//
// The MOR variable originates from the platform firmware; set the MOR
// Control Lock variable to report the locking capability to the OS.
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
index f90ec70..b5e8bf6 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
@@ -84,7 +84,7 @@
gEfiVariableWriteArchProtocolGuid ## PRODUCES
gEfiVariableArchProtocolGuid ## PRODUCES
gEdkiiVariableLockProtocolGuid ## PRODUCES
- gEdkiiVariablePolicyProtocolGuid ## CONSUMES
+ gEdkiiVariablePolicyProtocolGuid ## PRODUCES
gEdkiiVarCheckProtocolGuid ## PRODUCES
[Guids]
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
index 5253c32..12b76a9 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
@@ -14,7 +14,7 @@
VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(),
SmmVariableGetStatistics() should also do validation based on its own knowledge.
-Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -497,8 +497,8 @@ SmmVariableHandler (
return EFI_SUCCESS;
}
- if (!VariableSmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
- DEBUG ((DEBUG_ERROR, "SmmVariableHandler: SMM communication buffer in SMRAM or overflow!\n"));
+ if (!VariableSmmIsPrimaryBufferValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+ DEBUG ((DEBUG_ERROR, "SmmVariableHandler: SMM Primary Buffer (CommBuffer) is not valid!\n"));
return EFI_SUCCESS;
}
@@ -864,7 +864,7 @@ SmmVariableHandler (
// Verify runtime buffers do not overlap with SMRAM ranges.
//
if ((RuntimeVariableCacheContext->RuntimeHobCache != NULL) &&
- !VariableSmmIsBufferOutsideSmmValid (
+ !VariableSmmIsNonPrimaryBufferValid (
(UINTN)RuntimeVariableCacheContext->RuntimeHobCache,
(UINTN)RuntimeVariableCacheContext->RuntimeHobCache->Size
))
@@ -874,7 +874,7 @@ SmmVariableHandler (
goto EXIT;
}
- if (!VariableSmmIsBufferOutsideSmmValid (
+ if (!VariableSmmIsNonPrimaryBufferValid (
(UINTN)RuntimeVariableCacheContext->RuntimeVolatileCache,
(UINTN)RuntimeVariableCacheContext->RuntimeVolatileCache->Size
))
@@ -884,7 +884,7 @@ SmmVariableHandler (
goto EXIT;
}
- if (!VariableSmmIsBufferOutsideSmmValid (
+ if (!VariableSmmIsNonPrimaryBufferValid (
(UINTN)RuntimeVariableCacheContext->RuntimeNvCache,
(UINTN)RuntimeVariableCacheContext->RuntimeNvCache->Size
))
@@ -894,7 +894,7 @@ SmmVariableHandler (
goto EXIT;
}
- if (!VariableSmmIsBufferOutsideSmmValid (
+ if (!VariableSmmIsNonPrimaryBufferValid (
(UINTN)RuntimeVariableCacheContext->PendingUpdate,
sizeof (*(RuntimeVariableCacheContext->PendingUpdate))
))
@@ -904,7 +904,7 @@ SmmVariableHandler (
goto EXIT;
}
- if (!VariableSmmIsBufferOutsideSmmValid (
+ if (!VariableSmmIsNonPrimaryBufferValid (
(UINTN)RuntimeVariableCacheContext->ReadLock,
sizeof (*(RuntimeVariableCacheContext->ReadLock))
))
@@ -914,7 +914,7 @@ SmmVariableHandler (
goto EXIT;
}
- if (!VariableSmmIsBufferOutsideSmmValid (
+ if (!VariableSmmIsNonPrimaryBufferValid (
(UINTN)RuntimeVariableCacheContext->HobFlushComplete,
sizeof (*(RuntimeVariableCacheContext->HobFlushComplete))
))
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c
index 943993e..1057822 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.c
@@ -2,15 +2,35 @@
Parts of the SMM/MM implementation that are specific to standalone MM
-Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved. <BR>
Copyright (c) 2018, Linaro, Ltd. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
+#include <Library/MmServicesTableLib.h>
+#include <Library/StandaloneMmMemLib.h>
#include "Variable.h"
/**
+ This function checks if the Primary Buffer (CommBuffer) is valid.
+
+ @param Buffer The buffer start address to be checked.
+ @param Length The buffer length to be checked.
+
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
+**/
+BOOLEAN
+VariableSmmIsPrimaryBufferValid (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ )
+{
+ return TRUE;
+}
+
+/**
This function checks if the buffer is valid per processor architecture and
does not overlap with SMRAM.
@@ -23,12 +43,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
with SMRAM.
**/
BOOLEAN
-VariableSmmIsBufferOutsideSmmValid (
+VariableSmmIsNonPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
)
{
- return TRUE;
+ return MmIsBufferOutsideMmValid (Buffer, Length);
}
/**
@@ -49,6 +69,17 @@ VariableNotifySmmWriteReady (
VOID
)
{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ Handle = NULL;
+ Status = gMmst->MmInstallProtocolInterface (
+ &Handle,
+ &gSmmVariableWriteGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
}
/**
@@ -71,19 +102,15 @@ VariableServiceInitialize (
}
/**
- Whether the TCG or TCG2 protocols are installed in the UEFI protocol database.
- This information is used by the MorLock code to infer whether an existing
- MOR variable is legitimate or not.
-
- @retval TRUE Either the TCG or TCG2 protocol is installed in the UEFI
- protocol database
- @retval FALSE Neither the TCG nor the TCG2 protocol is installed in the UEFI
- protocol database
+ Whether the MOR variable is legitimate or not.
+
+ @retval TRUE MOR Variable is legitimate.
+ @retval FALSE MOR Variable in not legitimate.
**/
BOOLEAN
-VariableHaveTcgProtocols (
+VariableIsMorVariableLegitimate (
VOID
)
{
- return FALSE;
+ return TRUE;
}
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
index f09bed4..2d651c3 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
@@ -18,7 +18,7 @@
# may not be modified without authorization. If platform fails to protect these resources,
# the authentication service provided in this driver will be broken, and the behavior is undefined.
#
-# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -71,6 +71,7 @@
BaseMemoryLib
DebugLib
HobLib
+ MemLib
MemoryAllocationLib
MmServicesTableLib
SafeIntLib
@@ -114,6 +115,7 @@
gEfiMemoryOverwriteControlDataGuid ## SOMETIMES_CONSUMES ## Variable:L"MemoryOverwriteRequestControl"
gEfiMemoryOverwriteRequestControlLockGuid ## SOMETIMES_PRODUCES ## Variable:L"MemoryOverwriteRequestControlLock"
+ gSmmVariableWriteGuid ## PRODUCES ## GUID # Install protocol
gEfiSystemNvDataFvGuid ## CONSUMES ## GUID
gEdkiiFaultTolerantWriteGuid ## SOMETIMES_CONSUMES ## HOB
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c
index 0369c3c..cd82bb5 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableTraditionalMm.c
@@ -2,7 +2,7 @@
Parts of the SMM/MM implementation that are specific to traditional MM
-Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved. <BR>
Copyright (c) 2018, Linaro, Ltd. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -13,6 +13,24 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "Variable.h"
/**
+ This function checks if the Primary Buffer (CommBuffer) is valid.
+
+ @param Buffer The buffer start address to be checked.
+ @param Length The buffer length to be checked.
+
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
+**/
+BOOLEAN
+VariableSmmIsPrimaryBufferValid (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ )
+{
+ return SmmIsBufferOutsideSmmValid (Buffer, Length);
+}
+
+/**
This function checks if the buffer is valid per processor architecture and
does not overlap with SMRAM.
@@ -25,7 +43,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
with SMRAM.
**/
BOOLEAN
-VariableSmmIsBufferOutsideSmmValid (
+VariableSmmIsNonPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
)
@@ -100,12 +118,12 @@ VariableServiceInitialize (
MOR variable is legitimate or not.
@retval TRUE Either the TCG or TCG2 protocol is installed in the UEFI
- protocol database
+ protocol database. MOR variable is legitimate.
@retval FALSE Neither the TCG nor the TCG2 protocol is installed in the UEFI
- protocol database
+ protocol database. MOR variable is not legitimate.
**/
BOOLEAN
-VariableHaveTcgProtocols (
+VariableIsMorVariableLegitimate (
VOID
)
{
diff --git a/ArmPkg/Include/AsmMacroIoLibV8.h b/MdePkg/Include/AArch64/AsmMacroLib.h
index a5c8635..a5c8635 100644
--- a/ArmPkg/Include/AsmMacroIoLibV8.h
+++ b/MdePkg/Include/AArch64/AsmMacroLib.h
diff --git a/ArmPkg/Include/AsmMacroIoLib.h b/MdePkg/Include/Arm/AsmMacroLib.h
index 2493a15..2493a15 100644
--- a/ArmPkg/Include/AsmMacroIoLib.h
+++ b/MdePkg/Include/Arm/AsmMacroLib.h
diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h
index 7caebbe..363e0fe 100644
--- a/MdePkg/Include/Base.h
+++ b/MdePkg/Include/Base.h
@@ -1058,7 +1058,7 @@ typedef UINTN RETURN_STATUS;
@retval FALSE The high bit of StatusCode is clear.
**/
-#define RETURN_ERROR(StatusCode) (((INTN)(RETURN_STATUS)(StatusCode)) < 0)
+#define RETURN_ERROR(StatusCode) (((RETURN_STATUS)(StatusCode)) >= MAX_BIT)
///
/// The operation completed successfully.
diff --git a/MdePkg/Include/ConfidentialComputingGuestAttr.h b/MdePkg/Include/ConfidentialComputingGuestAttr.h
index 44e6df8..f62158f 100644
--- a/MdePkg/Include/ConfidentialComputingGuestAttr.h
+++ b/MdePkg/Include/ConfidentialComputingGuestAttr.h
@@ -29,9 +29,20 @@ typedef enum {
/* The guest is running with Intel TDX memory encryption enabled. */
CCAttrIntelTdx = 0x200,
+
+ CCAttrTypeMask = 0x000000000000ffff,
+
+ /* Features */
+
+ /* The AMD SEV-ES DebugVirtualization feature is enabled in SEV_STATUS */
+ CCAttrFeatureAmdSevEsDebugVirtualization = 0x0000000000010000,
+
+ CCAttrFeatureMask = 0xffffffffffff0000,
} CONFIDENTIAL_COMPUTING_GUEST_ATTR;
-#define CC_GUEST_IS_TDX(x) ((x) == CCAttrIntelTdx)
-#define CC_GUEST_IS_SEV(x) ((x) == CCAttrAmdSev || (x) == CCAttrAmdSevEs || (x) == CCAttrAmdSevSnp)
+#define _CC_GUEST_IS_TDX(x) ((x) == CCAttrIntelTdx)
+#define CC_GUEST_IS_TDX(x) _CC_GUEST_IS_TDX((x) & CCAttrTypeMask)
+#define _CC_GUEST_IS_SEV(x) ((x) == CCAttrAmdSev || (x) == CCAttrAmdSevEs || (x) == CCAttrAmdSevSnp)
+#define CC_GUEST_IS_SEV(x) _CC_GUEST_IS_SEV((x) & CCAttrTypeMask)
#endif
diff --git a/MdePkg/Include/Guid/ConformanceProfiles.h b/MdePkg/Include/Guid/ConformanceProfiles.h
new file mode 100644
index 0000000..bf89ab6
--- /dev/null
+++ b/MdePkg/Include/Guid/ConformanceProfiles.h
@@ -0,0 +1,67 @@
+/** @file
+ GUIDs used for UEFI Conformance Profiles Table in the UEFI 2.10 specification.
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CONFORMANCE_PROFILES_TABLE_GUID_H_
+#define CONFORMANCE_PROFILES_TABLE_GUID_H_
+
+//
+// This table allows the platform to advertise its UEFI specification conformance
+// in the form of pre-defined profiles. Each profile is identified by a GUID, with
+// known profiles listed in the section below.
+// The absence of this table shall indicate that the platform implementation is
+// conformant with the UEFI specification requirements, as defined in Section 2.6.
+// This is equivalent to publishing this configuration table with the
+// EFI_CONFORMANCE_PROFILES_UEFI_SPEC_GUID conformance profile.
+//
+#define EFI_CONFORMANCE_PROFILES_TABLE_GUID \
+ { \
+ 0x36122546, 0xf7e7, 0x4c8f, { 0xbd, 0x9b, 0xeb, 0x85, 0x25, 0xb5, 0x0c, 0x0b } \
+ }
+
+#pragma pack(1)
+
+typedef struct {
+ ///
+ /// Version of the table must be 0x1
+ ///
+ UINT16 Version;
+ ///
+ /// The number of profiles GUIDs present in ConformanceProfiles
+ ///
+ UINT16 NumberOfProfiles;
+ ///
+ /// An array of conformance profile GUIDs that are supported by this system.
+ /// EFI_GUID ConformanceProfiles[];
+ ///
+} EFI_CONFORMANCE_PROFILES_TABLE;
+
+#pragma pack()
+
+#define EFI_CONFORMANCE_PROFILES_TABLE_VERSION 0x1
+
+//
+// GUID defined in UEFI 2.10
+//
+#define EFI_CONFORMANCE_PROFILES_UEFI_SPEC_GUID \
+ { 0x523c91af, 0xa195, 0x4382, \
+ { 0x81, 0x8d, 0x29, 0x5f, 0xe4, 0x00, 0x64, 0x65 }}
+
+//
+// GUID defined in EBBR
+//
+#define EFI_CONFORMANCE_PROFILE_EBBR_2_1_GUID \
+ { 0xcce33c35, 0x74ac, 0x4087, \
+ { 0xbc, 0xe7, 0x8b, 0x29, 0xb0, 0x2e, 0xeb, 0x27 }}
+#define EFI_CONFORMANCE_PROFILE_EBBR_2_2_GUID \
+ { 0x9073eed4, 0xe50d, 0x11ee, \
+ { 0xb8, 0xb0, 0x8b, 0x68, 0xda, 0x62, 0xfc, 0x80 }}
+
+extern EFI_GUID gEfiConfProfilesTableGuid;
+extern EFI_GUID gEfiConfProfilesUefiSpecGuid;
+
+#endif
diff --git a/MdePkg/Include/IndustryStandard/Acpi51.h b/MdePkg/Include/IndustryStandard/Acpi51.h
index 4241b8f..cdf9538 100644
--- a/MdePkg/Include/IndustryStandard/Acpi51.h
+++ b/MdePkg/Include/IndustryStandard/Acpi51.h
@@ -1760,6 +1760,7 @@ typedef struct {
#define EFI_ACPI_5_1_EINJ_EXECUTE_OPERATION 0x05
#define EFI_ACPI_5_1_EINJ_CHECK_BUSY_STATUS 0x06
#define EFI_ACPI_5_1_EINJ_GET_COMMAND_STATUS 0x07
+#define EFI_ACPI_5_1_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08
#define EFI_ACPI_5_1_EINJ_TRIGGER_ERROR 0xFF
///
diff --git a/MdePkg/Include/IndustryStandard/Acpi60.h b/MdePkg/Include/IndustryStandard/Acpi60.h
index 3757d3f..d545de1 100644
--- a/MdePkg/Include/IndustryStandard/Acpi60.h
+++ b/MdePkg/Include/IndustryStandard/Acpi60.h
@@ -1947,6 +1947,7 @@ typedef struct {
#define EFI_ACPI_6_0_EINJ_EXECUTE_OPERATION 0x05
#define EFI_ACPI_6_0_EINJ_CHECK_BUSY_STATUS 0x06
#define EFI_ACPI_6_0_EINJ_GET_COMMAND_STATUS 0x07
+#define EFI_ACPI_6_0_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08
#define EFI_ACPI_6_0_EINJ_TRIGGER_ERROR 0xFF
///
diff --git a/MdePkg/Include/IndustryStandard/Acpi61.h b/MdePkg/Include/IndustryStandard/Acpi61.h
index c3facc6..5100d8b 100644
--- a/MdePkg/Include/IndustryStandard/Acpi61.h
+++ b/MdePkg/Include/IndustryStandard/Acpi61.h
@@ -1979,6 +1979,8 @@ typedef struct {
#define EFI_ACPI_6_1_EINJ_EXECUTE_OPERATION 0x05
#define EFI_ACPI_6_1_EINJ_CHECK_BUSY_STATUS 0x06
#define EFI_ACPI_6_1_EINJ_GET_COMMAND_STATUS 0x07
+#define EFI_ACPI_6_1_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08
+#define EFI_ACPI_6_1_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09
#define EFI_ACPI_6_1_EINJ_TRIGGER_ERROR 0xFF
///
diff --git a/MdePkg/Include/IndustryStandard/Acpi62.h b/MdePkg/Include/IndustryStandard/Acpi62.h
index 4dd3e21..711b88b 100644
--- a/MdePkg/Include/IndustryStandard/Acpi62.h
+++ b/MdePkg/Include/IndustryStandard/Acpi62.h
@@ -2292,6 +2292,8 @@ typedef struct {
#define EFI_ACPI_6_2_EINJ_EXECUTE_OPERATION 0x05
#define EFI_ACPI_6_2_EINJ_CHECK_BUSY_STATUS 0x06
#define EFI_ACPI_6_2_EINJ_GET_COMMAND_STATUS 0x07
+#define EFI_ACPI_6_2_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08
+#define EFI_ACPI_6_2_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09
#define EFI_ACPI_6_2_EINJ_TRIGGER_ERROR 0xFF
///
diff --git a/MdePkg/Include/IndustryStandard/Acpi63.h b/MdePkg/Include/IndustryStandard/Acpi63.h
index 7582dcc..68798da 100644
--- a/MdePkg/Include/IndustryStandard/Acpi63.h
+++ b/MdePkg/Include/IndustryStandard/Acpi63.h
@@ -2252,6 +2252,8 @@ typedef struct {
#define EFI_ACPI_6_3_EINJ_EXECUTE_OPERATION 0x05
#define EFI_ACPI_6_3_EINJ_CHECK_BUSY_STATUS 0x06
#define EFI_ACPI_6_3_EINJ_GET_COMMAND_STATUS 0x07
+#define EFI_ACPI_6_3_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08
+#define EFI_ACPI_6_3_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09
#define EFI_ACPI_6_3_EINJ_TRIGGER_ERROR 0xFF
///
diff --git a/MdePkg/Include/IndustryStandard/Acpi64.h b/MdePkg/Include/IndustryStandard/Acpi64.h
index faf069a..bbe6a3c 100644
--- a/MdePkg/Include/IndustryStandard/Acpi64.h
+++ b/MdePkg/Include/IndustryStandard/Acpi64.h
@@ -2335,6 +2335,8 @@ typedef struct {
#define EFI_ACPI_6_4_EINJ_EXECUTE_OPERATION 0x05
#define EFI_ACPI_6_4_EINJ_CHECK_BUSY_STATUS 0x06
#define EFI_ACPI_6_4_EINJ_GET_COMMAND_STATUS 0x07
+#define EFI_ACPI_6_4_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08
+#define EFI_ACPI_6_4_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09
#define EFI_ACPI_6_4_EINJ_TRIGGER_ERROR 0xFF
///
diff --git a/MdePkg/Include/IndustryStandard/Acpi65.h b/MdePkg/Include/IndustryStandard/Acpi65.h
index b9616a3..62d2fac 100644
--- a/MdePkg/Include/IndustryStandard/Acpi65.h
+++ b/MdePkg/Include/IndustryStandard/Acpi65.h
@@ -2,7 +2,7 @@
ACPI 6.5 definitions from the ACPI Specification Revision 6.5 Aug, 2022.
Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2019 - 2023, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2019 - 2024, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2023, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -1057,6 +1057,26 @@ typedef struct {
#define EFI_ACPI_6_5_RASF_PATROL_SCRUB_COMMAND_STOP_PATROL_SCRUBBER 0x03
///
+/// ACPI RAS2 PCC Descriptor
+///
+typedef struct {
+ UINT8 PccId;
+ UINT8 Reserved[2];
+ UINT8 RasFeatureType;
+ UINT32 Instance;
+} EFI_ACPI_RAS2_PCC_DESCRIPTOR;
+
+///
+/// ACPI RAS2 Feature Table definition.
+///
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT16 Reserved;
+ UINT16 PccCount;
+ // EFI_ACPI_RAS2_PCC_DESCRIPTOR Descriptors[PccCount];
+} EFI_ACPI_6_5_RAS2_FEATURE_TABLE;
+
+///
/// Memory Power State Table definition.
///
typedef struct {
@@ -1621,7 +1641,7 @@ typedef struct {
#define EFI_ACPI_6_5_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION { 0x66F0D379, 0xB4F3, 0x4074, { 0xAC, 0x43, 0x0D, 0x33, 0x18, 0xB7, 0x8C, 0xDB }}
#define EFI_ACPI_6_5_NFIT_GUID_NVDIMM_CONTROL_REGION { 0x92F701F6, 0x13B4, 0x405D, { 0x91, 0x0B, 0x29, 0x93, 0x67, 0xE8, 0x23, 0x4C }}
#define EFI_ACPI_6_5_NFIT_GUID_NVDIMM_BLOCK_DATA_WINDOW_REGION { 0x91AF0530, 0x5D86, 0x470E, { 0xA6, 0xB0, 0x0A, 0x2D, 0xB9, 0x40, 0x82, 0x49 }}
-#define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE { 0x77AB535A, 0x45FC, 0x6.5B, { 0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }}
+#define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_VOLATILE { 0x77AB535A, 0x45FC, 0x624B, { 0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }}
#define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_VOLATILE { 0x3D5ABD30, 0x4175, 0x87CE, { 0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }}
#define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_DISK_REGION_PERSISTENT { 0x5CEA02C9, 0x4D07, 0x69D3, { 0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }}
#define EFI_ACPI_6_5_NFIT_GUID_RAM_DISK_SUPPORTING_VIRTUAL_CD_REGION_PERSISTENT { 0x08018188, 0x42CD, 0xBB48, { 0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }}
@@ -1949,7 +1969,7 @@ typedef struct {
///
/// HEST Version (as defined in ACPI 6.5 spec.)
///
-#define EFI_ACPI_6_5_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x01
+#define EFI_ACPI_6_5_HARDWARE_ERROR_SOURCE_TABLE_REVISION 0x02
//
// Error Source structure types.
@@ -2419,7 +2439,7 @@ typedef struct {
///
/// EINJ Version (as defined in ACPI 6.5 spec.)
///
-#define EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REVISION 0x01
+#define EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REVISION 0x02
///
/// EINJ Error Injection Actions
@@ -2432,6 +2452,10 @@ typedef struct {
#define EFI_ACPI_6_5_EINJ_EXECUTE_OPERATION 0x05
#define EFI_ACPI_6_5_EINJ_CHECK_BUSY_STATUS 0x06
#define EFI_ACPI_6_5_EINJ_GET_COMMAND_STATUS 0x07
+#define EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE_WITH_ADDRESS 0x08
+#define EFI_ACPI_6_5_EINJ_GET_EXECUTE_OPERATION_TIMINGS 0x09
+#define EFI_ACPI_6_5_EINJ_EINJV2_SET_ERROR_TYPE 0x10
+#define EFI_ACPI_6_5_EINJ_EINJV2_GET_ERROR_TYPE 0x11
#define EFI_ACPI_6_5_EINJ_TRIGGER_ERROR 0xFF
///
@@ -2940,6 +2964,54 @@ typedef struct {
#define EFI_ACPI_6_5_PHAT_FIRMWARE_HEALTH_DATA_RECORD_UNKNOWN 0x02
#define EFI_ACPI_6_5_PHAT_FIRMWARE_HEALTH_DATA_RECORD_ADVISORY 0x03
+///
+/// Reset Reason Health Record Vendor Data Entry
+///
+typedef struct {
+ GUID VendorDataID;
+ UINT16 Length;
+ UINT16 Revision;
+ // UINTN Data[];
+} EFI_ACPI_6_5_PHAT_RESET_REASON_HEALTH_RECORD_VENDOR_DATA_ENTRY;
+
+///
+/// Reset Reason Health Record Structure
+///
+typedef struct {
+ UINT8 SupportedSources;
+ UINT8 Source;
+ UINT8 SubSource;
+ UINT8 Reason;
+ UINT16 VendorCount;
+ // EFI_ACPI_6_5_PHAT_RESET_REASON_HEALTH_RECORD_VENDOR_DATA_ENTRY VendorSpecificResetReasonEntry[];
+} EFI_ACPI_6_5_PHAT_RESET_REASON_HEALTH_RECORD_STRUCTURE;
+
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_HEADER_GUID { 0x7a014ce2, 0xf263, 0x4b77, { 0xb8, 0x8a, 0xe6, 0x33, 0x6b, 0x78, 0x2c, 0x14 }}
+
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_UNKNOWN BIT0
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_HARDWARE BIT1
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_FIRMWARE BIT2
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_SOFTWARE BIT3
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_SUPPORTED_SOURCES_SUPERVISOR BIT4
+
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_UNKNOWN BIT0
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_HARDWARE BIT1
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_FIRMWARE BIT2
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_SOFTWARE BIT3
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_SOURCES_SUPERVISOR BIT4
+
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_UNKNOWN 0x00
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_COLD_BOOT 0x01
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_COLD_RESET 0x02
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_WARM_RESET 0x03
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_UPDATE 0x04
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_UNEXPECTED_RESET 0x20
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_FAULT 0x21
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_TIMEOUT 0x22
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_THERMAL 0x23
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_POWER_LOSS 0x24
+#define EFI_ACPI_6_5_PHAT_RESET_REASON_REASON_POWER_BUTTON 0x25
+
//
// Known table signatures
//
@@ -3070,6 +3142,11 @@ typedef struct {
#define EFI_ACPI_6_5_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE SIGNATURE_32('P', 'S', 'D', 'T')
///
+/// "RAS2" ACPI RAS2 Feature Table
+///
+#define EFI_ACPI_6_5_ACPI_RAS2_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', '2')
+
+///
/// "RASF" ACPI RAS Feature Table
///
#define EFI_ACPI_6_5_ACPI_RAS_FEATURE_TABLE_SIGNATURE SIGNATURE_32('R', 'A', 'S', 'F')
@@ -3264,6 +3341,11 @@ typedef struct {
///
#define EFI_ACPI_6_5_XEN_PROJECT_TABLE_SIGNATURE SIGNATURE_32('X', 'E', 'N', 'V')
+///
+/// "MPAM" Memory System Resource Partitioning and Monitoring Table
+///
+#define EFI_ACPI_MEMORY_SYSTEM_RESOURCE_PARTITIONING_AND_MONITORING_TABLE_SIGNATURE SIGNATURE_32('M', 'P', 'A', 'M')
+
#pragma pack()
#endif
diff --git a/MdePkg/Include/IndustryStandard/Http11.h b/MdePkg/Include/IndustryStandard/Http11.h
index 2137ef1..7636a9e 100644
--- a/MdePkg/Include/IndustryStandard/Http11.h
+++ b/MdePkg/Include/IndustryStandard/Http11.h
@@ -248,6 +248,34 @@
///
#define HTTP_EXPECT_100_CONTINUE "100-continue"
+///
+/// Content-Range Response Header
+/// The Content-Range response HTTP header indicates where in a
+/// full body message a partial message belongs.
+///
+#define HTTP_HEADER_CONTENT_RANGE "Content-Range"
+
+///
+/// Last-Modified Response Header
+/// The Last-Modified response HTTP header contains a date and time when
+/// the origin server believes the resource was last modified. It is used
+/// as a validator to determine if the resource is the same as the
+/// previously stored one. Less accurate than an ETag header,
+/// it is a fallback mechanism. Conditional requests containing
+/// If-Modified-Since or If-Unmodified-Since headers make use of this field.
+///
+#define HTTP_HEADER_LAST_MODIFIED "Last-Modified"
+
+///
+/// If Unmodified Since Request Header
+/// Makes the request for the resource conditional: the server will send
+/// the requested resource or accept it in the case of a POST or another
+/// non-safe method only if the resource has not been modified after the
+/// date specified by this HTTP header. If the resource has been modified
+/// after the specified date, the response will be a 412 Precondition Failed error.
+///
+#define HTTP_HEADER_IF_UNMODIFIED_SINCE "If-Unmodified-Since"
+
#pragma pack()
#endif
diff --git a/MdePkg/Include/IndustryStandard/IoRemappingTable.h b/MdePkg/Include/IndustryStandard/IoRemappingTable.h
index 544aa67..851ce00 100644
--- a/MdePkg/Include/IndustryStandard/IoRemappingTable.h
+++ b/MdePkg/Include/IndustryStandard/IoRemappingTable.h
@@ -43,8 +43,9 @@
#define EFI_ACPI_IORT_MEM_ACCESS_PROP_AH_RA BIT2
#define EFI_ACPI_IORT_MEM_ACCESS_PROP_AH_AHO BIT3
-#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CPM BIT0
-#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_DACS BIT1
+#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CPM BIT0
+#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_DACS BIT1
+#define EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CANWBS BIT2
#define EFI_ACPI_IORT_SMMUv1v2_MODEL_v1 0x0
#define EFI_ACPI_IORT_SMMUv1v2_MODEL_v2 0x1
@@ -60,7 +61,8 @@
#define EFI_ACPI_IORT_SMMUv1v2_INT_FLAG_EDGE 0x1
#define EFI_ACPI_IORT_SMMUv3_FLAG_COHAC_OVERRIDE BIT0
-#define EFI_ACPI_IORT_SMMUv3_FLAG_HTTU_OVERRIDE BIT1
+#define EFI_ACPI_IORT_SMMUv3_FLAG_HTTU_OVERRIDE BIT1 // HW update of Access Flag supported
+#define EFI_ACPI_IORT_SMMUv3_FLAG_HTTU_OVERRIDE_DS BIT2 // HW update of Access Flag + Dirty Flag supported
#define EFI_ACPI_IORT_SMMUv3_FLAG_PROXIMITY_DOMAIN BIT3
#define EFI_ACPI_IORT_SMMUv3_FLAG_DEVICEID_VALID BIT4
diff --git a/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h b/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h
index 6b26656..b821ad5 100644
--- a/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h
+++ b/MdePkg/Include/IndustryStandard/IpmiNetFnGroupExtension.h
@@ -2,12 +2,21 @@
IPMI 2.0 definitions from the IPMI Specification Version 2.0, Revision 1.1.
Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ - Arm Server Base Manageability Requirements (SBMR) Specification
+ Revision 2.0d, Section F
+ https://developer.arm.com/documentation/den0069
+
**/
#ifndef _IPMI_NET_FN_GROUP_EXTENSION_H_
#define _IPMI_NET_FN_GROUP_EXTENSION_H_
+#include <Pi/PiStatusCode.h>
+
//
// Net function definition for Group Extension command
//
@@ -17,4 +26,72 @@
// All Group Extension commands and their structure definitions to follow here
//
+///
+/// Constants and structure definitions for Boot Progress Codes
+///
+/// See Section F of the Arm Server Base Manageability Requirements 2.0 specification,
+/// https://developer.arm.com/documentation/den0069
+///
+
+#pragma pack(1)
+//
+// Definitions for send progress code command
+//
+#define IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_SEND 0x02
+
+//
+// Definitions for get progress code command
+//
+#define IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_GET 0x03
+
+//
+// Definitions for send and get progress code command response
+//
+#define IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_COMPLETED_NORMALLY 0x00
+#define IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_COMPLETED_ERROR 0x80
+#define IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_DEFINING_BODY 0xAE
+
+//
+// Structure for the format of the boot progress code data
+// See Table 29: SBMR Boot Progress Codes format
+//
+typedef struct {
+ EFI_STATUS_CODE_TYPE CodeType;
+ EFI_STATUS_CODE_VALUE CodeValue;
+ UINT8 Instance;
+} IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_FORMAT;
+
+//
+// Structure for the boot progress code send request
+//
+typedef struct {
+ UINT8 DefiningBody;
+ IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_FORMAT BootProgressCode;
+} IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_SEND_REQUEST;
+
+//
+// Structure for the boot progress code send response
+//
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 DefiningBody;
+} IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_SEND_RESPONSE;
+
+//
+// Structure for the boot progress code get request
+//
+typedef struct {
+ UINT8 DefiningBody;
+} IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_GET_REQUEST;
+
+//
+// Structure for the boot progress code get response
+//
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 DefiningBody;
+ IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_FORMAT BootProgressCode;
+} IPMI_GROUP_EXTENSION_BOOT_PROGRESS_CODE_GET_RESPONSE;
+#pragma pack()
+
#endif
diff --git a/MdePkg/Include/IndustryStandard/Mpam.h b/MdePkg/Include/IndustryStandard/Mpam.h
new file mode 100644
index 0000000..8358b35
--- /dev/null
+++ b/MdePkg/Include/IndustryStandard/Mpam.h
@@ -0,0 +1,246 @@
+/** @file
+ ACPI for Memory System Resource Partitioning and Monitoring 2.0 (MPAM) as
+ specified in ARM spec DEN0065
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Specification Reference:
+ - [1] ACPI for Memory System Resource Partitioning and Monitoring 2.0
+ (https://developer.arm.com/documentation/den0065/latest)
+
+ @par Glossary:
+ - MPAM - Memory System Resource Partitioning And Monitoring
+ - MSC - Memory System Component
+ - PCC - Platform Communication Channel
+ - RIS - Resource Instance Selection
+ - SMMU - Arm System Memory Management Unit
+ **/
+
+#ifndef MPAM_H_
+#define MPAM_H_
+
+#include <IndustryStandard/Acpi.h>
+
+///
+/// MPAM Revision
+///
+#define EFI_ACPI_MEMORY_SYSTEM_RESOURCE_PARTITIONING_AND_MONITORING_TABLE_REVISION (0x01)
+
+///
+/// MPAM Interrupt mode
+///
+#define EFI_ACPI_MPAM_INTERRUPT_LEVEL_TRIGGERED (0x0)
+#define EFI_ACPI_MPAM_INTERRUPT_EDGE_TRIGGERED (0x1)
+
+///
+/// MPAM Interrupt type
+///
+#define EFI_ACPI_MPAM_INTERRUPT_WIRED (0x0)
+
+///
+/// MPAM Interrupt affinity type
+///
+#define EFI_ACPI_MPAM_INTERRUPT_PROCESSOR_AFFINITY (0x0)
+#define EFI_ACPI_MPAM_INTERRUPT_PROCESSOR_CONTAINER_AFFINITY (0x1)
+
+///
+/// MPAM MSC affinity valid
+///
+#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_NOT_VALID (0x0)
+#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_VALID (0x1)
+
+///
+/// MPAM Interrupt flag - bit positions
+///
+#define EFI_ACPI_MPAM_INTERRUPT_MODE_SHIFT (0)
+#define EFI_ACPI_MPAM_INTERRUPT_TYPE_SHIFT (1)
+#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_TYPE_SHIFT (3)
+#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_VALID_SHIFT (4)
+#define EFI_ACPI_MPAM_INTERRUPT_RESERVED_SHIFT (5)
+
+///
+/// MPAM Interrupt flag - bit masks
+///
+#define EFI_ACPI_MPAM_INTERRUPT_MODE_MASK (0x1)
+#define EFI_ACPI_MPAM_INTERRUPT_TYPE_MASK (0x3)
+#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_TYPE_MASK (0x8)
+#define EFI_ACPI_MPAM_INTERRUPT_AFFINITY_VALID_MASK (0x10)
+#define EFI_ACPI_MPAM_INTERRUPT_RESERVED_MASK (0xFFFFFFE0)
+
+///
+/// MPAM Location types
+/// as described in document [1], table 11.
+///
+#define EFI_ACPI_MPAM_LOCATION_PROCESSOR_CACHE (0x0)
+#define EFI_ACPI_MPAM_LOCATION_MEMORY (0x1)
+#define EFI_ACPI_MPAM_LOCATION_SMMU (0x2)
+#define EFI_ACPI_MPAM_LOCATION_MEMORY_CACHE (0x3)
+#define EFI_ACPI_MPAM_LOCATION_ACPI_DEVICE (0x4)
+#define EFI_ACPI_MPAM_LOCATION_INTERCONNECT (0x5)
+#define EFI_ACPI_MPAM_LOCATION_UNKNOWN (0xFF)
+
+///
+/// MPAM Interface types
+/// as desscribed in document[1], table 4.
+///
+#define EFI_ACPI_MPAM_INTERFACE_MMIO (0x00)
+#define EFI_ACPI_MPAM_INTERFACE_PCC (0x0A)
+
+///
+/// MPAM Link types
+/// as described in document [1], table 19.
+///
+#define EFI_ACPI_MPAM_LINK_TYPE_NUMA (0x00)
+#define EFI_ACPI_MPAM_LINK_TYPE_PROC (0x01)
+
+#pragma pack(1)
+
+///
+/// MPAM MSC generic locator descriptor
+/// as described in document [1], table 12.
+///
+typedef struct {
+ UINT64 Descriptor1;
+ UINT32 Descriptor2;
+} EFI_ACPI_MPAM_GENERIC_LOCATOR;
+
+///
+/// MPAM processor cache locator descriptor
+/// as described in document [1], table 13.
+///
+typedef struct {
+ UINT64 CacheReference;
+ UINT32 Reserved;
+} EFI_ACPI_MPAM_CACHE_LOCATOR;
+
+///
+/// MPAM memory locator descriptor
+/// as described in document [1], table 14.
+///
+typedef struct {
+ UINT64 ProximityDomain;
+ UINT32 Reserved;
+} EFI_ACPI_MPAM_MEMORY_LOCATOR;
+
+///
+/// MPAM SMMU locator descriptor
+/// as described in document [1], table 15.
+///
+typedef struct {
+ UINT64 SmmuInterface;
+ UINT32 Reserved;
+} EFI_ACPI_MPAM_SMMU_LOCATOR;
+
+///
+/// MPAM memory-side cache locator descriptor
+/// as described in Document [1], table 16.
+///
+typedef struct {
+ UINT8 Reserved[7];
+ UINT8 Level;
+ UINT32 Reference;
+} EFI_ACPI_MPAM_MEMORY_CACHE_LOCATOR;
+
+///
+/// MPAM ACPI device locator descriptor
+/// as described in document [1], table 17.
+///
+typedef struct {
+ UINT64 AcpiHardwareId;
+ UINT32 AcpiUniqueId;
+} EFI_ACPI_MPAM_ACPI_LOCATOR;
+
+///
+/// MPAM interconnect locator descriptor
+/// as described in document [1], table 18.
+///
+typedef struct {
+ UINT64 InterconnectDescTblOff;
+ UINT32 Reserved;
+} EFI_ACPI_MPAM_INTERCONNECT_LOCATOR;
+
+///
+/// MPAM interconnect descriptor
+/// as described in document [1], table 19.
+///
+typedef struct {
+ UINT32 SourceId;
+ UINT32 DestinationId;
+ UINT8 LinkType;
+ UINT8 Reserved[3];
+} EFI_ACPI_MPAM_INTERCONNECT_DESCRIPTOR;
+
+///
+/// MPAM interconnect descriptor table
+/// as described in document [1], table 20.
+///
+typedef struct {
+ UINT8 Signature[16];
+ UINT32 NumDescriptors;
+} EFI_ACPI_MPAM_INTERCONNECT_DESCRIPTOR_TABLE;
+
+///
+/// MPAM resource locator
+///
+typedef union {
+ EFI_ACPI_MPAM_CACHE_LOCATOR CacheLocator;
+ EFI_ACPI_MPAM_MEMORY_LOCATOR MemoryLocator;
+ EFI_ACPI_MPAM_SMMU_LOCATOR SmmuLocator;
+ EFI_ACPI_MPAM_MEMORY_CACHE_LOCATOR MemCacheLocator;
+ EFI_ACPI_MPAM_ACPI_LOCATOR AcpiLocator;
+ EFI_ACPI_MPAM_INTERCONNECT_LOCATOR InterconnectIfcLocator;
+ EFI_ACPI_MPAM_GENERIC_LOCATOR GenericLocator;
+} EFI_ACPI_MPAM_LOCATOR;
+
+///
+/// MPAM MSC node body
+/// as described document [1], table 4.
+///
+typedef struct {
+ UINT16 Length;
+ UINT8 InterfaceType;
+ UINT8 Reserved;
+ UINT32 Identifier;
+ UINT64 BaseAddress;
+ UINT32 MmioSize;
+ UINT32 OverflowInterrupt;
+ UINT32 OverflowInterruptFlags;
+ UINT32 Reserved1;
+ UINT32 OverflowInterruptAffinity;
+ UINT32 ErrorInterrupt;
+ UINT32 ErrorInterruptFlags;
+ UINT32 Reserved2;
+ UINT32 ErrorInterruptAffinity;
+ UINT32 MaxNrdyUsec;
+ UINT64 HardwareIdLinkedDevice;
+ UINT32 InstanceIdLinkedDevice;
+ UINT32 NumResources;
+} EFI_ACPI_MPAM_MSC_NODE;
+
+///
+/// MPAM MSC resource
+/// as described in document [1], table 9.
+///
+typedef struct {
+ UINT32 Identifier;
+ UINT8 RisIndex;
+ UINT16 Reserved1;
+ UINT8 LocatorType;
+ EFI_ACPI_MPAM_LOCATOR Locator;
+ UINT32 NumFunctionalDependencies;
+} EFI_ACPI_MPAM_MSC_RESOURCE;
+
+///
+/// MPAM Function dependency descriptor
+/// as described in document [1], table 10.
+///
+typedef struct {
+ UINT32 Producer;
+ UINT32 Reserved;
+} EFI_ACPI_MPAM_FUNCTIONAL_DEPENDENCY_DESCRIPTOR;
+
+#pragma pack()
+
+#endif
diff --git a/MdePkg/Include/IndustryStandard/Nvme.h b/MdePkg/Include/IndustryStandard/Nvme.h
index c190d67..ffb8b84 100644
--- a/MdePkg/Include/IndustryStandard/Nvme.h
+++ b/MdePkg/Include/IndustryStandard/Nvme.h
@@ -3,6 +3,7 @@
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
Copyright (c) 2017 - 2023, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Specification Reference:
@@ -27,10 +28,12 @@
#define NVME_INTMC_OFFSET 0x0010 // Interrupt Mask Clear
#define NVME_CC_OFFSET 0x0014 // Controller Configuration
#define NVME_CSTS_OFFSET 0x001c // Controller Status
-#define NVME_NSSR_OFFSET 0x0020 // NVM Subsystem Reset
+#define NVME_NSSR_OFFSET 0x0020 // NVM Subsystem Reset (Optional)
#define NVME_AQA_OFFSET 0x0024 // Admin Queue Attributes
#define NVME_ASQ_OFFSET 0x0028 // Admin Submission Queue Base Address
#define NVME_ACQ_OFFSET 0x0030 // Admin Completion Queue Base Address
+#define NVME_CMBLOC_OFFSET 0x0038 // Control Memory Buffer Location (Optional)
+#define NVME_CMBSZ_OFFSET 0x003C // Control Memory Buffer Size (Optional)
#define NVME_BPINFO_OFFSET 0x0040 // Boot Partition Information
#define NVME_BPRSEL_OFFSET 0x0044 // Boot Partition Read Select
#define NVME_BPMBL_OFFSET 0x0048 // Boot Partition Memory Buffer Location
@@ -54,16 +57,16 @@ typedef struct {
UINT8 Cqr : 1; // Contiguous Queues Required
UINT8 Ams : 2; // Arbitration Mechanism Supported
UINT8 Rsvd1 : 5;
- UINT8 To; // Timeout
- UINT16 Dstrd : 4;
+ UINT8 To; // Timeout
+ UINT16 Dstrd : 4; // Doorbell Stride
UINT16 Nssrs : 1; // NVM Subsystem Reset Supported NSSRS
UINT16 Css : 8; // Command Sets Supported - Bit 37
UINT16 Bps : 1; // Boot Partition Support - Bit 45 in NVMe1.4
UINT16 Rsvd3 : 2;
- UINT8 Mpsmin : 4;
- UINT8 Mpsmax : 4;
- UINT8 Pmrs : 1;
- UINT8 Cmbs : 1;
+ UINT8 Mpsmin : 4; // Memory Page Size Minimum
+ UINT8 Mpsmax : 4; // Memory Page Size Maximum
+ UINT8 Pmrs : 1; // Persistent Memory Region Supported
+ UINT8 Cmbs : 1; // Controller Memory Buffer Supported
UINT8 Rsvd4 : 6;
} NVME_CAP;
@@ -382,7 +385,21 @@ typedef struct {
UINT8 Cmic; /* Multi-interface Capabilities */
UINT8 Mdts; /* Maximum Data Transfer Size */
UINT8 Cntlid[2]; /* Controller ID */
- UINT8 Rsvd1[176]; /* Reserved as of Nvm Express 1.1 Spec */
+ UINT32 Ver; /* Version */
+ UINT32 Rtd3r; /* RTD3 Resume Latency */
+ UINT32 Rtd3e; /* RTD3 Entry Latency */
+ UINT32 Oaes; /* Optional Async Events Supported */
+ UINT32 Ctratt; /* Controller Attributes */
+ UINT16 Rrls; /* Read Recovery Levels Supported */
+ UINT8 Rsvd1[9]; /* Reserved as of NVM Express 1.4c Spec */
+ UINT8 Cntrltype; /* Controller Type */
+ UINT8 Fguid[16]; /* FRU Globally Unique Identifier */
+ UINT16 Crdt1; /* Command Retry Delay Time 1 */
+ UINT16 Crdt2; /* Command Retry Delay Time 2 */
+ UINT16 Crdt3; /* Command Retry Delay Time 3 */
+ UINT8 Rsvd2[106]; /* Reserved as of NVM Express 1.4c Spec */
+ UINT8 Rsvd3[16]; /* Reserved for NVMe MI Spec */
+
//
// Admin Command Set Attributes
//
@@ -418,30 +435,39 @@ typedef struct {
UINT16 Mntmt; /* Minimum Thermal Management Temperature */
UINT16 Mxtmt; /* Maximum Thermal Management Temperature */
NVME_SANICAP Sanicap; /* Sanitize Capabilities */
- UINT8 Rsvd2[180]; /* Reserved as of Nvm Express 1.4 Spec */
+ UINT32 Hmminds; /* Host Memory Buffer Minimum Descriptor Entry Size */
+ UINT16 Hmmaxd; /* Host Memory Maximum Descriptors Entries */
+ UINT16 Nsetidmax; /* NVM Set Identifier Maximum */
+ UINT16 Endgidmax; /* Endurance Group Identifier Maximum */
+ UINT8 Anatt; /* ANA Transition Time */
+ UINT8 Anacap; /* Asymmetric Namespace Access Capabilities */
+ UINT32 Anagrpmax; /* ANA Group Identifier Maximum */
+ UINT32 Nanagrpid; /* Number of ANA Group Identifiers */
+ UINT32 Pels; /* Persistent Event Log Size */
+ UINT8 Rsvd4[156]; /* Reserved as of NVM Express 1.4c Spec */
//
// NVM Command Set Attributes
//
- UINT8 Sqes; /* Submission Queue Entry Size */
- UINT8 Cqes; /* Completion Queue Entry Size */
- UINT16 Rsvd3; /* Reserved as of Nvm Express 1.1 Spec */
- UINT32 Nn; /* Number of Namespaces */
- UINT16 Oncs; /* Optional NVM Command Support */
- UINT16 Fuses; /* Fused Operation Support */
- UINT8 Fna; /* Format NVM Attributes */
- UINT8 Vwc; /* Volatile Write Cache */
- UINT16 Awun; /* Atomic Write Unit Normal */
- UINT16 Awupf; /* Atomic Write Unit Power Fail */
- UINT8 Nvscc; /* NVM Vendor Specific Command Configuration */
- UINT8 Rsvd4; /* Reserved as of Nvm Express 1.1 Spec */
- UINT16 Acwu; /* Atomic Compare & Write Unit */
- UINT16 Rsvd5; /* Reserved as of Nvm Express 1.1 Spec */
- UINT32 Sgls; /* SGL Support */
- UINT8 Rsvd6[164]; /* Reserved as of Nvm Express 1.1 Spec */
- //
- // I/O Command set Attributes
- //
- UINT8 Rsvd7[1344]; /* Reserved as of Nvm Express 1.1 Spec */
+ UINT8 Sqes; /* Submission Queue Entry Size */
+ UINT8 Cqes; /* Completion Queue Entry Size */
+ UINT16 Maxcmd; /* Maximum Outstanding Commands */
+ UINT32 Nn; /* Number of Namespaces */
+ UINT16 Oncs; /* Optional NVM Command Support */
+ UINT16 Fuses; /* Fused Operation Support */
+ UINT8 Fna; /* Format NVM Attributes */
+ UINT8 Vwc; /* Volatile Write Cache */
+ UINT16 Awun; /* Atomic Write Unit Normal */
+ UINT16 Awupf; /* Atomic Write Unit Power Fail */
+ UINT8 Nvscc; /* NVM Vendor Specific Command Configuration */
+ UINT8 Nwpc; /* Namespace Write Protection Capabilities */
+ UINT16 Acwu; /* Atomic Compare & Write Unit */
+ UINT16 Rsvd5; /* Reserved as of NVM Express 1.4c Spec */
+ UINT32 Sgls; /* SGL Support */
+ UINT32 Mnan; /* Maximum Number of Allowed Namespace */
+ UINT8 Rsvd6[224]; /* Reserved as of NVM Express 1.4c Spec */
+ UINT8 Subnqn[256]; /* NVM Subsystem NVMe Qualified Name */
+ UINT8 Rsvd7[768]; /* Reserved as of NVM Express 1.4c Spec */
+ UINT8 Rsvd8[256]; /* Reserved for NVMe over Fabrics Spec */
//
// Power State Descriptors
//
@@ -764,6 +790,10 @@ typedef struct {
UINT32 Rsvd1 : 20;
} NVME_ADMIN_FORMAT_NVM;
+#define SES_NO_SECURE_ERASE 0x0
+#define SES_USER_DATA_ERASE 0x1
+#define SES_CRYPTO_ERASE 0x2
+
//
// NvmExpress Admin Security Receive Command
//
diff --git a/MdePkg/Include/IndustryStandard/Pci.h b/MdePkg/Include/IndustryStandard/Pci.h
index 42c00ac..4220ad8 100644
--- a/MdePkg/Include/IndustryStandard/Pci.h
+++ b/MdePkg/Include/IndustryStandard/Pci.h
@@ -9,7 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#ifndef _PCI_H_
#define _PCI_H_
-#include <IndustryStandard/PciExpress50.h>
+#include <IndustryStandard/PciExpress60.h>
#include <IndustryStandard/PciCodeId.h>
#endif
diff --git a/MdePkg/Include/IndustryStandard/PciExpress21.h b/MdePkg/Include/IndustryStandard/PciExpress21.h
index 341e3e5..b437ca5 100644
--- a/MdePkg/Include/IndustryStandard/PciExpress21.h
+++ b/MdePkg/Include/IndustryStandard/PciExpress21.h
@@ -40,7 +40,7 @@ typedef union {
UINT16 SlotImplemented : 1;
UINT16 InterruptMessageNumber : 5;
UINT16 Undefined : 1;
- UINT16 Reserved : 1;
+ UINT16 FlitModeSupported : 1;
} Bits;
UINT16 Uint16;
} PCI_REG_PCIE_CAPABILITY;
@@ -64,11 +64,13 @@ typedef union {
UINT32 EndpointL1AcceptableLatency : 3;
UINT32 Undefined : 3;
UINT32 RoleBasedErrorReporting : 1;
- UINT32 Reserved : 2;
+ UINT32 ErrCorSubclassCapable : 1;
+ UINT32 RxMpsFixed : 1;
UINT32 CapturedSlotPowerLimitValue : 8;
UINT32 CapturedSlotPowerLimitScale : 2;
UINT32 FunctionLevelReset : 1;
- UINT32 Reserved2 : 3;
+ UINT32 MixedMpsSupported : 1;
+ UINT32 Reserved2 : 2;
} Bits;
UINT32 Uint32;
} PCI_REG_PCIE_DEVICE_CAPABILITY;
@@ -111,13 +113,14 @@ typedef union {
typedef union {
struct {
- UINT16 CorrectableError : 1;
- UINT16 NonFatalError : 1;
- UINT16 FatalError : 1;
- UINT16 UnsupportedRequest : 1;
- UINT16 AuxPower : 1;
- UINT16 TransactionsPending : 1;
- UINT16 Reserved : 10;
+ UINT16 CorrectableError : 1;
+ UINT16 NonFatalError : 1;
+ UINT16 FatalError : 1;
+ UINT16 UnsupportedRequest : 1;
+ UINT16 AuxPower : 1;
+ UINT16 TransactionsPending : 1;
+ UINT16 EmergencyPowerReductionDetected : 1;
+ UINT16 Reserved : 9;
} Bits;
UINT16 Uint16;
} PCI_REG_PCIE_DEVICE_STATUS;
@@ -146,7 +149,7 @@ typedef union {
typedef union {
struct {
UINT16 AspmControl : 2;
- UINT16 Reserved : 1;
+ UINT16 PtmPropagationDelayB : 1;
UINT16 ReadCompletionBoundary : 1;
UINT16 LinkDisable : 1;
UINT16 RetrainLink : 1;
@@ -156,6 +159,9 @@ typedef union {
UINT16 HardwareAutonomousWidthDisable : 1;
UINT16 LinkBandwidthManagementInterrupt : 1;
UINT16 LinkAutonomousBandwidthInterrupt : 1;
+ UINT16 SrisClocking : 1;
+ UINT16 FlitModeDisable : 1;
+ UINT16 DrsSignalingControl : 2;
} Bits;
UINT16 Uint16;
} PCI_REG_PCIE_LINK_CONTROL;
@@ -205,7 +211,9 @@ typedef union {
UINT16 PowerController : 1;
UINT16 ElectromechanicalInterlock : 1;
UINT16 DataLinkLayerStateChanged : 1;
- UINT16 Reserved : 3;
+ UINT16 AutoSlotPowerLimitDisable : 1;
+ UINT16 InbandPdDisable : 1;
+ UINT16 Reserved : 1;
} Bits;
UINT16 Uint16;
} PCI_REG_PCIE_SLOT_CONTROL;
@@ -233,7 +241,8 @@ typedef union {
UINT16 SystemErrorOnFatalError : 1;
UINT16 PmeInterrupt : 1;
UINT16 CrsSoftwareVisibility : 1;
- UINT16 Reserved : 11;
+ UINT16 NoNfmSubtree : 1;
+ UINT16 Reserved : 10;
} Bits;
UINT16 Uint16;
} PCI_REG_PCIE_ROOT_CONTROL;
@@ -268,7 +277,7 @@ typedef union {
UINT32 NoRoEnabledPrPrPassing : 1;
UINT32 LtrMechanism : 1;
UINT32 TphCompleter : 2;
- UINT32 LnSystemCLS : 2;
+ UINT32 Reserved : 2;
UINT32 TenBitTagCompleterSupported : 1;
UINT32 TenBitTagRequesterSupported : 1;
UINT32 Obff : 2;
@@ -277,7 +286,9 @@ typedef union {
UINT32 MaxEndEndTlpPrefixes : 2;
UINT32 EmergencyPowerReductionSupported : 2;
UINT32 EmergencyPowerReductionInitializationRequired : 1;
- UINT32 Reserved3 : 4;
+ UINT32 Reserved2 : 1;
+ UINT32 DmwrCompleter : 1;
+ UINT32 DmwrLengths : 2;
UINT32 FrsSupported : 1;
} Bits;
UINT32 Uint32;
@@ -330,10 +341,15 @@ typedef union {
typedef union {
struct {
- UINT32 Reserved : 1;
- UINT32 LinkSpeedsVector : 7;
- UINT32 Crosslink : 1;
- UINT32 Reserved2 : 23;
+ UINT32 Reserved : 1;
+ UINT32 LinkSpeedsVector : 7;
+ UINT32 Crosslink : 1;
+ UINT32 LowerSkpOsGeneration : 7;
+ UINT32 LowerSkpOsReception : 7;
+ UINT32 RetimerPresenceDetect : 1;
+ UINT32 TwoRetimersPresenceDetect : 1;
+ UINT32 Reserved2 : 6;
+ UINT32 DrsSupported : 1;
} Bits;
UINT32 Uint32;
} PCI_REG_PCIE_LINK_CAPABILITY2;
@@ -360,11 +376,25 @@ typedef union {
UINT16 EqualizationPhase2Successful : 1;
UINT16 EqualizationPhase3Successful : 1;
UINT16 LinkEqualizationRequest : 1;
- UINT16 Reserved : 10;
+ UINT16 RetimerPresence : 1;
+ UINT16 TwoRetimersPresence : 1;
+ UINT16 CrosslinkResolution : 2;
+ UINT16 FlitModeStatus : 1;
+ UINT16 Reserved : 1;
+ UINT16 DownstreamComponentPresence : 3;
+ UINT16 DRSMessageReceived : 1;
} Bits;
UINT16 Uint16;
} PCI_REG_PCIE_LINK_STATUS2;
+typedef union {
+ struct {
+ UINT32 InbandPdDisable : 1;
+ UINT32 Reserved : 30;
+ } Bits;
+ UINT32 Uint32;
+} PCI_REG_PCIE_SLOT_CAPABILITY2;
+
typedef struct {
EFI_PCI_CAPABILITY_HDR Hdr;
PCI_REG_PCIE_CAPABILITY Capability;
@@ -386,7 +416,7 @@ typedef struct {
PCI_REG_PCIE_LINK_CAPABILITY2 LinkCapability2;
PCI_REG_PCIE_LINK_CONTROL2 LinkControl2;
PCI_REG_PCIE_LINK_STATUS2 LinkStatus2;
- UINT32 SlotCapability2;
+ PCI_REG_PCIE_SLOT_CAPABILITY2 SlotCapability2;
UINT16 SlotControl2;
UINT16 SlotStatus2;
} PCI_CAPABILITY_PCIEXP;
diff --git a/MdePkg/Include/IndustryStandard/PciExpress60.h b/MdePkg/Include/IndustryStandard/PciExpress60.h
new file mode 100644
index 0000000..5427ddd
--- /dev/null
+++ b/MdePkg/Include/IndustryStandard/PciExpress60.h
@@ -0,0 +1,121 @@
+/** @file
+Support for the PCI Express 6.0 standard.
+
+This header file may not define all structures. Please extend as required.
+
+Copyright (c) 2024, American Megatrends International LLC. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCIEXPRESS60_H_
+#define PCIEXPRESS60_H_
+
+#include <IndustryStandard/PciExpress50.h>
+
+/// The Physical Layer PCI Express Extended Capability definitions.
+///
+/// Based on section 7.7.7 of PCI Express Base Specification 6.0.
+///@{
+#define PCI_EXPRESS_EXTENDED_CAPABILITY_PHYSICAL_LAYER_64_0_ID 0x0031
+#define PCI_EXPRESS_EXTENDED_CAPABILITY_PHYSICAL_LAYER_64_0_VER1 0x1
+
+// Register offsets from Physical Layer PCI-E Ext Cap Header
+#define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CAPABILITIES_OFFSET 0x04
+#define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CONTROL_OFFSET 0x08
+#define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_STATUS_OFFSET 0x0C
+#define PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_LANE_EQUALIZATION_CONTROL_OFFSET 0x10
+
+#define PCI_EXPRESS_EXTENDED_CAPABILITY_DEVICE3_ID 0x002F
+#define PCI_EXPRESS_EXTENDED_CAPABILITY_DEVICE3_VER1 0x1
+
+#define EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_3_OFFSET 0x04
+#define EFI_PCIE_CAPABILITY_DEVICE_CONTROL_3_OFFSET 0x08
+#define EFI_PCIE_CAPABILITY_DEVICE_STATUS_3_OFFSET 0x0C
+
+#pragma pack(1)
+
+typedef union {
+ struct {
+ UINT32 Reserved : 32; // Reserved bit 0:31
+ } Bits;
+ UINT32 Uint32;
+} PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CAPABILITIES;
+
+typedef union {
+ struct {
+ UINT32 Reserved : 32; // Reserved bit 0:31
+ } Bits;
+ UINT32 Uint32;
+} PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CONTROL;
+
+typedef union {
+ struct {
+ UINT32 EqualizationComplete : 1; // bit 0
+ UINT32 EqualizationPhase1Success : 1; // bit 1
+ UINT32 EqualizationPhase2Success : 1; // bit 2
+ UINT32 EqualizationPhase3Success : 1; // bit 3
+ UINT32 LinkEqualizationRequest : 1; // bit 4
+ UINT32 TransmitterPrecodingOn : 1; // bit 5
+ UINT32 TransmitterPrecodeRequest : 1; // bit 6
+ UINT32 NoEqualizationNeededRcvd : 1; // bit 7
+ UINT32 Reserved : 24; // Reserved bit 8:31
+ } Bits;
+ UINT32 Uint32;
+} PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_STATUS;
+
+typedef union {
+ struct {
+ UINT8 DownstreamPortTransmitterPreset : 4; // bit 0..3
+ UINT8 UpstreamPortTransmitterPreset : 4; // bit 4..7
+ } Bits;
+ UINT8 Uint8;
+} PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_LANE_EQUALIZATION_CONTROL;
+
+typedef struct {
+ PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER Header;
+ PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CAPABILITIES Capablities;
+ PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_CONTROL Control;
+ PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_STATUS Status;
+ PCI_EXPRESS_REG_PHYSICAL_LAYER_64_0_LANE_EQUALIZATION_CONTROL LaneEqualizationControl[1];
+} PCI_EXPRESS_EXTENDED_CAPABILITIES_PHYSICAL_LAYER_64_0;
+///@}
+
+typedef union {
+ struct {
+ UINT32 DmwrRequestRouting : 1; // bit 0
+ UINT32 FourteenBitTagCompleter : 1; // bit 1
+ UINT32 FourteenBitTagRequester : 1; // bit 2
+ UINT32 ReceiverL0p : 1; // bit 3
+ UINT32 PortL0pExitLatencyLatency : 3; // bit 4..6
+ UINT32 RetimerL0pExit : 3; // bit 7..9
+ UINT32 Reserved : 22; // bit 10..31
+ } Bits;
+ UINT32 Uint32;
+} PCI_REG_PCIE_DEVICE_CAPABILITY3;
+
+typedef union {
+ struct {
+ UINT32 DmwrRequesterEnable : 1; // bit 0
+ UINT32 DmwrEgressBlocking : 1; // bit 1
+ UINT32 FourteenBitTagRequesterEnable : 1; // bit 2
+ UINT32 L0pEnable : 1; // bit 3
+ UINT32 TargetLinkWidth : 3; // bit 4..6
+ UINT32 Reserved : 25; // bit 7..31
+ } Bits;
+ UINT32 Uint32;
+} PCI_REG_PCIE_DEVICE_CONTROL3;
+
+typedef union {
+ struct {
+ UINT32 InitialLinkWidth : 3; // bit 0..2
+ UINT32 SegmentCaptured : 1; // bit 3
+ UINT32 RemoteL0pSupported : 1; // bit 4
+ UINT32 Reserved : 27; // bit 5..31
+ } Bits;
+ UINT32 Uint32;
+} PCI_REG_PCIE_DEVICE_STATUS3;
+
+#pragma pack()
+
+#endif
diff --git a/MdePkg/Include/IndustryStandard/SmBios.h b/MdePkg/Include/IndustryStandard/SmBios.h
index 020733b..8ba6129 100644
--- a/MdePkg/Include/IndustryStandard/SmBios.h
+++ b/MdePkg/Include/IndustryStandard/SmBios.h
@@ -887,7 +887,8 @@ typedef enum {
ProcessorUpgradeSocketBGA2551 = 0x54,
ProcessorUpgradeSocketLGA1851 = 0x55,
ProcessorUpgradeSocketBGA2114 = 0x56,
- ProcessorUpgradeSocketBGA2833 = 0x57
+ ProcessorUpgradeSocketBGA2833 = 0x57,
+ ProcessorUpgradeInvalid = 0xFF
} PROCESSOR_UPGRADE;
///
@@ -1020,6 +1021,10 @@ typedef struct {
// Add for smbios 3.6
//
UINT16 ThreadEnabled;
+ //
+ // Add for smbios 3.8
+ //
+ SMBIOS_TABLE_STRING SocketType;
} SMBIOS_TABLE_TYPE4;
///
@@ -1524,7 +1529,7 @@ typedef struct {
UINT8 AsyncSurpriseRemoval : 1;
UINT8 FlexbusSlotCxl10Capable : 1;
UINT8 FlexbusSlotCxl20Capable : 1;
- UINT8 Reserved : 1; ///< Set to 0.
+ UINT8 FlexbusSlotCxl30Capable : 1; /// SMBIOS spec 3.7.0 updated CXL 3.0 support
} MISC_SLOT_CHARACTERISTICS2;
///
@@ -2027,6 +2032,13 @@ typedef struct {
//
UINT32 ExtendedSpeed;
UINT32 ExtendedConfiguredMemorySpeed;
+ //
+ // Add for smbios 3.7.0
+ //
+ UINT16 Pmic0ManufacturerID;
+ UINT16 Pmic0RevisionNumber;
+ UINT16 RcdManufacturerID;
+ UINT16 RcdRevisionNumber;
} SMBIOS_TABLE_TYPE17;
///
diff --git a/MdePkg/Include/IndustryStandard/Tdx.h b/MdePkg/Include/IndustryStandard/Tdx.h
index 2662761..17f1e8f 100644
--- a/MdePkg/Include/IndustryStandard/Tdx.h
+++ b/MdePkg/Include/IndustryStandard/Tdx.h
@@ -113,8 +113,8 @@ typedef struct {
typedef struct {
UINT64 Gpaw;
UINT64 Attributes;
- UINT32 MaxVcpus;
UINT32 NumVcpus;
+ UINT32 MaxVcpus;
UINT64 Resv[3];
} TDCALL_INFO_RETURN_DATA;
diff --git a/MdePkg/Include/IndustryStandard/Tpm20.h b/MdePkg/Include/IndustryStandard/Tpm20.h
index 4440f37..9303f16 100644
--- a/MdePkg/Include/IndustryStandard/Tpm20.h
+++ b/MdePkg/Include/IndustryStandard/Tpm20.h
@@ -203,15 +203,16 @@ typedef UINT16 TPM_ALG_ID;
// Table 8 - TPM_ECC_CURVE Constants
typedef UINT16 TPM_ECC_CURVE;
-#define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000)
-#define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001)
-#define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002)
-#define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003)
-#define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004)
-#define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005)
-#define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010)
-#define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011)
-#define TPM_ECC_SM2_P256 (TPM_ECC_CURVE)(0x0020)
+#define TPM_ECC_NONE (TPM_ECC_CURVE)(0x0000)
+#define TPM_ECC_NIST_P192 (TPM_ECC_CURVE)(0x0001)
+#define TPM_ECC_NIST_P224 (TPM_ECC_CURVE)(0x0002)
+#define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0003)
+#define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0004)
+#define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0005)
+#define TPM_ECC_BN_P256 (TPM_ECC_CURVE)(0x0010)
+#define TPM_ECC_BN_P638 (TPM_ECC_CURVE)(0x0011)
+#define TPM_ECC_SM2_P256 (TPM_ECC_CURVE)(0x0020)
+#define TPM_ECC_BP_P512_R1 (TPM_ECC_CURVE)(0x0032)
// Table 11 - TPM_CC Constants (Numeric Order)
typedef UINT32 TPM_CC;
diff --git a/MdePkg/Include/IndustryStandard/Tpm2Acpi.h b/MdePkg/Include/IndustryStandard/Tpm2Acpi.h
index e7d14f9..882e21d 100644
--- a/MdePkg/Include/IndustryStandard/Tpm2Acpi.h
+++ b/MdePkg/Include/IndustryStandard/Tpm2Acpi.h
@@ -3,6 +3,7 @@
Copyright (c) 2013 - 2019, Intel Corporation. All rights reserved. <BR>
Copyright (c) 2021, Ampere Computing LLC. All rights reserved. <BR>
+Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -18,6 +19,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define EFI_TPM2_ACPI_TABLE_REVISION_4 4
#define EFI_TPM2_ACPI_TABLE_REVISION EFI_TPM2_ACPI_TABLE_REVISION_4
+#define EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4 12
+#define EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE EFI_TPM2_ACPI_TABLE_START_METHOD_SPECIFIC_PARAMETERS_MAX_SIZE_REVISION_4
+
typedef struct {
EFI_ACPI_DESCRIPTION_HEADER Header;
// Flags field is replaced in version 4 and above
diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h
index 6a1503a..087cddf 100644
--- a/MdePkg/Include/Library/ArmLib.h
+++ b/MdePkg/Include/Library/ArmLib.h
@@ -182,24 +182,6 @@ ArmIsMpCore (
VOID
EFIAPI
-ArmInvalidateDataCache (
- VOID
- );
-
-VOID
-EFIAPI
-ArmCleanInvalidateDataCache (
- VOID
- );
-
-VOID
-EFIAPI
-ArmCleanDataCache (
- VOID
- );
-
-VOID
-EFIAPI
ArmInvalidateInstructionCache (
VOID
);
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 95f8055..9658026 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7,6 +7,7 @@ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.<BR>
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
+Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -126,6 +127,92 @@ typedef struct {
#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8
+/**
+ Reads the current value of CNTPCT_EL0 register.
+
+ Reads and returns the current value of CNTPCT_EL0.
+ This function is only available on AARCH64.
+
+ @return The current value of CNTPCT_EL0
+**/
+UINT64
+EFIAPI
+ArmReadCntPctReg (
+ VOID
+ );
+
+//
+// Bit shifts for the ID_AA64ISAR0_EL1 register.
+//
+#define ARM_ID_AA64ISAR0_EL1_AES_SHIFT (4U)
+#define ARM_ID_AA64ISAR0_EL1_SHA1_SHIFT (8U)
+#define ARM_ID_AA64ISAR0_EL1_SHA2_SHIFT (12U)
+#define ARM_ID_AA64ISAR0_EL1_CRC32_SHIFT (16U)
+#define ARM_ID_AA64ISAR0_EL1_ATOMIC_SHIFT (20U)
+#define ARM_ID_AA64ISAR0_EL1_RDM_SHIFT (28U)
+#define ARM_ID_AA64ISAR0_EL1_SHA3_SHIFT (32U)
+#define ARM_ID_AA64ISAR0_EL1_SM3_SHIFT (36U)
+#define ARM_ID_AA64ISAR0_EL1_SM4_SHIFT (40U)
+#define ARM_ID_AA64ISAR0_EL1_DP_SHIFT (44U)
+#define ARM_ID_AA64ISAR0_EL1_FHM_SHIFT (48U)
+#define ARM_ID_AA64ISAR0_EL1_TS_SHIFT (52U)
+#define ARM_ID_AA64ISAR0_EL1_TLB_SHIFT (56U)
+#define ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT (60U)
+
+//
+// Bit masks for the ID_AA64ISAR0_EL1 fields.
+//
+#define ARM_ID_AA64ISAR0_EL1_AES_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_SHA1_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_SHA2_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_CRC32_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_ATOMIC_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_RDM_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_SHA3_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_SM3_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_SM4_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_DP_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_FHM_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_TS_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_TLB_MASK (0xFU)
+#define ARM_ID_AA64ISAR0_EL1_RNDR_MASK (0xFU)
+
+//
+// Bit masks for the ID_AA64ISAR0_EL1 field values.
+//
+#define ARM_ID_AA64ISAR0_EL1_AES_FEAT_AES_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_AES_FEAT_PMULL_MASK (0x2U)
+#define ARM_ID_AA64ISAR0_EL1_SHA1_FEAT_SHA1_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA256_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_SHA2_FEAT_SHA512_MASK (0x2U)
+#define ARM_ID_AA64ISAR0_EL1_CRC32_HAVE_CRC32_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_ATOMIC_FEAT_LSE_MASK (0x2U)
+#define ARM_ID_AA64ISAR0_EL1_RDM_FEAT_RDM_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_SHA3_FEAT_SHA3_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_SM3_FEAT_SM3_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_SM4_FEAT_SM4_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_DP_FEAT_DOTPROD_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_FHM_FEAT_FHM_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_TS_FEAT_FLAGM_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_TS_FEAT_FLAGM2_MASK (0x2U)
+#define ARM_ID_AA64ISAR0_EL1_TLB_FEAT_TLBIOS_MASK (0x1U)
+#define ARM_ID_AA64ISAR0_EL1_TLB_FEAT_TLBIRANGE_MASK (0x2U)
+#define ARM_ID_AA64ISAR0_EL1_RNDR_FEAT_RNG_MASK (0x1U)
+
+/**
+ Reads the current value of ID_AA64ISAR0_EL1 register.
+
+ Reads and returns the current value of ID_AA64ISAR0_EL1.
+ This function is only available on AARCH64.
+
+ @return The current value of ID_AA64ISAR0_EL1
+**/
+UINT64
+EFIAPI
+ArmReadIdAA64Isar0Reg (
+ VOID
+ );
+
#endif // defined (MDE_CPU_AARCH64)
#if defined (MDE_CPU_RISCV64)
@@ -4900,6 +4987,23 @@ CalculateCrc32c (
IN UINT32 InitialValue
);
+/**
+ Calculates the CRC16-CCITT-FALSE checksum of the given buffer.
+
+ @param[in] Buffer Pointer to the buffer.
+ @param[in] Length Length of the buffer, in bytes.
+ @param[in] InitialValue Initial value of the CRC.
+
+ @return The CRC16-CCITT-FALSE checksum.
+**/
+UINT16
+EFIAPI
+CalculateCrc16CcittF (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 InitialValue
+ );
+
//
// Base Library CPU Functions
//
@@ -5155,8 +5259,6 @@ SpeculationBarrier (
VOID
);
-#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32)
-
/**
The TDCALL instruction causes a VM exit to the Intel TDX module. It is
used to call guest-side Intel TDX functions, either local or a TD exit
@@ -5219,8 +5321,6 @@ TdIsEnabled (
VOID
);
-#endif
-
#if defined (MDE_CPU_X64)
//
// The page size for the PVALIDATE instruction
diff --git a/MdePkg/Include/Library/DebugLib.h b/MdePkg/Include/Library/DebugLib.h
index 0db3b78..b074296 100644
--- a/MdePkg/Include/Library/DebugLib.h
+++ b/MdePkg/Include/Library/DebugLib.h
@@ -342,13 +342,13 @@ UnitTestDebugAssert (
#if defined (_ASSERT)
#undef _ASSERT
#endif
- #if defined (__clang__) && defined (__FILE_NAME__)
+ #if defined (__FILE_NAME__)
#define _ASSERT(Expression) UnitTestDebugAssert (__FILE_NAME__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression))
#else
#define _ASSERT(Expression) UnitTestDebugAssert (__FILE__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression))
#endif
#else
- #if defined (__clang__) && defined (__FILE_NAME__)
+ #if defined (__FILE_NAME__)
#define _ASSERT(Expression) DebugAssert (__FILE_NAME__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression))
#else
#define _ASSERT(Expression) DebugAssert (__FILE__, DEBUG_LINE_NUMBER, DEBUG_EXPRESSION_STRING (Expression))
@@ -534,7 +534,10 @@ UnitTestDebugAssert (
are not included in a module.
**/
-#define DEBUG_CODE_BEGIN() do { if (DebugCodeEnabled ()) { UINT8 __DebugCodeLocal
+#define DEBUG_CODE_BEGIN() \
+ do { \
+ if (DebugCodeEnabled ()) { \
+ do { } while (FALSE)
/**
The macro that marks the end of debug source code.
@@ -545,7 +548,9 @@ UnitTestDebugAssert (
are not included in a module.
**/
-#define DEBUG_CODE_END() __DebugCodeLocal = 0; __DebugCodeLocal++; } } while (FALSE)
+#define DEBUG_CODE_END() \
+ } \
+ } while (FALSE)
/**
The macro that declares a section of debug source code.
diff --git a/MdePkg/Include/Library/FdtLib.h b/MdePkg/Include/Library/FdtLib.h
index 65d7460..a7d26f7 100644
--- a/MdePkg/Include/Library/FdtLib.h
+++ b/MdePkg/Include/Library/FdtLib.h
@@ -19,6 +19,115 @@
#ifndef FDT_LIB_H_
#define FDT_LIB_H_
+/* Error codes: informative error codes */
+#define FDT_ERR_NOTFOUND 1
+/* FDT_ERR_NOTFOUND: The requested node or property does not exist */
+#define FDT_ERR_EXISTS 2
+
+/* FDT_ERR_EXISTS: Attempted to create a node or property which
+ * already exists */
+#define FDT_ERR_NOSPACE 3
+
+/* FDT_ERR_NOSPACE: Operation needed to expand the device
+ * tree, but its buffer did not have sufficient space to
+ * contain the expanded tree. Use fdt_open_into() to move the
+ * device tree to a buffer with more space. */
+
+/* Error codes: codes for bad parameters */
+#define FDT_ERR_BADOFFSET 4
+
+/* FDT_ERR_BADOFFSET: Function was passed a structure block
+ * offset which is out-of-bounds, or which points to an
+ * unsuitable part of the structure for the operation. */
+#define FDT_ERR_BADPATH 5
+
+/* FDT_ERR_BADPATH: Function was passed a badly formatted path
+ * (e.g. missing a leading / for a function which requires an
+ * absolute path) */
+#define FDT_ERR_BADPHANDLE 6
+
+/* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle.
+ * This can be caused either by an invalid phandle property
+ * length, or the phandle value was either 0 or -1, which are
+ * not permitted. */
+#define FDT_ERR_BADSTATE 7
+
+/* FDT_ERR_BADSTATE: Function was passed an incomplete device
+ * tree created by the sequential-write functions, which is
+ * not sufficiently complete for the requested operation. */
+
+/* Error codes: codes for bad device tree blobs */
+#define FDT_ERR_TRUNCATED 8
+
+/* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly
+ * terminated (overflows, goes outside allowed bounds, or
+ * isn't properly terminated). */
+#define FDT_ERR_BADMAGIC 9
+
+/* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
+ * device tree at all - it is missing the flattened device
+ * tree magic number. */
+#define FDT_ERR_BADVERSION 10
+
+/* FDT_ERR_BADVERSION: Given device tree has a version which
+ * can't be handled by the requested operation. For
+ * read-write functions, this may mean that fdt_open_into() is
+ * required to convert the tree to the expected version. */
+#define FDT_ERR_BADSTRUCTURE 11
+
+/* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
+ * structure block or other serious error (e.g. misnested
+ * nodes, or subnodes preceding properties). */
+#define FDT_ERR_BADLAYOUT 12
+
+/* FDT_ERR_BADLAYOUT: For read-write functions, the given
+ * device tree has it's sub-blocks in an order that the
+ * function can't handle (memory reserve map, then structure,
+ * then strings). Use fdt_open_into() to reorganize the tree
+ * into a form suitable for the read-write operations. */
+
+/* "Can't happen" error indicating a bug in libfdt */
+#define FDT_ERR_INTERNAL 13
+
+/* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
+ * Should never be returned, if it is, it indicates a bug in
+ * libfdt itself. */
+
+/* Errors in device tree content */
+#define FDT_ERR_BADNCELLS 14
+
+/* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
+ * or similar property with a bad format or value */
+
+#define FDT_ERR_BADVALUE 15
+
+/* FDT_ERR_BADVALUE: Device tree has a property with an unexpected
+ * value. For example: a property expected to contain a string list
+ * is not NUL-terminated within the length of its value. */
+
+#define FDT_ERR_BADOVERLAY 16
+
+/* FDT_ERR_BADOVERLAY: The device tree overlay, while
+ * correctly structured, cannot be applied due to some
+ * unexpected or missing value, property or node. */
+
+#define FDT_ERR_NOPHANDLES 17
+
+/* FDT_ERR_NOPHANDLES: The device tree doesn't have any
+ * phandle available anymore without causing an overflow */
+
+#define FDT_ERR_BADFLAGS 18
+
+/* FDT_ERR_BADFLAGS: The function was passed a flags field that
+ * contains invalid flags or an invalid combination of flags. */
+
+#define FDT_ERR_ALIGNMENT 19
+
+/* FDT_ERR_ALIGNMENT: The device tree base address is not 8-byte
+ * aligned. */
+
+#define FDT_ERR_MAX 19
+
/**
Flattened Device Tree definition
@@ -63,6 +172,22 @@ typedef struct {
CHAR8 Data[];
} FDT_PROPERTY;
+#ifndef FDT_TAGSIZE
+#define FDT_TAGSIZE sizeof(UINT32)
+#endif
+#ifndef FDT_MAX_NCELLS
+#define FDT_MAX_NCELLS 4
+#endif
+
+#define FdtGetHeader(Fdt, Field) \
+ (Fdt32ToCpu (((const FDT_HEADER *)(Fdt))->Field))
+#define FdtTotalSize(Fdt) (FdtGetHeader ((Fdt), TotalSize))
+
+#define FdtForEachSubnode(Node, Fdt, Parent) \
+ for (Node = FdtFirstSubnode (Fdt, Parent); \
+ Node >= 0; \
+ Node = FdtNextSubnode (Fdt, Node))
+
/**
Convert UINT16 data of the FDT blob to little-endian
@@ -162,6 +287,37 @@ FdtCheckHeader (
);
/**
+ Unpack FDT blob into new buffer
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[out] Buffer Pointer to destination buffer.
+ @param[in] BufferSize The size of destination buffer.
+
+ @return Zero for successfully, otherwise failed.
+
+ **/
+INT32
+EFIAPI
+FdtOpenInto (
+ IN CONST VOID *Fdt,
+ OUT VOID *Buffer,
+ IN INT32 BufferSize
+ );
+
+/**
+ Pack FDT blob in place.
+
+ @param[in][out] Fdt The pointer to FDT blob.
+
+ @return Zero.
+**/
+INT32
+EFIAPI
+FdtPack (
+ IN OUT VOID *Fdt
+ );
+
+/**
Create a empty Flattened Device Tree.
@param[in] Buffer The pointer to allocate a pool for FDT blob.
@@ -178,6 +334,23 @@ FdtCreateEmptyTree (
);
/**
+ Returns a pointer to the node at a given offset.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Offset The offset to node.
+ @param[in] Length Maximum length of node.
+
+ @return pointer to node.
+**/
+CONST VOID *
+EFIAPI
+FdtOffsetPointer (
+ IN CONST VOID *Fdt,
+ IN INT32 Offset,
+ IN UINT32 Length
+ );
+
+/**
Returns a offset of next node from the given node.
@param[in] Fdt The pointer to FDT blob.
@@ -248,6 +421,55 @@ FdtSubnodeOffsetNameLen (
);
/**
+ Returns the number of memory reserve map entries.
+
+ @param[in] Fdt The pointer to FDT blob.
+
+ @return The number of entries in the reserve map.
+
+**/
+INTN
+EFIAPI
+FdtGetNumberOfReserveMapEntries (
+ IN CONST VOID *Fdt
+ );
+
+/**
+ Returns a memory reserve map entry.
+
+ @param[in] *Fdt The pointer to FDT blob.
+ @param[in] Index Index of reserve map entry.
+ @param[out] Addr Pointer to 64-bit variable to hold the start address
+ @param[out] *Size Pointer to 64-bit variable to hold size of reservation
+
+ @return 0 on success, or negative error code.
+
+**/
+INTN
+EFIAPI
+FdtGetReserveMapEntry (
+ IN CONST VOID *Fdt,
+ IN INTN Index,
+ OUT UINT64 *Addr,
+ OUT UINT64 *Size
+ );
+
+/**
+ Find the parent of a given node.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] NodeOffset The offset to the node to find the parent for.
+
+ @return Structure block offset, or negative return value.
+**/
+INT32
+EFIAPI
+FdtParentOffset (
+ IN CONST VOID *Fdt,
+ IN INT32 NodeOffset
+ );
+
+/**
Returns a offset of first node which includes the given property name and value.
@param[in] Fdt The pointer to FDT blob.
@@ -261,7 +483,7 @@ FdtSubnodeOffsetNameLen (
**/
INT32
EFIAPI
-FdtNodeOffsetByPropValue (
+FdtNodeOffsetByPropertyValue (
IN CONST VOID *Fdt,
IN INT32 StartOffset,
IN CONST CHAR8 *PropertyName,
@@ -270,6 +492,38 @@ FdtNodeOffsetByPropValue (
);
/**
+ Returns a offset of first node which includes the given property name and value.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Phandle Phandle value to search for.
+
+ @return The offset to node with matching Phandle value.
+**/
+INT32
+EFIAPI
+FdtNodeOffsetByPhandle (
+ IN CONST VOID *Fdt,
+ IN UINT32 Phandle
+ );
+
+/**
+ Look for a string in a stringlist
+
+ @param[in] StringList Pointer to stringlist to search.
+ @param[in] ListLength Length of StringList.
+ @param[in] String Pointer to string to search for.
+
+ @return 1 if found.
+**/
+INT32
+EFIAPI
+FdtStringListContains (
+ IN CONST CHAR8 *StringList,
+ IN INT32 ListLength,
+ IN CONST CHAR8 *String
+ );
+
+/**
Returns a property with the given name from the given node.
@param[in] Fdt The pointer to FDT blob.
@@ -291,6 +545,25 @@ FdtGetProperty (
);
/**
+ Returns a pointer to a node mapped to an alias matching a substring.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Name The alias name string.
+ @param[in] Length The length to the size of the property found.
+
+ @return A pointer to the expansion of the alias matching the substring,
+ or NULL if alias not found.
+
+**/
+CONST CHAR8 *
+EFIAPI
+FdtGetAliasNameLen (
+ IN CONST VOID *Fdt,
+ IN CONST CHAR8 *Name,
+ IN INT32 Length
+ );
+
+/**
Returns a offset of first property in the given node.
@param[in] Fdt The pointer to FDT blob.
@@ -390,7 +663,49 @@ FdtAddSubnode (
**/
INT32
EFIAPI
-FdtSetProp (
+FdtSetProperty (
+ IN VOID *Fdt,
+ IN INT32 NodeOffset,
+ IN CONST CHAR8 *Name,
+ IN CONST VOID *Value,
+ IN UINT32 Length
+ );
+
+/**
+ Set a property to a 64-bit integer.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] NodeOffset The offset to the node offset which want to add in.
+ @param[in] Name The name to name the property.
+ @param[in] Value The value (big-endian) to the property value.
+
+ @return Zero for successfully, otherwise failed.
+
+ **/
+INT32
+EFIAPI
+FdtSetPropU64 (
+ IN VOID *Fdt,
+ IN INT32 NodeOffset,
+ IN CONST CHAR8 *Name,
+ IN UINT64 Value
+ );
+
+/**
+ Append or create a property in the given node.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] NodeOffset The offset to the node offset which want to add in.
+ @param[in] Name The name to name the property.
+ @param[in] Value The value (big-endian) to the property value.
+ @param[in] Length The length to the size of the property.
+
+ @return Zero for successfully, otherwise failed.
+
+ **/
+INT32
+EFIAPI
+FdtAppendProp (
IN VOID *Fdt,
IN INT32 NodeOffset,
IN CONST CHAR8 *Name,
@@ -399,6 +714,58 @@ FdtSetProp (
);
/**
+ Delete a property.
+
+ This function will delete data from the blob, and will therefore
+ change the offsets of some existing nodes.
+
+ @param[in][out] Fdt Pointer to the device tree blob.
+ @param[in] NodeOffset Offset of the node whose property to nop.
+ @param[in] Name Name of the property to nop.
+
+ @return Zero for successfully, otherwise failed.
+
+**/
+INT32
+FdtDelProp (
+ IN OUT VOID *Fdt,
+ IN INT32 NodeOffset,
+ IN CONST CHAR8 *Name
+ );
+
+/**
+ Finds a tree node by substring
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Path Full path of the node to locate.
+ @param[in] NameLength The length of the name to check only.
+
+ @return structure block offset of the node with the requested path (>=0), on success
+**/
+INT32
+EFIAPI
+FdtPathOffsetNameLen (
+ IN CONST VOID *Fdt,
+ IN CONST CHAR8 *Path,
+ IN INT32 NameLength
+ );
+
+/**
+ Finds a tree node by its full path.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Path Full path of the node to locate.
+
+ @return structure block offset of the node with the requested path (>=0), on success
+**/
+INT32
+EFIAPI
+FdtPathOffset (
+ IN CONST VOID *Fdt,
+ IN CONST CHAR8 *Path
+ );
+
+/**
Returns the name of a given node.
@param[in] Fdt The pointer to FDT blob.
@@ -432,4 +799,59 @@ FdtNodeDepth (
IN INT32 NodeOffset
);
+/**
+ Find nodes with a given 'compatible' value.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] StartOffset Only find nodes after this offset.
+ @param[in] Compatible The string to match against.
+
+ @retval The offset of the first node after StartOffset.
+**/
+INT32
+EFIAPI
+FdtNodeOffsetByCompatible (
+ IN CONST VOID *Fdt,
+ IN INT32 StartOffset,
+ IN CONST CHAR8 *Compatible
+ );
+
+/**
+ Retrieve address size for a bus represented in the tree
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] NodeOffset Offset of node to check.
+
+ @return Number of cells in the bus address, or negative error.
+**/
+INT32
+EFIAPI
+FdtAddressCells (
+ IN CONST VOID *Fdt,
+ IN INT32 NodeOffset
+ );
+
+/**
+ Retrieve address range size for a bus represented in the tree
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] NodeOffset Offset of node to check.
+
+ @return Number of cells in the bus size, or negative error.
+**/
+INT32
+EFIAPI
+FdtSizeCells (
+ IN CONST VOID *Fdt,
+ IN INT32 NodeOffset
+ );
+
+/* Debug functions. */
+CONST
+CHAR8
+*
+FdtStrerror (
+ IN INT32 ErrVal
+ );
+
#endif /* FDT_LIB_H_ */
diff --git a/MdePkg/Include/Library/PerformanceLib.h b/MdePkg/Include/Library/PerformanceLib.h
index d0f2dfb..40e99d0 100644
--- a/MdePkg/Include/Library/PerformanceLib.h
+++ b/MdePkg/Include/Library/PerformanceLib.h
@@ -734,7 +734,10 @@ LogPerformanceMeasurement (
Otherwise, the source lines between PERF_CODE_BEGIN() and PERF_CODE_END() are not included in a module.
**/
-#define PERF_CODE_BEGIN() do { if (PerformanceMeasurementEnabled ()) { UINT8 __PerformanceCodeLocal
+#define PERF_CODE_BEGIN() \
+ do { \
+ if (PerformanceMeasurementEnabled ()) { \
+ do { } while (FALSE)
/**
Macro that marks the end of performance measurement source code.
@@ -744,7 +747,9 @@ LogPerformanceMeasurement (
Otherwise, the source lines between PERF_CODE_BEGIN() and PERF_CODE_END() are not included in a module.
**/
-#define PERF_CODE_END() __PerformanceCodeLocal = 0; __PerformanceCodeLocal++; } } while (FALSE)
+#define PERF_CODE_END() \
+ } \
+ } while (FALSE)
/**
Macro that declares a section of performance measurement source code.
diff --git a/MdePkg/Include/Library/StackCheckFailureHookLib.h b/MdePkg/Include/Library/StackCheckFailureHookLib.h
new file mode 100644
index 0000000..f0657dd
--- /dev/null
+++ b/MdePkg/Include/Library/StackCheckFailureHookLib.h
@@ -0,0 +1,26 @@
+/** @file
+ Library provides a hook called when a stack cookie check fails.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef STACK_COOKIE_FAILURE_HOOK_LIB_H_
+#define STACK_COOKIE_FAILURE_HOOK_LIB_H_
+
+#include <Uefi.h>
+
+/**
+ This function gets called when a compiler generated stack cookie fails. This allows a platform to hook this
+ call and perform any required actions/telemetry at that time.
+
+ @param FailureAddress The address of the function that failed the stack cookie check.
+
+**/
+VOID
+EFIAPI
+StackCheckFailureHook (
+ VOID *FailureAddress
+ );
+
+#endif
diff --git a/MdePkg/Include/Protocol/Http.h b/MdePkg/Include/Protocol/Http.h
index 28e6221..7d9481a 100644
--- a/MdePkg/Include/Protocol/Http.h
+++ b/MdePkg/Include/Protocol/Http.h
@@ -98,7 +98,8 @@ typedef enum {
HTTP_STATUS_503_SERVICE_UNAVAILABLE,
HTTP_STATUS_504_GATEWAY_TIME_OUT,
HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED,
- HTTP_STATUS_308_PERMANENT_REDIRECT
+ HTTP_STATUS_308_PERMANENT_REDIRECT,
+ HTTP_STATUS_429_TOO_MANY_REQUESTS
} EFI_HTTP_STATUS_CODE;
///
diff --git a/MdePkg/Include/Protocol/Smbios.h b/MdePkg/Include/Protocol/Smbios.h
index f9346aa..e6977b4 100644
--- a/MdePkg/Include/Protocol/Smbios.h
+++ b/MdePkg/Include/Protocol/Smbios.h
@@ -69,6 +69,10 @@
#define EFI_SMBIOS_TYPE_ADDITIONAL_INFORMATION SMBIOS_TYPE_ADDITIONAL_INFORMATION
#define EFI_SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION
#define EFI_SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE
+#define EFI_SMBIOS_TYPE_TPM_DEVICE SMBIOS_TYPE_TPM_DEVICE
+#define EFI_SMBIOS_TYPE_PROCESSOR_ADDITIONAL_INFORMATION SMBIOS_TYPE_PROCESSOR_ADDITIONAL_INFORMATION
+#define EFI_SMBIOS_TYPE_FIRMWARE_INVENTORY_INFORMATION SMBIOS_TYPE_FIRMWARE_INVENTORY_INFORMATION
+#define EFI_SMBIOS_TYPE_STRING_PROPERTY_INFORMATION SMBIOS_TYPE_STRING_PROPERTY_INFORMATION
#define EFI_SMBIOS_TYPE_INACTIVE SMBIOS_TYPE_INACTIVE
#define EFI_SMBIOS_TYPE_END_OF_TABLE SMBIOS_TYPE_END_OF_TABLE
#define EFI_SMBIOS_OEM_BEGIN SMBIOS_OEM_BEGIN
diff --git a/MdePkg/Include/Register/Amd/SevSnpMsr.h b/MdePkg/Include/Register/Amd/SevSnpMsr.h
index 1b8fbc1..5187f96 100644
--- a/MdePkg/Include/Register/Amd/SevSnpMsr.h
+++ b/MdePkg/Include/Register/Amd/SevSnpMsr.h
@@ -126,19 +126,106 @@ typedef union {
///
/// [Bit 0] Secure Encrypted Virtualization (Sev) is enabled
///
- UINT32 SevBit : 1;
+ UINT32 SevBit : 1;
///
/// [Bit 1] Secure Encrypted Virtualization Encrypted State (SevEs) is enabled
///
- UINT32 SevEsBit : 1;
+ UINT32 SevEsBit : 1;
///
/// [Bit 2] Secure Nested Paging (SevSnp) is enabled
///
- UINT32 SevSnpBit : 1;
+ UINT32 SevSnpBit : 1;
- UINT32 Reserved2 : 29;
+ ///
+ /// [Bit 3] Virtual TOM feature is enabled in SEV_FEATURES[1]
+ ///
+ UINT32 vTOM : 1;
+
+ ///
+ /// [Bit 4] ReflectVC feature is enabled in SEV_FEATURES[2]
+ ///
+ UINT32 ReflectVC : 1;
+
+ ///
+ /// [Bit 5] Restricted Injection feature is enabled in SEV_FEATURES[3]
+ ///
+ UINT32 RestrictedInjection : 1;
+
+ ///
+ /// [Bit 6] Alternate Injection feature is enabled in SEV_FEATURES[4]
+ ///
+ UINT32 AlternateInjection : 1;
+
+ ///
+ /// [Bit 7] Debug Virtualization feature is enabled in SEV_FEATURES[5]
+ ///
+ UINT32 DebugVirtualization : 1;
+
+ ///
+ /// [Bit 8] PreventHostIBS feature is enabled in SEV_FEATURES[6]
+ ///
+ UINT32 PreventHostIBS : 1;
+
+ ///
+ /// [Bit 9] BTB isolation feature is enabled in SEV_FEATURES[7]
+ ///
+ UINT32 SNPBTBIsolation : 1;
+
+ ///
+ /// [Bit 10] VMPL SSS feature is enabled in SEV_FEATURES[8]
+ ///
+ UINT32 VmplSSS : 1;
+
+ ///
+ /// [Bit 11] Secure TSC feature is enabled in SEV_FEATURES[9]
+ ///
+ UINT32 SecureTsc : 1;
+
+ ///
+ /// [Bit 12] VMGEXIT Parameter feature is enabled in SEV_FEATURES[10]
+ ///
+ UINT32 VmgexitParameter : 1;
+
+ ///
+ /// [Bit 13] PMC Virtualization feature is enabled in SEV_FEATURES[11]
+ ///
+ UINT32 PmcVirtualization : 1;
+
+ ///
+ /// [Bit 14] IBS Virtualization feature is enabled in SEV_FEATURES[12]
+ ///
+ UINT32 IbsVirtualization : 1;
+
+ ///
+ /// [Bit 15]
+ ///
+ UINT32 Reserved1 : 1;
+
+ ///
+ /// [Bit 16] VMSA Register Protection feature is enabled in SEV_FEATURES[14]
+ ///
+ UINT32 VmsaRegProt : 1;
+
+ ///
+ /// [Bit 17] SMT Protection feature is enabled in SEV_FEATURES[15]
+ ///
+ UINT32 SmtProtection : 1;
+ ///
+ ///
+ /// [Bit 18] Secure AVIC feature is enabled in SEV_FEATURES[16]
+ ///
+ UINT32 SecureAVIC : 1;
+
+ UINT32 Reserved2 : 4;
+
+ ///
+ /// [Bit 23] IBPB on Entry feature is enabled in SEV_FEATURES[21]
+ ///
+ UINT32 IbpbOnEntry : 1;
+
+ UINT32 Reserved3 : 8;
} Bits;
///
/// All bit fields as a 32-bit value
diff --git a/MdePkg/Include/Register/Intel/StmApi.h b/MdePkg/Include/Register/Intel/StmApi.h
index 9d42bcd..6c1cdf9 100644
--- a/MdePkg/Include/Register/Intel/StmApi.h
+++ b/MdePkg/Include/Register/Intel/StmApi.h
@@ -18,6 +18,8 @@
#pragma pack (1)
+#define STM_SMM_REV_ID 0x80010100
+
/**
STM Header Structures
**/
diff --git a/MdePkg/Include/Register/LoongArch64/Csr.h b/MdePkg/Include/Register/LoongArch64/Csr.h
index aa22a26..fe2ebd9 100644
--- a/MdePkg/Include/Register/LoongArch64/Csr.h
+++ b/MdePkg/Include/Register/LoongArch64/Csr.h
@@ -112,7 +112,7 @@
//
// Config CSR registers
//
-#define LOONGARCH_CSR_CPUNUM 0x20 // CPU core number
+#define LOONGARCH_CSR_CPUID 0x20 // CPU core ID
#define LOONGARCH_CSR_PRCFG1 0x21 // Config1
#define LOONGARCH_CSR_PRCFG2 0x22 // Config2
#define LOONGARCH_CSR_PRCFG3 0x23 // Config3
diff --git a/MdePkg/Include/Register/RiscV64/RiscVEncoding.h b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h
index 8ccdea2..a656d44 100644
--- a/MdePkg/Include/Register/RiscV64/RiscVEncoding.h
+++ b/MdePkg/Include/Register/RiscV64/RiscVEncoding.h
@@ -120,4 +120,14 @@
#define CAUSE_VIRTUAL_INST_FAULT 0x16
#define CAUSE_STORE_GUEST_PAGE_FAULT 0x17
+/* Sstc extension */
+#define CSR_SEED 0x15
+
+#define SEED_OPST_MASK 0xc0000000
+#define SEED_OPST_BIST 0x00000000
+#define SEED_OPST_WAIT 0x40000000
+#define SEED_OPST_ES16 0x80000000
+#define SEED_OPST_DEAD 0xc0000000
+#define SEED_ENTROPY_MASK 0xffff
+
#endif
diff --git a/MdePkg/Include/Uefi/UefiMultiPhase.h b/MdePkg/Include/Uefi/UefiMultiPhase.h
index 7884913..1f1f3f4 100644
--- a/MdePkg/Include/Uefi/UefiMultiPhase.h
+++ b/MdePkg/Include/Uefi/UefiMultiPhase.h
@@ -108,7 +108,22 @@ typedef enum {
/// by a corresponding call to the underlying isolation architecture.
///
EfiUnacceptedMemoryType,
- EfiMaxMemoryType
+ EfiMaxMemoryType,
+ //
+ // +---------------------------------------------------+
+ // | 0..(EfiMaxMemoryType - 1) - Normal memory type |
+ // +---------------------------------------------------+
+ // | EfiMaxMemoryType..0x6FFFFFFF - Invalid |
+ // +---------------------------------------------------+
+ // | 0x70000000..0x7FFFFFFF - OEM reserved |
+ // +---------------------------------------------------+
+ // | 0x80000000..0xFFFFFFFF - OS reserved |
+ // +---------------------------------------------------+
+ //
+ MEMORY_TYPE_OEM_RESERVED_MIN = 0x70000000,
+ MEMORY_TYPE_OEM_RESERVED_MAX = 0x7FFFFFFF,
+ MEMORY_TYPE_OS_RESERVED_MIN = 0x80000000,
+ MEMORY_TYPE_OS_RESERVED_MAX = 0xFFFFFFFF
} EFI_MEMORY_TYPE;
///
diff --git a/MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.c b/MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.c
index 316d78b..84366a4 100644
--- a/MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.c
+++ b/MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.c
@@ -41,7 +41,7 @@ GetArmTrngVersion (
OUT UINT16 *MinorRevision
)
{
- ASSERT (FALSE);
+ DEBUG ((DEBUG_ERROR, "ArmTrng Backend not found\n"));
return RETURN_UNSUPPORTED;
}
diff --git a/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
index 730e568..b581538 100644
--- a/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
+++ b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
@@ -57,6 +57,9 @@
BaseMemoryLib
[BuildOptions]
- MSFT:*_*_IA32_CC_FLAGS = /wd4146 /wd4245
- MSFT:*_*_X64_CC_FLAGS = /wd4146 /wd4244 /wd4245 /wd4267
+# warning C4706: assignment within conditional expression
+# if ((err = fdt_splice_(fdt, p, oldlen, newlen)))
+# in BaseFdtLib\libfdt\libfdt\fdt_rw.c (wait for sub module update to remove this)
+ MSFT:*_*_IA32_CC_FLAGS = /wd4146 /wd4245 /wd4706
+ MSFT:*_*_X64_CC_FLAGS = /wd4146 /wd4244 /wd4245 /wd4267 /wd4706
diff --git a/MdePkg/Library/BaseFdtLib/FdtLib.c b/MdePkg/Library/BaseFdtLib/FdtLib.c
index c9514af..ebddf4a 100644
--- a/MdePkg/Library/BaseFdtLib/FdtLib.c
+++ b/MdePkg/Library/BaseFdtLib/FdtLib.c
@@ -7,6 +7,8 @@
**/
#include <libfdt/libfdt/libfdt.h>
+#include <Library/FdtLib.h>
+#include <Uefi/UefiBaseType.h>
/**
Convert UINT16 data of the FDT blob to little-endian
@@ -147,6 +149,63 @@ FdtCreateEmptyTree (
}
/**
+ Unpack FDT blob into new buffer
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[out] Buffer Pointer to destination buffer.
+ @param[in] BufferSize The size of destination buffer.
+
+ @return Zero for successfully, otherwise failed.
+
+ **/
+INT32
+EFIAPI
+FdtOpenInto (
+ IN CONST VOID *Fdt,
+ OUT VOID *Buffer,
+ IN INT32 BufferSize
+ )
+{
+ return fdt_open_into (Fdt, Buffer, BufferSize);
+}
+
+/**
+ Pack FDT blob in place.
+
+ @param[in][out] Fdt The pointer to FDT blob.
+
+ @return Zero.
+**/
+INT32
+EFIAPI
+FdtPack (
+ IN OUT VOID *Fdt
+ )
+{
+ return fdt_pack (Fdt);
+}
+
+/**
+ Returns a pointer to the node at a given offset.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Offset The offset to node.
+ @param[in] Length Maximum length of node.
+
+ @return pointer to node.
+**/
+CONST VOID *
+EFIAPI
+FdtOffsetPointer (
+ IN CONST VOID *Fdt,
+ IN INT32 Offset,
+ IN UINT32 Length
+ )
+{
+ return fdt_offset_ptr (Fdt, Offset, Length);
+}
+
+/**
Returns a offset of next node from the given node.
@param[in] Fdt The pointer to FDT blob.
@@ -206,6 +265,46 @@ FdtNextSubnode (
}
/**
+ Returns the number of memory reserve map entries.
+
+ @param[in] Fdt The pointer to FDT blob.
+
+ @return The number of entries in the reserve map.
+
+**/
+INTN
+EFIAPI
+FdtGetNumberOfReserveMapEntries (
+ IN CONST VOID *Fdt
+ )
+{
+ return fdt_num_mem_rsv (Fdt);
+}
+
+/**
+ Returns a memory reserve map entry.
+
+ @param[in] *Fdt The pointer to FDT blob.
+ @param[in] Index Index of reserve map entry.
+ @param[out] Addr Pointer to 64-bit variable to hold the start address
+ @param[out] *Size Pointer to 64-bit variable to hold size of reservation
+
+ @return 0 on success, or negative error code.
+
+**/
+INTN
+EFIAPI
+FdtGetReserveMapEntry (
+ IN CONST VOID *Fdt,
+ IN INTN Index,
+ OUT EFI_PHYSICAL_ADDRESS *Addr,
+ OUT UINT64 *Size
+ )
+{
+ return fdt_get_mem_rsv (Fdt, Index, Addr, Size);
+}
+
+/**
Returns a offset of first node which includes the given name.
@param[in] Fdt The pointer to FDT blob.
@@ -229,6 +328,45 @@ FdtSubnodeOffsetNameLen (
}
/**
+ Returns a offset of first node which matches the given name.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] ParentOffset The offset to the node which start find under.
+ @param[in] Name The name to search the node with the name.
+
+ @return The offset to node offset with given node name.
+
+ **/
+INT32
+EFIAPI
+FdtSubnodeOffset (
+ IN CONST VOID *Fdt,
+ IN INT32 ParentOffset,
+ IN CONST CHAR8 *Name
+ )
+{
+ return fdt_subnode_offset (Fdt, ParentOffset, Name);
+}
+
+/**
+ Find the parent of a given node.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] NodeOffset The offset to the node to find the parent for.
+
+ @return Structure block offset, or negative return value.
+**/
+INT32
+EFIAPI
+FdtParentOffset (
+ IN CONST VOID *Fdt,
+ IN INT32 NodeOffset
+ )
+{
+ return fdt_parent_offset (Fdt, NodeOffset);
+}
+
+/**
Returns a offset of first node which includes the given property name and value.
@param[in] Fdt The pointer to FDT blob.
@@ -242,7 +380,7 @@ FdtSubnodeOffsetNameLen (
**/
INT32
EFIAPI
-FdtNodeOffsetByPropValue (
+FdtNodeOffsetByPropertyValue (
IN CONST VOID *Fdt,
IN INT32 StartOffset,
IN CONST CHAR8 *PropertyName,
@@ -254,6 +392,44 @@ FdtNodeOffsetByPropValue (
}
/**
+ Returns a offset of first node which includes the given property name and value.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Phandle Phandle value to search for.
+
+ @return The offset to node with matching Phandle value.
+**/
+INT32
+EFIAPI
+FdtNodeOffsetByPhandle (
+ IN CONST VOID *Fdt,
+ IN UINT32 Phandle
+ )
+{
+ return fdt_node_offset_by_phandle (Fdt, Phandle);
+}
+
+/**
+ Look for a string in a stringlist
+
+ @param[in] StringList Pointer to stringlist to search.
+ @param[in] ListLength Length of StringList.
+ @param[in] String Pointer to string to search for.
+
+ @return 1 if found.
+**/
+INT32
+EFIAPI
+FdtStringListContains (
+ IN CONST CHAR8 *StringList,
+ IN INT32 ListLength,
+ IN CONST CHAR8 *String
+ )
+{
+ return fdt_stringlist_contains (StringList, ListLength, String);
+}
+
+/**
Returns a property with the given name from the given node.
@param[in] Fdt The pointer to FDT blob.
@@ -265,7 +441,7 @@ FdtNodeOffsetByPropValue (
come from FDT blob, it's encoding with big-endian.
**/
-CONST struct fdt_property *
+CONST FDT_PROPERTY *
EFIAPI
FdtGetProperty (
IN CONST VOID *Fdt,
@@ -274,7 +450,29 @@ FdtGetProperty (
IN INT32 *Length
)
{
- return fdt_get_property (Fdt, NodeOffset, Name, Length);
+ return (FDT_PROPERTY *)fdt_get_property (Fdt, NodeOffset, Name, Length);
+}
+
+/**
+ Returns a pointer to a node mapped to an alias matching a substring.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Name The alias name string.
+ @param[in] Length The length to the size of the property found.
+
+ @return A pointer to the expansion of the alias matching the substring,
+ or NULL if alias not found.
+
+**/
+CONST CHAR8 *
+EFIAPI
+FdtGetAliasNameLen (
+ IN CONST VOID *Fdt,
+ IN CONST CHAR8 *Name,
+ IN INT32 Length
+ )
+{
+ return fdt_get_alias_namelen (Fdt, Name, Length);
}
/**
@@ -325,7 +523,7 @@ FdtNextPropertyOffset (
@return The property to the structure of the given property offset.
**/
-CONST struct fdt_property *
+CONST FDT_PROPERTY *
EFIAPI
FdtGetPropertyByOffset (
IN CONST VOID *Fdt,
@@ -333,7 +531,7 @@ FdtGetPropertyByOffset (
IN INT32 *Length
)
{
- return fdt_get_property_by_offset (Fdt, Offset, Length);
+ return (FDT_PROPERTY *)fdt_get_property_by_offset (Fdt, Offset, Length);
}
/**
@@ -392,7 +590,7 @@ FdtAddSubnode (
**/
INT32
EFIAPI
-FdtSetProp (
+FdtSetProperty (
IN VOID *Fdt,
IN INT32 NodeOffset,
IN CONST CHAR8 *Name,
@@ -404,6 +602,119 @@ FdtSetProp (
}
/**
+ Set a property to a 64-bit integer.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] NodeOffset The offset to the node offset which want to add in.
+ @param[in] Name The name to name the property.
+ @param[in] Value The value (big-endian) to the property value.
+
+ @return Zero for successfully, otherwise failed.
+
+ **/
+INT32
+EFIAPI
+FdtSetPropU64 (
+ IN VOID *Fdt,
+ IN INT32 NodeOffset,
+ IN CONST CHAR8 *Name,
+ IN UINT64 Value
+ )
+{
+ UINT64 Tmp;
+
+ Tmp = cpu_to_fdt64 (Value);
+
+ return fdt_setprop (Fdt, NodeOffset, Name, &Tmp, sizeof (Tmp));
+}
+
+/**
+ Append or create a property in the given node.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] NodeOffset The offset to the node offset which want to add in.
+ @param[in] Name The name to name the property.
+ @param[in] Value The value (big-endian) to the property value.
+ @param[in] Length The length to the size of the property.
+
+ @return Zero for successfully, otherwise failed.
+
+ **/
+INT32
+EFIAPI
+FdtAppendProp (
+ IN VOID *Fdt,
+ IN INT32 NodeOffset,
+ IN CONST CHAR8 *Name,
+ IN CONST VOID *Value,
+ IN UINT32 Length
+ )
+{
+ return fdt_appendprop (Fdt, NodeOffset, Name, Value, (int)Length);
+}
+
+/**
+ Delete a property.
+
+ This function will delete data from the blob, and will therefore
+ change the offsets of some existing nodes.
+
+ @param[in][out] Fdt Pointer to the device tree blob.
+ @param[in] NodeOffset Offset of the node whose property to nop.
+ @param[in] Name Name of the property to nop.
+
+ @return Zero for successfully, otherwise failed.
+
+**/
+INT32
+FdtDelProp (
+ IN OUT VOID *Fdt,
+ IN INT32 NodeOffset,
+ IN CONST CHAR8 *Name
+ )
+{
+ return fdt_delprop (Fdt, NodeOffset, Name);
+}
+
+/**
+ Finds a tree node by substring
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Path Full path of the node to locate.
+ @param[in] NameLength The length of the name to check only.
+
+ @return structure block offset of the node with the requested path (>=0), on success
+**/
+INT32
+EFIAPI
+FdtPathOffsetNameLen (
+ IN CONST VOID *Fdt,
+ IN CONST CHAR8 *Path,
+ IN INT32 NameLength
+ )
+{
+ return fdt_path_offset_namelen (Fdt, Path, NameLength);
+}
+
+/**
+ Finds a tree node by its full path.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] Path Full path of the node to locate.
+
+ @return structure block offset of the node with the requested path (>=0), on success
+**/
+INT32
+EFIAPI
+FdtPathOffset (
+ IN CONST VOID *Fdt,
+ IN CONST CHAR8 *Path
+ )
+{
+ return fdt_path_offset (Fdt, Path);
+}
+
+/**
Returns the name of a given node.
@param[in] Fdt The pointer to FDT blob.
@@ -442,3 +753,70 @@ FdtNodeDepth (
{
return fdt_node_depth (Fdt, NodeOffset);
}
+
+/**
+ Find nodes with a given 'compatible' value.
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] StartOffset Only find nodes after this offset.
+ @param[in] Compatible The string to match against.
+
+ @retval The offset of the first node after StartOffset.
+**/
+INT32
+EFIAPI
+FdtNodeOffsetByCompatible (
+ IN CONST VOID *Fdt,
+ IN INT32 StartOffset,
+ IN CONST CHAR8 *Compatible
+ )
+{
+ return fdt_node_offset_by_compatible (Fdt, StartOffset, Compatible);
+}
+
+/**
+ Retrieve address size for a bus represented in the tree
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] NodeOffset Offset of node to check.
+
+ @return Number of cells in the bus address, or negative error.
+**/
+INT32
+EFIAPI
+FdtAddressCells (
+ IN CONST VOID *Fdt,
+ IN INT32 NodeOffset
+ )
+{
+ return fdt_address_cells (Fdt, NodeOffset);
+}
+
+/**
+ Retrieve address range size for a bus represented in the tree
+
+ @param[in] Fdt The pointer to FDT blob.
+ @param[in] NodeOffset Offset of node to check.
+
+ @return Number of cells in the bus size, or negative error.
+**/
+INT32
+EFIAPI
+FdtSizeCells (
+ IN CONST VOID *Fdt,
+ IN INT32 NodeOffset
+ )
+{
+ return fdt_size_cells (Fdt, NodeOffset);
+}
+
+/* Debug functions. */
+CONST
+CHAR8
+*
+FdtStrerror (
+ IN INT32 ErrVal
+ )
+{
+ return fdt_strerror (ErrVal);
+}
diff --git a/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.S b/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.S
new file mode 100644
index 0000000..cfabd7a
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.S
@@ -0,0 +1,30 @@
+#------------------------------------------------------------------------------
+#
+# ArmReadCntPctReg() for AArch64
+#
+# Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#------------------------------------------------------------------------------
+
+.text
+.p2align 2
+GCC_ASM_EXPORT(ArmReadCntPctReg)
+
+#/**
+# Reads the CNTPCT_EL0 Register.
+#
+# @return The contents of the CNTPCT_EL0 register.
+#
+#**/
+#UINT64
+#EFIAPI
+#ArmReadCntPctReg (
+# VOID
+# );
+#
+ASM_PFX(ArmReadCntPctReg):
+ AARCH64_BTI(c)
+ mrs x0, cntpct_el0
+ ret
diff --git a/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.asm b/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.asm
new file mode 100644
index 0000000..98823fd
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/ArmReadCntPctReg.asm
@@ -0,0 +1,30 @@
+;------------------------------------------------------------------------------
+;
+; ArmReadCntPctReg() for AArch64
+;
+; Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.<BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+ EXPORT ArmReadCntPctReg
+ AREA BaseLib_LowLevel, CODE, READONLY
+
+;/**
+; Reads the CNTPCT_EL0 Register.
+;
+; @return The contents of the CNTPCT_EL0 register.
+;
+;**/
+;UINT64
+;EFIAPI
+;ArmReadCntPctReg (
+; VOID
+; );
+;
+ArmReadCntPctReg
+ mrs x0, cntpct_el0
+ ret
+
+ END
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S b/MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.S
index d30b63f..4e61b86 100644
--- a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S
+++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.S
@@ -1,6 +1,6 @@
#------------------------------------------------------------------------------
#
-# ArmReadIdIsar0() for AArch64
+# ArmReadIdAA64Isar0Reg() for AArch64
#
# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
#
@@ -10,7 +10,7 @@
.text
.p2align 2
-GCC_ASM_EXPORT(ArmReadIdIsar0)
+GCC_ASM_EXPORT(ArmReadIdAA64Isar0Reg)
#/**
# Reads the ID_AA64ISAR0 Register.
@@ -20,11 +20,11 @@ GCC_ASM_EXPORT(ArmReadIdIsar0)
#**/
#UINT64
#EFIAPI
-#ArmReadIdIsar0 (
+#ArmReadIdAA64Isar0Reg (
# VOID
# );
#
-ASM_PFX(ArmReadIdIsar0):
+ASM_PFX(ArmReadIdAA64Isar0Reg):
AARCH64_BTI(c)
- mrs x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register
+ mrs x0, id_aa64isar0_el1
ret
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm b/MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.asm
index 1d9f9a8..790fb90 100644
--- a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm
+++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdAA64Isar0Reg.asm
@@ -1,6 +1,6 @@
;------------------------------------------------------------------------------
;
-; ArmReadIdIsar0() for AArch64
+; ArmReadIdAA64Isar0Reg() for AArch64
;
; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
;
@@ -8,7 +8,7 @@
;
;------------------------------------------------------------------------------
- EXPORT ArmReadIdIsar0
+ EXPORT ArmReadIdAA64Isar0Reg
AREA BaseLib_LowLevel, CODE, READONLY
;/**
@@ -19,12 +19,12 @@
;**/
;UINT64
;EFIAPI
-;ArmReadIdIsar0 (
+;ArmReadIdAA64Isar0Reg (
; VOID
; );
;
-ArmReadIdIsar0
- mrs x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register
+ArmReadIdAA64Isar0Reg
+ mrs x0, id_aa64isar0_el1
ret
END
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index 26e66a8..317d32c 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -3,7 +3,7 @@
#
# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+# Portions copyright (c) 2011 - 2024, Arm Limited. All rights reserved.<BR>
# Copyright (c) 2020 - 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -339,6 +339,7 @@
Ebc/SpeculationBarrier.c
Unaligned.c
Math64.c
+ IntelTdxNull.c
[Sources.ARM]
Arm/InternalSwitchStack.c
@@ -364,6 +365,7 @@
Arm/CpuBreakpoint.S | GCC
Arm/MemoryFence.S | GCC
Arm/SpeculationBarrier.S | GCC
+ IntelTdxNull.c
[Sources.AARCH64]
Arm/InternalSwitchStack.c
@@ -378,6 +380,8 @@
AArch64/SetJumpLongJump.S | GCC
AArch64/CpuBreakpoint.S | GCC
AArch64/SpeculationBarrier.S | GCC
+ AArch64/ArmReadCntPctReg.S | GCC
+ AArch64/ArmReadIdAA64Isar0Reg.S | GCC
AArch64/MemoryFence.asm | MSFT
AArch64/SwitchStack.asm | MSFT
@@ -387,6 +391,9 @@
AArch64/SetJumpLongJump.asm | MSFT
AArch64/CpuBreakpoint.asm | MSFT
AArch64/SpeculationBarrier.asm | MSFT
+ AArch64/ArmReadCntPctReg.asm | MSFT
+ AArch64/ArmReadIdAA64Isar0Reg.asm | MSFT
+ IntelTdxNull.c
[Sources.RISCV64]
Math64.c
@@ -408,6 +415,7 @@
RiscV64/ReadTimer.S | GCC
RiscV64/RiscVMmu.S | GCC
RiscV64/SpeculationBarrier.S | GCC
+ IntelTdxNull.c
[Sources.LOONGARCH64]
Math64.c
@@ -428,6 +436,7 @@
LoongArch64/ExceptionBase.S | GCC
LoongArch64/Cpucfg.S | GCC
LoongArch64/ReadStableCounter.S | GCC
+ IntelTdxNull.c
[Packages]
MdePkg/MdePkg.dec
diff --git a/MdePkg/Library/BaseLib/CheckSum.c b/MdePkg/Library/BaseLib/CheckSum.c
index 57d324c..1c82a53 100644
--- a/MdePkg/Library/BaseLib/CheckSum.c
+++ b/MdePkg/Library/BaseLib/CheckSum.c
@@ -762,3 +762,72 @@ CalculateCrc32c (
return ~Crc;
}
+
+// The lookup table is inherited from [https://crccalc.com/](https://crccalc.com/%60)
+GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT16 mCrc16CcittFLookupTable[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
+};
+
+/**
+ Calculates the CRC16-CCITT-FALSE checksum of the given buffer.
+
+ @param[in] Buffer Pointer to the buffer.
+ @param[in] Length Length of the buffer, in bytes.
+ @param[in] InitialValue Initial value of the CRC.
+
+ @return The CRC16-CCITT-FALSE checksum.
+**/
+UINT16
+EFIAPI
+CalculateCrc16CcittF (
+ IN CONST VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 InitialValue
+ )
+{
+ CONST UINT8 *Buf;
+ UINT16 Crc;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1));
+
+ Buf = Buffer;
+ Crc = InitialValue;
+
+ while (Length-- != 0) {
+ Crc = mCrc16CcittFLookupTable[((Crc >> 8) ^ *(Buf++)) & 0xFF] ^ (Crc << 8);
+ }
+
+ return Crc;
+}
diff --git a/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S b/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S
index 3a87941..bb57924 100644
--- a/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S
+++ b/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S
@@ -50,12 +50,12 @@ TlbCsrRd:
jirl $zero, $t0, 0
CfgCsrRd:
- li.w $t0, LOONGARCH_CSR_CPUNUM
+ li.w $t0, LOONGARCH_CSR_CPUID
bltu $a0, $t0, ReadSelNumErr
li.w $t0, LOONGARCH_CSR_PRCFG3
bltu $t0, $a0, KcsCsrRd
la.pcrel $t0, CfgCsrRead
- addi.w $t1, $a0, -LOONGARCH_CSR_CPUNUM
+ addi.w $t1, $a0, -LOONGARCH_CSR_CPUID
alsl.d $t0, $t1, $t0, 3
jirl $zero, $t0, 0
@@ -100,8 +100,7 @@ DirMapCsrRd:
jirl $zero, $t0, 0
ReadSelNumErr:
- addi.d $a0, $zero, -1
- jirl $zero, $ra, 0
+ break 0
BasicCsrRead:
CsrSel = LOONGARCH_CSR_CRMD
@@ -118,8 +117,8 @@ TlbCsrRead:
.endr
CfgCsrRead:
- CsrSel = LOONGARCH_CSR_CPUNUM
- .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUNUM + 1
+ CsrSel = LOONGARCH_CSR_CPUID
+ .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUID + 1
AsmCsrRd CsrSel
CsrSel = CsrSel + 1
.endr
@@ -175,12 +174,12 @@ TlbCsrWr:
jirl $zero, $t0, 0
CfgCsrWr:
- li.w $t0, LOONGARCH_CSR_CPUNUM
+ li.w $t0, LOONGARCH_CSR_CPUID
bltu $a0, $t0, WriteSelNumErr
li.w $t0, LOONGARCH_CSR_PRCFG3
bltu $t0, $a0, KcsCsrWr
la.pcrel $t0, CfgCsrWrite
- addi.w $t1, $a0, -LOONGARCH_CSR_CPUNUM
+ addi.w $t1, $a0, -LOONGARCH_CSR_CPUID
alsl.d $t0, $t1, $t0, 3
move $a0, $a1
jirl $zero, $t0, 0
@@ -230,8 +229,7 @@ DirMapCsrWr:
jirl $zero, $t0, 0
WriteSelNumErr:
- addi.d $a0, $zero, -1
- jirl $zero, $ra, 0
+ break 0
BasicCsrWrite:
CsrSel = LOONGARCH_CSR_CRMD
@@ -248,8 +246,8 @@ TlbCsrWrite:
.endr
CfgCsrWrite:
- CsrSel = LOONGARCH_CSR_CPUNUM
- .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUNUM + 1
+ CsrSel = LOONGARCH_CSR_CPUID
+ .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUID + 1
AsmCsrWr CsrSel
CsrSel = CsrSel + 1
.endr
@@ -308,12 +306,12 @@ TlbCsrXchg:
jirl $zero, $t0, 0
CfgCsrXchg:
- li.w $t0, LOONGARCH_CSR_CPUNUM
+ li.w $t0, LOONGARCH_CSR_CPUID
bltu $a0, $t0, XchgSelNumErr
li.w $t0, LOONGARCH_CSR_PRCFG3
bltu $t0, $a0, KcsCsrXchg
la.pcrel $t0, CfgCsrXchange
- addi.w $t1, $a0, -LOONGARCH_CSR_CPUNUM
+ addi.w $t1, $a0, -LOONGARCH_CSR_CPUID
alsl.d $t0, $t1, $t0, 3
move $a0, $a1
move $a1, $a2
@@ -368,8 +366,7 @@ DirMapCsrXchg:
jirl $zero, $t0, 0
XchgSelNumErr:
- addi.d $a0, $zero, -1
- jirl $zero, $ra, 0
+ break 0
BasicCsrXchange:
CsrSel = LOONGARCH_CSR_CRMD
@@ -386,8 +383,8 @@ TlbCsrXchange:
.endr
CfgCsrXchange:
- CsrSel = LOONGARCH_CSR_CPUNUM
- .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUNUM + 1
+ CsrSel = LOONGARCH_CSR_CPUID
+ .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUID + 1
AsmCsrXChange CsrSel
CsrSel = CsrSel + 1
.endr
diff --git a/MdePkg/Library/BaseLib/LoongArch64/Csr.c b/MdePkg/Library/BaseLib/LoongArch64/Csr.c
index f2ec80b..5a40bfe 100644
--- a/MdePkg/Library/BaseLib/LoongArch64/Csr.c
+++ b/MdePkg/Library/BaseLib/LoongArch64/Csr.c
@@ -29,7 +29,8 @@ AsmCsrXChg (
@param[in] Select CSR read instruction select values.
- @return The return value of csrrd instruction, return -1 means Select is out of support.
+ @return The return value of csrrd instruction,
+ if a break exception is triggered, the Select is out of support.
**/
UINTN
EFIAPI
@@ -47,7 +48,7 @@ CsrRead (
@param[in, out] Value The csrwr will write the value.
@return The return value of csrwr instruction, that is, store the old value of
- the register, return -1 means Select is out of support.
+ the register, if a break exception is triggered, the Select is out of support.
**/
UINTN
EFIAPI
@@ -67,7 +68,7 @@ CsrWrite (
@param[in] Mask The csrxchg mask value.
@return The return value of csrxchg instruction, that is, store the old value of
- the register, return -1 means Select is out of support.
+ the register, if a break exception is triggered, the Select is out of support.
**/
UINTN
EFIAPI
diff --git a/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf b/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
index e84a2c7..eac88cf 100644
--- a/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+++ b/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
@@ -32,6 +32,7 @@
ScanMem8Wrapper.c
ZeroMemWrapper.c
CompareMemWrapper.c
+ SetMemNWrapper.c
SetMem64Wrapper.c
SetMem32Wrapper.c
SetMem16Wrapper.c
diff --git a/MdePkg/Library/BaseMemoryLib/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLib/SetMemNWrapper.c
new file mode 100644
index 0000000..8a7cfca
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLib/SetMemNWrapper.c
@@ -0,0 +1,54 @@
+/** @file
+ SetMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a value that is size UINTN, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the UINTN sized value specified by
+ Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The number of bytes in Buffer to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMemN (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return SetMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return SetMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
diff --git a/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c
index 39ec8cb..31f8bd4 100644
--- a/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c
+++ b/MdePkg/Library/BaseMemoryLib/SetMemWrapper.c
@@ -1,5 +1,5 @@
/** @file
- SetMem() and SetMemN() implementation.
+ SetMem() implementation.
The following BaseMemoryLib instances contain the same copy of this file:
@@ -49,37 +49,3 @@ SetMem (
return InternalMemSetMem (Buffer, Length, Value);
}
-
-/**
- Fills a target buffer with a value that is size UINTN, and returns the target buffer.
-
- This function fills Length bytes of Buffer with the UINTN sized value specified by
- Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
- bytes of Buffer.
-
- If Length > 0 and Buffer is NULL, then ASSERT().
- If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
- If Buffer is not aligned on a UINTN boundary, then ASSERT().
- If Length is not aligned on a UINTN boundary, then ASSERT().
-
- @param Buffer The pointer to the target buffer to fill.
- @param Length The number of bytes in Buffer to fill.
- @param Value The value with which to fill Length bytes of Buffer.
-
- @return Buffer.
-
-**/
-VOID *
-EFIAPI
-SetMemN (
- OUT VOID *Buffer,
- IN UINTN Length,
- IN UINTN Value
- )
-{
- if (sizeof (UINTN) == sizeof (UINT64)) {
- return SetMem64 (Buffer, Length, (UINT64)Value);
- } else {
- return SetMem32 (Buffer, Length, (UINT32)Value);
- }
-}
diff --git a/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf b/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf
index c470fa4..2f37c69 100644
--- a/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf
+++ b/MdePkg/Library/BaseMemoryLibMmx/BaseMemoryLibMmx.inf
@@ -36,6 +36,7 @@
ScanMem8Wrapper.c
ZeroMemWrapper.c
CompareMemWrapper.c
+ SetMemNWrapper.c
SetMem64Wrapper.c
SetMem32Wrapper.c
SetMem16Wrapper.c
@@ -57,17 +58,6 @@
Ia32/ZeroMem.nasm
Ia32/SetMem.nasm
Ia32/CopyMem.nasm
- Ia32/ScanMem64.nasm
- Ia32/ScanMem32.nasm
- Ia32/ScanMem16.nasm
- Ia32/ScanMem8.nasm
- Ia32/CompareMem.nasm
- Ia32/SetMem64.nasm
- Ia32/SetMem32.nasm
- Ia32/SetMem16.nasm
- Ia32/ZeroMem.nasm
- Ia32/SetMem.nasm
- Ia32/CopyMem.nasm
Ia32/IsZeroBuffer.nasm
[Sources.X64]
@@ -82,20 +72,8 @@
X64/SetMem16.nasm
X64/SetMem.nasm
X64/CopyMem.nasm
- X64/ScanMem64.nasm
- X64/ScanMem32.nasm
- X64/ScanMem16.nasm
- X64/ScanMem8.nasm
- X64/CompareMem.nasm
- X64/SetMem64.nasm
- X64/SetMem32.nasm
- X64/SetMem16.nasm
- X64/ZeroMem.nasm
- X64/SetMem.nasm
- X64/CopyMem.nasm
X64/IsZeroBuffer.nasm
-
[LibraryClasses]
DebugLib
BaseLib
diff --git a/MdePkg/Library/BaseMemoryLibMmx/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLibMmx/SetMemNWrapper.c
new file mode 100644
index 0000000..8a7cfca
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibMmx/SetMemNWrapper.c
@@ -0,0 +1,54 @@
+/** @file
+ SetMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a value that is size UINTN, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the UINTN sized value specified by
+ Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The number of bytes in Buffer to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMemN (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return SetMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return SetMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
diff --git a/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c
index 39ec8cb..31f8bd4 100644
--- a/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c
+++ b/MdePkg/Library/BaseMemoryLibMmx/SetMemWrapper.c
@@ -1,5 +1,5 @@
/** @file
- SetMem() and SetMemN() implementation.
+ SetMem() implementation.
The following BaseMemoryLib instances contain the same copy of this file:
@@ -49,37 +49,3 @@ SetMem (
return InternalMemSetMem (Buffer, Length, Value);
}
-
-/**
- Fills a target buffer with a value that is size UINTN, and returns the target buffer.
-
- This function fills Length bytes of Buffer with the UINTN sized value specified by
- Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
- bytes of Buffer.
-
- If Length > 0 and Buffer is NULL, then ASSERT().
- If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
- If Buffer is not aligned on a UINTN boundary, then ASSERT().
- If Length is not aligned on a UINTN boundary, then ASSERT().
-
- @param Buffer The pointer to the target buffer to fill.
- @param Length The number of bytes in Buffer to fill.
- @param Value The value with which to fill Length bytes of Buffer.
-
- @return Buffer.
-
-**/
-VOID *
-EFIAPI
-SetMemN (
- OUT VOID *Buffer,
- IN UINTN Length,
- IN UINTN Value
- )
-{
- if (sizeof (UINTN) == sizeof (UINT64)) {
- return SetMem64 (Buffer, Length, (UINT64)Value);
- } else {
- return SetMem32 (Buffer, Length, (UINT32)Value);
- }
-}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
index 366a6c6..ed10b2e 100644
--- a/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
@@ -40,17 +40,6 @@
Ia32/SetMem16.nasm
Ia32/SetMem.nasm
Ia32/CopyMem.nasm
- Ia32/ScanMem64.nasm
- Ia32/ScanMem32.nasm
- Ia32/ScanMem16.nasm
- Ia32/ScanMem8.nasm
- Ia32/CompareMem.nasm
- Ia32/ZeroMem.nasm
- Ia32/SetMem64.nasm
- Ia32/SetMem32.nasm
- Ia32/SetMem16.nasm
- Ia32/SetMem.nasm
- Ia32/CopyMem.nasm
Ia32/IsZeroBuffer.nasm
MemLibGuid.c
@@ -103,6 +92,7 @@
ScanMem8Wrapper.c
ZeroMemWrapper.c
CompareMemWrapper.c
+ SetMemNWrapper.c
SetMem64Wrapper.c
SetMem32Wrapper.c
SetMem16Wrapper.c
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/SetMemNWrapper.c
new file mode 100644
index 0000000..8a7cfca
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/SetMemNWrapper.c
@@ -0,0 +1,54 @@
+/** @file
+ SetMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a value that is size UINTN, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the UINTN sized value specified by
+ Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The number of bytes in Buffer to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMemN (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return SetMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return SetMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c
index 39ec8cb..31f8bd4 100644
--- a/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c
+++ b/MdePkg/Library/BaseMemoryLibOptDxe/SetMemWrapper.c
@@ -1,5 +1,5 @@
/** @file
- SetMem() and SetMemN() implementation.
+ SetMem() implementation.
The following BaseMemoryLib instances contain the same copy of this file:
@@ -49,37 +49,3 @@ SetMem (
return InternalMemSetMem (Buffer, Length, Value);
}
-
-/**
- Fills a target buffer with a value that is size UINTN, and returns the target buffer.
-
- This function fills Length bytes of Buffer with the UINTN sized value specified by
- Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
- bytes of Buffer.
-
- If Length > 0 and Buffer is NULL, then ASSERT().
- If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
- If Buffer is not aligned on a UINTN boundary, then ASSERT().
- If Length is not aligned on a UINTN boundary, then ASSERT().
-
- @param Buffer The pointer to the target buffer to fill.
- @param Length The number of bytes in Buffer to fill.
- @param Value The value with which to fill Length bytes of Buffer.
-
- @return Buffer.
-
-**/
-VOID *
-EFIAPI
-SetMemN (
- OUT VOID *Buffer,
- IN UINTN Length,
- IN UINTN Value
- )
-{
- if (sizeof (UINTN) == sizeof (UINT64)) {
- return SetMem64 (Buffer, Length, (UINT64)Value);
- } else {
- return SetMem32 (Buffer, Length, (UINT32)Value);
- }
-}
diff --git a/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf b/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf
index 0bb4b7c..7e31369 100644
--- a/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf
+++ b/MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf
@@ -27,6 +27,20 @@
[Sources]
MemLibInternals.h
+ ScanMem64Wrapper.c
+ ScanMem32Wrapper.c
+ ScanMem16Wrapper.c
+ ScanMem8Wrapper.c
+ ZeroMemWrapper.c
+ CompareMemWrapper.c
+ SetMemNWrapper.c
+ SetMem64Wrapper.c
+ SetMem32Wrapper.c
+ SetMem16Wrapper.c
+ SetMemWrapper.c
+ CopyMemWrapper.c
+ IsZeroBufferWrapper.c
+ MemLibGuid.c
[Sources.Ia32]
Ia32/ScanMem64.nasm
@@ -40,31 +54,7 @@
Ia32/SetMem16.nasm
Ia32/SetMem.nasm
Ia32/CopyMem.nasm
- Ia32/ScanMem64.nasm
- Ia32/ScanMem32.nasm
- Ia32/ScanMem16.nasm
- Ia32/ScanMem8.nasm
- Ia32/CompareMem.nasm
- Ia32/ZeroMem.nasm
- Ia32/SetMem64.nasm
- Ia32/SetMem32.nasm
- Ia32/SetMem16.nasm
- Ia32/SetMem.nasm
- Ia32/CopyMem.nasm
Ia32/IsZeroBuffer.nasm
- ScanMem64Wrapper.c
- ScanMem32Wrapper.c
- ScanMem16Wrapper.c
- ScanMem8Wrapper.c
- ZeroMemWrapper.c
- CompareMemWrapper.c
- SetMem64Wrapper.c
- SetMem32Wrapper.c
- SetMem16Wrapper.c
- SetMemWrapper.c
- CopyMemWrapper.c
- IsZeroBufferWrapper.c
- MemLibGuid.c
[Sources.X64]
X64/ScanMem64.nasm
@@ -79,20 +69,6 @@
X64/SetMem.nasm
X64/CopyMem.nasm
X64/IsZeroBuffer.nasm
- ScanMem64Wrapper.c
- ScanMem32Wrapper.c
- ScanMem16Wrapper.c
- ScanMem8Wrapper.c
- ZeroMemWrapper.c
- CompareMemWrapper.c
- SetMem64Wrapper.c
- SetMem32Wrapper.c
- SetMem16Wrapper.c
- SetMemWrapper.c
- CopyMemWrapper.c
- IsZeroBufferWrapper.c
- MemLibGuid.c
-
[Packages]
MdePkg/MdePkg.dec
diff --git a/MdePkg/Library/BaseMemoryLibOptPei/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLibOptPei/SetMemNWrapper.c
new file mode 100644
index 0000000..8a7cfca
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibOptPei/SetMemNWrapper.c
@@ -0,0 +1,54 @@
+/** @file
+ SetMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a value that is size UINTN, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the UINTN sized value specified by
+ Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The number of bytes in Buffer to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMemN (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return SetMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return SetMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
diff --git a/MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c
index 39ec8cb..31f8bd4 100644
--- a/MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c
+++ b/MdePkg/Library/BaseMemoryLibOptPei/SetMemWrapper.c
@@ -1,5 +1,5 @@
/** @file
- SetMem() and SetMemN() implementation.
+ SetMem() implementation.
The following BaseMemoryLib instances contain the same copy of this file:
@@ -49,37 +49,3 @@ SetMem (
return InternalMemSetMem (Buffer, Length, Value);
}
-
-/**
- Fills a target buffer with a value that is size UINTN, and returns the target buffer.
-
- This function fills Length bytes of Buffer with the UINTN sized value specified by
- Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
- bytes of Buffer.
-
- If Length > 0 and Buffer is NULL, then ASSERT().
- If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
- If Buffer is not aligned on a UINTN boundary, then ASSERT().
- If Length is not aligned on a UINTN boundary, then ASSERT().
-
- @param Buffer The pointer to the target buffer to fill.
- @param Length The number of bytes in Buffer to fill.
- @param Value The value with which to fill Length bytes of Buffer.
-
- @return Buffer.
-
-**/
-VOID *
-EFIAPI
-SetMemN (
- OUT VOID *Buffer,
- IN UINTN Length,
- IN UINTN Value
- )
-{
- if (sizeof (UINTN) == sizeof (UINT64)) {
- return SetMem64 (Buffer, Length, (UINT64)Value);
- } else {
- return SetMem32 (Buffer, Length, (UINT32)Value);
- }
-}
diff --git a/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf b/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
index 9d4f876..4dad964 100644
--- a/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+++ b/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
@@ -33,6 +33,7 @@
ScanMem8Wrapper.c
ZeroMemWrapper.c
CompareMemWrapper.c
+ SetMemNWrapper.c
SetMem64Wrapper.c
SetMem32Wrapper.c
SetMem16Wrapper.c
@@ -53,17 +54,6 @@
Ia32/SetMem16.nasm
Ia32/SetMem.nasm
Ia32/CopyMem.nasm
- Ia32/ScanMem64.nasm
- Ia32/ScanMem32.nasm
- Ia32/ScanMem16.nasm
- Ia32/ScanMem8.nasm
- Ia32/CompareMem.nasm
- Ia32/ZeroMem.nasm
- Ia32/SetMem64.nasm
- Ia32/SetMem32.nasm
- Ia32/SetMem16.nasm
- Ia32/SetMem.nasm
- Ia32/CopyMem.nasm
Ia32/IsZeroBuffer.nasm
[Sources.X64]
@@ -78,17 +68,6 @@
X64/SetMem16.nasm
X64/SetMem.nasm
X64/CopyMem.nasm
- X64/ScanMem64.nasm
- X64/ScanMem32.nasm
- X64/ScanMem16.nasm
- X64/ScanMem8.nasm
- X64/CompareMem.nasm
- X64/ZeroMem.nasm
- X64/SetMem64.nasm
- X64/SetMem32.nasm
- X64/SetMem16.nasm
- X64/SetMem.nasm
- X64/CopyMem.nasm
X64/IsZeroBuffer.nasm
[Packages]
diff --git a/MdePkg/Library/BaseMemoryLibRepStr/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLibRepStr/SetMemNWrapper.c
new file mode 100644
index 0000000..8a7cfca
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibRepStr/SetMemNWrapper.c
@@ -0,0 +1,54 @@
+/** @file
+ SetMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a value that is size UINTN, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the UINTN sized value specified by
+ Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The number of bytes in Buffer to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMemN (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return SetMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return SetMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
diff --git a/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c
index 39ec8cb..31f8bd4 100644
--- a/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c
+++ b/MdePkg/Library/BaseMemoryLibRepStr/SetMemWrapper.c
@@ -1,5 +1,5 @@
/** @file
- SetMem() and SetMemN() implementation.
+ SetMem() implementation.
The following BaseMemoryLib instances contain the same copy of this file:
@@ -49,37 +49,3 @@ SetMem (
return InternalMemSetMem (Buffer, Length, Value);
}
-
-/**
- Fills a target buffer with a value that is size UINTN, and returns the target buffer.
-
- This function fills Length bytes of Buffer with the UINTN sized value specified by
- Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
- bytes of Buffer.
-
- If Length > 0 and Buffer is NULL, then ASSERT().
- If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
- If Buffer is not aligned on a UINTN boundary, then ASSERT().
- If Length is not aligned on a UINTN boundary, then ASSERT().
-
- @param Buffer The pointer to the target buffer to fill.
- @param Length The number of bytes in Buffer to fill.
- @param Value The value with which to fill Length bytes of Buffer.
-
- @return Buffer.
-
-**/
-VOID *
-EFIAPI
-SetMemN (
- OUT VOID *Buffer,
- IN UINTN Length,
- IN UINTN Value
- )
-{
- if (sizeof (UINTN) == sizeof (UINT64)) {
- return SetMem64 (Buffer, Length, (UINT64)Value);
- } else {
- return SetMem32 (Buffer, Length, (UINT32)Value);
- }
-}
diff --git a/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf b/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf
index 79618c9..fbc1a7b 100644
--- a/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf
+++ b/MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf
@@ -32,6 +32,7 @@
ScanMem8Wrapper.c
ZeroMemWrapper.c
CompareMemWrapper.c
+ SetMemNWrapper.c
SetMem64Wrapper.c
SetMem32Wrapper.c
SetMem16Wrapper.c
@@ -52,17 +53,6 @@
Ia32/SetMem16.nasm
Ia32/SetMem.nasm
Ia32/CopyMem.nasm
- Ia32/ScanMem64.nasm
- Ia32/ScanMem32.nasm
- Ia32/ScanMem16.nasm
- Ia32/ScanMem8.nasm
- Ia32/CompareMem.nasm
- Ia32/ZeroMem.nasm
- Ia32/SetMem64.nasm
- Ia32/SetMem32.nasm
- Ia32/SetMem16.nasm
- Ia32/SetMem.nasm
- Ia32/CopyMem.nasm
Ia32/IsZeroBuffer.nasm
[Sources.X64]
@@ -77,17 +67,6 @@
X64/SetMem16.nasm
X64/SetMem.nasm
X64/CopyMem.nasm
- X64/ScanMem64.nasm
- X64/ScanMem32.nasm
- X64/ScanMem16.nasm
- X64/ScanMem8.nasm
- X64/CompareMem.nasm
- X64/ZeroMem.nasm
- X64/SetMem64.nasm
- X64/SetMem32.nasm
- X64/SetMem16.nasm
- X64/SetMem.nasm
- X64/CopyMem.nasm
X64/IsZeroBuffer.nasm
[Packages]
diff --git a/MdePkg/Library/BaseMemoryLibSse2/SetMemNWrapper.c b/MdePkg/Library/BaseMemoryLibSse2/SetMemNWrapper.c
new file mode 100644
index 0000000..8a7cfca
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibSse2/SetMemNWrapper.c
@@ -0,0 +1,54 @@
+/** @file
+ SetMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a value that is size UINTN, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the UINTN sized value specified by
+ Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The number of bytes in Buffer to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMemN (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return SetMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return SetMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
diff --git a/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c b/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c
index 39ec8cb..31f8bd4 100644
--- a/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c
+++ b/MdePkg/Library/BaseMemoryLibSse2/SetMemWrapper.c
@@ -1,5 +1,5 @@
/** @file
- SetMem() and SetMemN() implementation.
+ SetMem() implementation.
The following BaseMemoryLib instances contain the same copy of this file:
@@ -49,37 +49,3 @@ SetMem (
return InternalMemSetMem (Buffer, Length, Value);
}
-
-/**
- Fills a target buffer with a value that is size UINTN, and returns the target buffer.
-
- This function fills Length bytes of Buffer with the UINTN sized value specified by
- Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
- bytes of Buffer.
-
- If Length > 0 and Buffer is NULL, then ASSERT().
- If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
- If Buffer is not aligned on a UINTN boundary, then ASSERT().
- If Length is not aligned on a UINTN boundary, then ASSERT().
-
- @param Buffer The pointer to the target buffer to fill.
- @param Length The number of bytes in Buffer to fill.
- @param Value The value with which to fill Length bytes of Buffer.
-
- @return Buffer.
-
-**/
-VOID *
-EFIAPI
-SetMemN (
- OUT VOID *Buffer,
- IN UINTN Length,
- IN UINTN Value
- )
-{
- if (sizeof (UINTN) == sizeof (UINT64)) {
- return SetMem64 (Buffer, Length, (UINT64)Value);
- } else {
- return SetMem32 (Buffer, Length, (UINT32)Value);
- }
-}
diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
index 86ff2e7..617e86d 100644
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
@@ -1054,7 +1054,7 @@ PeCoffLoaderRelocateImage (
RelocDir = &Hdr.Te->DataDirectory[0];
}
- if ((RelocDir != NULL) && (RelocDir->Size > 0)) {
+ if ((RelocDir != NULL) && (RelocDir->Size > 0) && ((RelocDir->Size - 1) < (MAX_UINT32 - RelocDir->VirtualAddress))) {
RelocBase = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress, TeStrippedOffset);
RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *)PeCoffLoaderImageAddress (
ImageContext,
diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
index 2d6ef48..b4b3c97 100644
--- a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
+++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h
@@ -27,16 +27,4 @@ ArmRndr (
OUT UINT64 *Rand
);
-/**
- Reads the ID_AA64ISAR0 Register.
-
- @return The contents of the ID_AA64ISAR0 register.
-
-**/
-UINT64
-EFIAPI
-ArmReadIdIsar0 (
- VOID
- );
-
#endif /* ARM_RNG_H_ */
diff --git a/MdePkg/Library/BaseRngLib/AArch64/Rndr.c b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
index 3a556a2..2c53443 100644
--- a/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
+++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
@@ -21,11 +21,6 @@
STATIC BOOLEAN mRndrSupported;
-//
-// Bit mask used to determine if RNDR instruction is supported.
-//
-#define RNDR_MASK ((UINT64)MAX_UINT16 << 60U)
-
/**
The constructor function checks whether or not RNDR instruction is supported
by the host hardware.
@@ -49,9 +44,8 @@ BaseRngLibConstructor (
// Determine RNDR support by examining bits 63:60 of the ISAR0 register returned by
// MSR. A non-zero value indicates that the processor supports the RNDR instruction.
//
- Isar0 = ArmReadIdIsar0 ();
-
- mRndrSupported = ((Isar0 & RNDR_MASK) != 0);
+ Isar0 = ArmReadIdAA64Isar0Reg ();
+ mRndrSupported = !!((Isar0 >> ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT) & ARM_ID_AA64ISAR0_EL1_RNDR_MASK);
return EFI_SUCCESS;
}
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.inf b/MdePkg/Library/BaseRngLib/BaseRngLib.inf
index 49503b1..53833a7 100644
--- a/MdePkg/Library/BaseRngLib/BaseRngLib.inf
+++ b/MdePkg/Library/BaseRngLib/BaseRngLib.inf
@@ -38,10 +38,8 @@
AArch64/Rndr.c
AArch64/ArmRng.h
- AArch64/ArmReadIdIsar0.S | GCC
AArch64/ArmRng.S | GCC
- AArch64/ArmReadIdIsar0.asm | MSFT
AArch64/ArmRng.asm | MSFT
[Guids.AARCH64]
@@ -50,6 +48,10 @@
[Guids.Ia32, Guids.X64]
gEfiRngAlgorithmSp80090Ctr256Guid
+[Sources.RISCV64]
+ Riscv/Rng.c
+ Riscv/Seed.S | GCC
+
[Packages]
MdePkg/MdePkg.dec
@@ -59,3 +61,7 @@
[LibraryClasses]
BaseLib
DebugLib
+
+[Pcd.RISCV64]
+ # Does the CPU support the Zkr extension (for the `Seed` CSR)
+ gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride ## CONSUMES
diff --git a/MdePkg/Library/BaseRngLib/Riscv/Rng.c b/MdePkg/Library/BaseRngLib/Riscv/Rng.c
new file mode 100644
index 0000000..305ab60
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/Riscv/Rng.c
@@ -0,0 +1,277 @@
+/** @file
+ Random number generator service that uses the SEED instruction
+ to provide pseudorandom numbers.
+
+ Copyright (c) 2024, Rivos, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+ **/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RngLib.h>
+#include <Register/RiscV64/RiscVEncoding.h>
+
+#include "BaseRngLibInternals.h"
+#define RISCV_CPU_FEATURE_ZKR_BITMASK 0x8
+
+#define SEED_RETRY_LOOPS 100
+
+// 64-bit Mersenne Twister implementation
+// A widely used pseudo random number generator. It performs bit shifts etc to
+// achieve the random number. It's output is determined by SEED value generated
+// by RISC-V SEED CSR"
+
+#define STATE_SIZE 312
+#define MIDDLE 156
+#define INIT_SHIFT 62
+#define TWIST_MASK 0xb5026f5aa96619e9ULL
+#define INIT_FACT 6364136223846793005ULL
+#define SHIFT1 29
+#define MASK1 0x5555555555555555ULL
+#define SHIFT2 17
+#define MASK2 0x71d67fffeda60000ULL
+#define SHIFT3 37
+#define MASK3 0xfff7eee000000000ULL
+#define SHIFT4 43
+
+#define LOWER_MASK 0x7fffffff
+#define UPPER_MASK (~(UINT64)LOWER_MASK)
+
+static UINT64 mState[STATE_SIZE];
+static UINTN mIndex = STATE_SIZE + 1;
+
+/**
+ Initialize mState to defualt state.
+
+ @param[in] S Input seed value
+ **/
+STATIC
+VOID
+SeedRng (
+ IN UINT64 S
+ )
+{
+ UINTN I;
+
+ mIndex = STATE_SIZE;
+ mState[0] = S;
+
+ for (I = 1; I < STATE_SIZE; I++) {
+ mState[I] = (INIT_FACT * (mState[I - 1] ^ (mState[I - 1] >> INIT_SHIFT))) + I;
+ }
+}
+
+/**
+ Initializes mState with entropy values. The initialization is based on the
+ Seed value populated in mState[0] which then influences all the other values
+ in the mState array. Later values are retrieved from the same array instead
+ of calling trng instruction every time.
+
+ **/
+STATIC
+VOID
+TwistRng (
+ VOID
+ )
+{
+ UINTN I;
+ UINT64 X;
+
+ for (I = 0; I < STATE_SIZE; I++) {
+ X = (mState[I] & UPPER_MASK) | (mState[(I + 1) % STATE_SIZE] & LOWER_MASK);
+ X = (X >> 1) ^ (X & 1 ? TWIST_MASK : 0);
+ mState[I] = mState[(I + MIDDLE) % STATE_SIZE] ^ X;
+ }
+
+ mIndex = 0;
+}
+
+// Defined in Seed.S
+extern UINT64
+ReadSeed (
+ VOID
+ );
+
+/**
+ Gets seed value by executing trng instruction (CSR 0x15) amd returns
+ the see to the caller 64bit value.
+
+ @param[out] Out Buffer pointer to store the 64-bit random value.
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+ **/
+STATIC
+BOOLEAN
+Get64BitSeed (
+ OUT UINT64 *Out
+ )
+{
+ UINT64 Seed;
+ UINTN Retry;
+ UINTN ValidSeeds;
+ UINTN NeededSeeds;
+ UINT16 *Entropy;
+
+ Retry = SEED_RETRY_LOOPS;
+ Entropy = (UINT16 *)Out;
+ NeededSeeds = sizeof (UINT64) / sizeof (UINT16);
+ ValidSeeds = 0;
+
+ if (!ArchIsRngSupported ()) {
+ DEBUG ((DEBUG_ERROR, "Get64BitSeed: HW not supported!\n"));
+ return FALSE;
+ }
+
+ do {
+ Seed = ReadSeed ();
+
+ switch (Seed & SEED_OPST_MASK) {
+ case SEED_OPST_ES16:
+ Entropy[ValidSeeds++] = Seed & SEED_ENTROPY_MASK;
+ if (ValidSeeds == NeededSeeds) {
+ return TRUE;
+ }
+
+ break;
+
+ case SEED_OPST_DEAD:
+ DEBUG ((DEBUG_ERROR, "Get64BitSeed: Unrecoverable error!\n"));
+ return FALSE;
+
+ case SEED_OPST_BIST: // fallthrough
+ case SEED_OPST_WAIT: // fallthrough
+ default:
+ continue;
+ }
+ } while (--Retry);
+
+ return FALSE;
+}
+
+/**
+ Constructor library which initializes Seeds and mStatus array.
+
+ @retval EFI_SUCCESS Intialization was successful.
+ @retval EFI_UNSUPPORTED Feature not supported.
+
+ **/
+EFI_STATUS
+EFIAPI
+BaseRngLibConstructor (
+ VOID
+ )
+{
+ UINT64 Seed;
+
+ if (Get64BitSeed (&Seed)) {
+ SeedRng (Seed);
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+/**
+ Generates a 16-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 16-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+ **/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber16 (
+ OUT UINT16 *Rand
+ )
+{
+ UINT64 Rand64;
+
+ if (ArchGetRandomNumber64 (&Rand64)) {
+ *Rand = Rand64 & MAX_UINT16;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 32-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 32-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+ **/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber32 (
+ OUT UINT32 *Rand
+ )
+{
+ UINT64 Rand64;
+
+ if (ArchGetRandomNumber64 (&Rand64)) {
+ *Rand = Rand64 & MAX_UINT32;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Generates a 64-bit random number.
+
+ @param[out] Rand Buffer pointer to store the 64-bit random value.
+
+ @retval TRUE Random number generated successfully.
+ @retval FALSE Failed to generate the random number.
+
+ **/
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber64 (
+ OUT UINT64 *Rand
+ )
+{
+ UINT64 Y;
+
+ // Never initialized.
+ if (mIndex > STATE_SIZE) {
+ return FALSE;
+ }
+
+ // Mersenne Twister
+ if (mIndex == STATE_SIZE) {
+ TwistRng ();
+ }
+
+ Y = mState[mIndex];
+ Y ^= (Y >> SHIFT1) & MASK1;
+ Y ^= (Y << SHIFT2) & MASK2;
+ Y ^= (Y << SHIFT3) & MASK3;
+ Y ^= Y >> SHIFT4;
+
+ mIndex++;
+
+ *Rand = Y;
+ return TRUE;
+}
+
+/**
+ Checks whether SEED is supported.
+
+ @retval TRUE SEED is supported.
+ **/
+BOOLEAN
+EFIAPI
+ArchIsRngSupported (
+ VOID
+ )
+{
+ return ((PcdGet64 (PcdRiscVFeatureOverride) & RISCV_CPU_FEATURE_ZKR_BITMASK) != 0);
+}
diff --git a/MdePkg/Library/BaseRngLib/Riscv/Seed.S b/MdePkg/Library/BaseRngLib/Riscv/Seed.S
new file mode 100644
index 0000000..0028923
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/Riscv/Seed.S
@@ -0,0 +1,19 @@
+//------------------------------------------------------------------------------
+//
+// RISC-V cache operation.
+//
+// Copyright (c) 2024, Rivos Inc. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//------------------------------------------------------------------------------
+
+#include <Register/RiscV64/RiscVImpl.h>
+
+.text
+ .p2align 4
+
+ASM_FUNC (ReadSeed)
+#The SEED CSR must only be accessed with read-write instructions
+csrrw a0, CSR_SEED, x0
+ret
diff --git a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckGcc.c b/MdePkg/Library/BaseStackCheckLib/BaseStackCheckGcc.c
deleted file mode 100644
index ea16884..0000000
--- a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckGcc.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/** @file
- Base Stack Check library for GCC/clang.
-
- Use -fstack-protector-all compiler flag to make the compiler insert the
- __stack_chk_guard "canary" value into the stack and check the value prior
- to exiting the function. If the "canary" is overwritten __stack_chk_fail()
- is called. This is GCC specific code.
-
- Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
- Copyright (c) 2012, Apple Inc. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Base.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/PcdLib.h>
-
-/// "canary" value that is inserted by the compiler into the stack frame.
-VOID *__stack_chk_guard = (VOID *)0x0AFF;
-
-// If ASLR was enabled we could use
-// void (*__stack_chk_guard)(void) = __stack_chk_fail;
-
-/**
- Error path for compiler generated stack "canary" value check code. If the
- stack canary has been overwritten this function gets called on exit of the
- function.
-**/
-VOID
-__stack_chk_fail (
- VOID
- )
-{
- UINT8 DebugPropertyMask;
-
- DEBUG ((DEBUG_ERROR, "STACK FAULT: Buffer Overflow at 0x%p.\n", RETURN_ADDRESS (0)));
-
- //
- // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings even if
- // BaseDebugLibNull is in use.
- //
- DebugPropertyMask = PcdGet8 (PcdDebugPropertyMask);
- if ((DebugPropertyMask & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
- CpuBreakpoint ();
- } else if ((DebugPropertyMask & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
- CpuDeadLoop ();
- }
-}
diff --git a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf b/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
deleted file mode 100644
index b827645..0000000
--- a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+++ /dev/null
@@ -1,39 +0,0 @@
-## @file
-# Stack Check Library
-#
-# Stack Check Library
-#
-# Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = BaseStackCheckLib
- MODULE_UNI_FILE = BaseStackCheckLib.uni
- FILE_GUID = 5f6579f7-b648-4fdb-9f19-4c17e27e8eff
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = NULL
-
-
-#
-# VALID_ARCHITECTURES = ARM AARCH64
-#
-
-[Sources]
- BaseStackCheckGcc.c | GCC
- BaseStackCheckNull.c | MSFT
-
-[Packages]
- MdePkg/MdePkg.dec
-
-[LibraryClasses]
- BaseLib
- DebugLib
-
-[Pcd]
- gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask ## CONSUMES
diff --git a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.uni b/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.uni
deleted file mode 100644
index 03b9d7c..0000000
--- a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.uni
+++ /dev/null
@@ -1,16 +0,0 @@
-// /** @file
-// Stack Check Library
-//
-// Stack Check Library
-//
-// Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-
-#string STR_MODULE_ABSTRACT #language en-US "Stack Check Library"
-
-#string STR_MODULE_DESCRIPTION #language en-US "Stack Check Library"
-
diff --git a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckNull.c b/MdePkg/Library/BaseStackCheckLib/BaseStackCheckNull.c
deleted file mode 100644
index 3293200..0000000
--- a/MdePkg/Library/BaseStackCheckLib/BaseStackCheckNull.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/** @file
- This file is purely empty as a work around for BaseStackCheck to pass MSVC build.
-
- Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-extern int __BaseStackCheckNull;
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S b/MdePkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S
index 3792020..3792020 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/AArch64/Atomics.S
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S b/MdePkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S
index 79a7b35..77348a0 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/AArch64/ashlti3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__ashlti3)
# return if shift is 0
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S
index dee659b..f5f1450 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ashldi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__ashldi3)
cmp r2, #31
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S
index d60c1c6..855497e 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ashrdi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__ashrdi3)
cmp r2, #31
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S
index 493392a..54a7f3c 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/clzsi2.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__clzsi2)
@ frame_needed = 1, uses_anonymous_args = 0
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S
index 5b21ec7..d1ff500 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ctzsi2.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__ctzsi2)
uxth r3, r0
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/div.S
index d6075ab..d6075ab 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/div.S
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm b/MdePkg/Library/CompilerIntrinsicsLib/Arm/div.asm
index 3cbeaa4..3cbeaa4 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/div.asm
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/div.asm
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S
index f809a7d..c1c3c77 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/divdi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__divdi3)
@ args = 0, pretend = 0, frame = 0
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S
index 45c0fcc..eb4c30f 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/divsi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__divsi3)
eor r3, r0, r0, asr #31
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/lasr.S
index feeea9e..27201de 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lasr.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/lasr.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
#
#UINT64
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S
index 9f4ddda..15c99c5 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.S
@@ -6,7 +6,7 @@
//
//------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
//
// A pair of (unsigned) long longs is returned in {{r0, r1}, {r2, r3}},
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm
index 310b2e7..310b2e7 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ldivmod.asm
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/llsl.S
index cc63a15..d0a4acd 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsl.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/llsl.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
#
#VOID
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/llsr.S
index 246d565..af6fd27 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/llsr.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
#VOID
#EFIAPI
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm b/MdePkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm
index fce1df2..fce1df2 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/llsr.asm
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S
index 829d8de..288573c 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/lshrdi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__lshrdi3)
cmp r2, #31
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/memmove.S
index f9f1932..d8588d3 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/memmove.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/memmove.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
# VOID
# EFIAPI
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S
index faf077d..e208f8f 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/moddi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__moddi3)
stmfd sp!, {r4, r5, r7, lr}
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S
index b329985..d67f88f 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/modsi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__modsi3)
stmfd sp!, {r4, r5, r7, lr}
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S
index adee647..6fdc527 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/muldi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__muldi3)
stmfd sp!, {r4, r5, r6, r7, lr}
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/mullu.S
index a878f3a..a878f3a 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/mullu.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/mullu.S
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S
index 81459fc..81459fc 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/sourcery.S
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switch16.S
index e6d5567..3287087 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch16.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switch16.S
@@ -7,7 +7,7 @@
#**/
#
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
.syntax unified
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switch32.S
index fbf72dd..040d65d 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch32.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switch32.S
@@ -7,7 +7,7 @@
#**/
#
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
.syntax unified
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switch8.S
index aea048f..08fec9a 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switch8.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switch8.S
@@ -7,7 +7,7 @@
#**/
#
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
.syntax unified
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S
index 22aeacd..a94b368 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/switchu8.S
@@ -7,7 +7,7 @@
#**/
#
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
.syntax unified
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S
index 681e3cf..8d199fb 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/ucmpdi2.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__ucmpdi2)
stmfd sp!, {r4, r5, r8, lr}
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S
index 505ae54..ccb6f6c 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/udivdi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__udivdi3)
stmfd sp!, {r7, lr}
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S
index a74db6f..edee8fc 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/udivmoddi4.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
.syntax unified
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S
index e1f7da7..100a6a0 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/udivsi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
.syntax unified
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S
index f611283..f611283 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uldiv.S
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm
index e143052..e143052 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uldiv.asm
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S
index 3f26e2c..b22a785 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/umoddi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__umoddi3)
stmfd sp!, {r7, lr}
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S
index b48b25b..ee548af 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/umodsi3.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
ASM_FUNC(__umodsi3)
stmfd sp!, {r4, r5, r7, lr}
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uread.S
index e8a1dba..132975c 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uread.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uread.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
#
#UINT32
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S
index 9432ac4..2c56ba3 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S
+++ b/MdePkg/Library/CompilerIntrinsicsLib/Arm/uwrite.S
@@ -6,7 +6,7 @@
#
#------------------------------------------------------------------------------
-#include <AsmMacroIoLib.h>
+#include <AsmMacroLib.h>
#
#UINT32
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf b/MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
index 054e681..ac48b46 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+++ b/MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
@@ -10,9 +10,9 @@
#**/
[Defines]
- INF_VERSION = 0x00010005
+ INF_VERSION = 1.29
BASE_NAME = CompilerIntrinsicsLib
- FILE_GUID = 855274FA-3575-4C20-9709-C031DC5589FA
+ FILE_GUID = 2A6B451F-B99D-47B1-8F29-D805433C62E0
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = CompilerIntrinsicsLib
@@ -70,7 +70,6 @@
[Packages]
MdePkg/MdePkg.dec
- ArmPkg/ArmPkg.dec
[BuildOptions]
MSFT:*_*_*_CC_FLAGS = /GL-
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memcmp_ms.c b/MdePkg/Library/CompilerIntrinsicsLib/memcmp_ms.c
index cedbfca..cedbfca 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/memcmp_ms.c
+++ b/MdePkg/Library/CompilerIntrinsicsLib/memcmp_ms.c
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memcpy.c b/MdePkg/Library/CompilerIntrinsicsLib/memcpy.c
index 415146f..415146f 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/memcpy.c
+++ b/MdePkg/Library/CompilerIntrinsicsLib/memcpy.c
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memcpy_ms.c b/MdePkg/Library/CompilerIntrinsicsLib/memcpy_ms.c
index 0eafa83..0eafa83 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/memcpy_ms.c
+++ b/MdePkg/Library/CompilerIntrinsicsLib/memcpy_ms.c
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memmove_ms.c b/MdePkg/Library/CompilerIntrinsicsLib/memmove_ms.c
index f68eb52..f68eb52 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/memmove_ms.c
+++ b/MdePkg/Library/CompilerIntrinsicsLib/memmove_ms.c
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memset.c b/MdePkg/Library/CompilerIntrinsicsLib/memset.c
index 3e45302..3e45302 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/memset.c
+++ b/MdePkg/Library/CompilerIntrinsicsLib/memset.c
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memset_ms.c b/MdePkg/Library/CompilerIntrinsicsLib/memset_ms.c
index 5882cd2..5882cd2 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/memset_ms.c
+++ b/MdePkg/Library/CompilerIntrinsicsLib/memset_ms.c
diff --git a/MdePkg/Library/DxeRngLib/DxeRngLib.c b/MdePkg/Library/DxeRngLib/DxeRngLib.c
index 05c7957..3092d3e 100644
--- a/MdePkg/Library/DxeRngLib/DxeRngLib.c
+++ b/MdePkg/Library/DxeRngLib/DxeRngLib.c
@@ -1,17 +1,136 @@
/** @file
Provides an implementation of the library class RngLib that uses the Rng protocol.
- Copyright (c) 2023, Arm Limited. All rights reserved.
+ Copyright (c) 2023 - 2024, Arm Limited. All rights reserved.
Copyright (c) Microsoft Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Uefi.h>
#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
#include <Library/RngLib.h>
#include <Protocol/Rng.h>
+STATIC EFI_RNG_PROTOCOL *mRngProtocol;
+STATIC UINTN mFirstAlgo = MAX_UINTN;
+
+typedef struct {
+ /// Guid of the secure algorithm.
+ EFI_GUID *Guid;
+
+ /// Algorithm name.
+ CONST CHAR8 *Name;
+
+ /// The algorithm is available for use.
+ BOOLEAN Available;
+} SECURE_RNG_ALGO_ARRAY;
+
+//
+// These represent UEFI SPEC defined algorithms that should be supported by
+// the RNG protocol and are generally considered secure.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED SECURE_RNG_ALGO_ARRAY mSecureHashAlgorithms[] = {
+ #ifdef MDE_CPU_AARCH64
+ {
+ &gEfiRngAlgorithmArmRndr, // unspecified SP800-90A DRBG (through RNDR instr.)
+ "ARM-RNDR",
+ FALSE,
+ },
+ #endif
+ {
+ &gEfiRngAlgorithmSp80090Ctr256Guid, // SP800-90A DRBG CTR using AES-256
+ "DRBG-CTR",
+ FALSE,
+ },
+ {
+ &gEfiRngAlgorithmSp80090Hmac256Guid, // SP800-90A DRBG HMAC using SHA-256
+ "DRBG-HMAC",
+ FALSE,
+ },
+ {
+ &gEfiRngAlgorithmSp80090Hash256Guid, // SP800-90A DRBG Hash using SHA-256
+ "DRBG-Hash",
+ FALSE,
+ },
+ {
+ &gEfiRngAlgorithmRaw, // Raw data from NRBG (or TRNG)
+ "TRNG",
+ FALSE,
+ },
+};
+
+/**
+ Constructor routine to probe the available secure Rng algorithms.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_NOT_FOUND Not found.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+DxeRngLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN RngArraySize;
+ UINTN RngArrayCnt;
+ UINT32 Index;
+ UINT32 Index1;
+ EFI_RNG_ALGORITHM *RngArray;
+
+ Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&mRngProtocol);
+ if (EFI_ERROR (Status) || (mRngProtocol == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a: Could not locate RNG protocol, Status = %r\n", __func__, Status));
+ return Status;
+ }
+
+ RngArraySize = 0;
+
+ Status = mRngProtocol->GetInfo (mRngProtocol, &RngArraySize, NULL);
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ return Status;
+ } else if (RngArraySize == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ RngArrayCnt = RngArraySize / sizeof (*RngArray);
+
+ RngArray = AllocateZeroPool (RngArraySize);
+ if (RngArray == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = mRngProtocol->GetInfo (mRngProtocol, &RngArraySize, RngArray);
+ if (EFI_ERROR (Status)) {
+ goto ExitHandler;
+ }
+
+ for (Index = 0; Index < RngArrayCnt; Index++) {
+ for (Index1 = 0; Index1 < ARRAY_SIZE (mSecureHashAlgorithms); Index1++) {
+ if (CompareGuid (&RngArray[Index], mSecureHashAlgorithms[Index1].Guid)) {
+ mSecureHashAlgorithms[Index1].Available = TRUE;
+ if (mFirstAlgo == MAX_UINTN) {
+ mFirstAlgo = Index1;
+ }
+
+ break;
+ }
+ }
+ }
+
+ExitHandler:
+ FreePool (RngArray);
+ return Status;
+}
+
/**
Routine Description:
@@ -32,55 +151,70 @@ GenerateRandomNumberViaNist800Algorithm (
IN UINTN BufferSize
)
{
- EFI_STATUS Status;
- EFI_RNG_PROTOCOL *RngProtocol;
-
- RngProtocol = NULL;
+ EFI_STATUS Status;
+ UINTN Index;
+ SECURE_RNG_ALGO_ARRAY *Algo;
if (Buffer == NULL) {
DEBUG ((DEBUG_ERROR, "%a: Buffer == NULL.\n", __func__));
return EFI_INVALID_PARAMETER;
}
- Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&RngProtocol);
- if (EFI_ERROR (Status) || (RngProtocol == NULL)) {
- DEBUG ((DEBUG_ERROR, "%a: Could not locate RNG prototocol, Status = %r\n", __func__, Status));
- return Status;
+ if (mRngProtocol == NULL) {
+ return EFI_NOT_FOUND;
}
- Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Ctr256Guid, BufferSize, Buffer);
- DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm CTR-256 - Status = %r\n", __func__, Status));
- if (!EFI_ERROR (Status)) {
- return Status;
+ // Try the first available algorithm.
+ if (mFirstAlgo != MAX_UINTN) {
+ Algo = &mSecureHashAlgorithms[mFirstAlgo];
+ Status = mRngProtocol->GetRNG (mRngProtocol, Algo->Guid, BufferSize, Buffer);
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: GetRNG algorithm %a - Status = %r\n",
+ __func__,
+ Algo->Name,
+ Status
+ ));
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Index = mFirstAlgo + 1;
+ } else {
+ Index = 0;
}
- Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hmac256Guid, BufferSize, Buffer);
- DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm HMAC-256 - Status = %r\n", __func__, Status));
- if (!EFI_ERROR (Status)) {
- return Status;
- }
-
- Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hash256Guid, BufferSize, Buffer);
- DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm Hash-256 - Status = %r\n", __func__, Status));
- if (!EFI_ERROR (Status)) {
- return Status;
+ // Iterate over other available algorithms.
+ for ( ; Index < ARRAY_SIZE (mSecureHashAlgorithms); Index++) {
+ Algo = &mSecureHashAlgorithms[Index];
+ if (!Algo->Available) {
+ continue;
+ }
+
+ Status = mRngProtocol->GetRNG (mRngProtocol, Algo->Guid, BufferSize, Buffer);
+ DEBUG ((
+ DEBUG_INFO,
+ "%a: GetRNG algorithm %a - Status = %r\n",
+ __func__,
+ Algo->Name,
+ Status
+ ));
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
}
- Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmRaw, BufferSize, Buffer);
- DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm Raw - Status = %r\n", __func__, Status));
- if (!EFI_ERROR (Status)) {
- return Status;
- }
-
- // If all the other methods have failed, use the default method from the RngProtocol
- Status = RngProtocol->GetRNG (RngProtocol, NULL, BufferSize, Buffer);
- DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm default - Status = %r\n", __func__, Status));
- if (!EFI_ERROR (Status)) {
- return Status;
+ if (!PcdGetBool (PcdEnforceSecureRngAlgorithms)) {
+ // If all the other methods have failed, use the default method from the RngProtocol
+ Status = mRngProtocol->GetRNG (mRngProtocol, NULL, BufferSize, Buffer);
+ DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm default - Status = %r\n", __func__, Status));
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
}
// If we get to this point, we have failed
- DEBUG ((DEBUG_ERROR, "%a: GetRNG() failed, staus = %r\n", __func__, Status));
+ DEBUG ((DEBUG_ERROR, "%a: GetRNG() failed, Status = %r\n", __func__, Status));
return Status;
}// GenerateRandomNumberViaNist800Algorithm()
diff --git a/MdePkg/Library/DxeRngLib/DxeRngLib.inf b/MdePkg/Library/DxeRngLib/DxeRngLib.inf
index 281fec4..f430b12 100644
--- a/MdePkg/Library/DxeRngLib/DxeRngLib.inf
+++ b/MdePkg/Library/DxeRngLib/DxeRngLib.inf
@@ -15,6 +15,7 @@
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = RngLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER
+ CONSTRUCTOR = DxeRngLibConstructor
[Packages]
MdePkg/MdePkg.dec
@@ -24,6 +25,7 @@
[LibraryClasses]
DebugLib
+ MemoryAllocationLib
UefiBootServicesTableLib
[Protocols]
@@ -37,3 +39,9 @@
gEfiRngAlgorithmSp80090Hash256Guid
gEfiRngAlgorithmSp80090Hmac256Guid
gEfiRngAlgorithmRaw
+
+[Guids.AARCH64]
+ gEfiRngAlgorithmArmRndr
+
+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES
diff --git a/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHook.c b/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHook.c
new file mode 100644
index 0000000..0a258e4
--- /dev/null
+++ b/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHook.c
@@ -0,0 +1,25 @@
+/** @file
+ Library provides a hook called when a stack cookie check fails.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi.h>
+
+/**
+ This function gets called when a compiler generated stack cookie fails. This allows a platform to hook this
+ call and perform any required actions/telemetry at that time.
+
+ @param FailureAddress The address of the function that failed the stack cookie check.
+
+**/
+VOID
+EFIAPI
+StackCheckFailureHook (
+ VOID *FailureAddress
+ )
+{
+ return;
+}
diff --git a/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf b/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf
new file mode 100644
index 0000000..300073a
--- /dev/null
+++ b/MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf
@@ -0,0 +1,20 @@
+## @file
+# Library provides a hook called when a stack cookie check fails.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = StackCheckFailureHookLibNull
+ FILE_GUID = 9ca2587c-d1f2-451a-989a-d49a9a0a613e
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = StackCheckFailureHookLib
+
+[Sources]
+ StackCheckFailureHook.c
+
+[Packages]
+ MdePkg/MdePkg.dec
diff --git a/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S
new file mode 100644
index 0000000..bce1364
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.S
@@ -0,0 +1,21 @@
+//------------------------------------------------------------------------------
+// AArch64/StackCookieInterrupt.S
+//
+// Copyright (c) Microsoft Corporation.
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//------------------------------------------------------------------------------
+
+ .text
+
+//------------------------------------------------------------------------------
+// Calls an interrupt using the vector specified by PcdStackCookieExceptionVector
+//
+// VOID
+// TriggerStackCookieInterrupt (
+// VOID
+// );
+//------------------------------------------------------------------------------
+.global ASM_PFX(TriggerStackCookieInterrupt)
+ASM_PFX(TriggerStackCookieInterrupt):
+ svc FixedPcdGet8 (PcdStackCookieExceptionVector)
+ ret
diff --git a/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm
new file mode 100644
index 0000000..ff5ee35
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/AArch64/StackCookieInterrupt.asm
@@ -0,0 +1,25 @@
+;------------------------------------------------------------------------------
+; AArch64/StackCookieInterrupt.asm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ EXPORT TriggerStackCookieInterrupt
+
+ AREA |.text|, CODE, READONLY
+
+;------------------------------------------------------------------------------
+; Calls an interrupt using the vector specified by PcdStackCookieExceptionVector
+;
+; VOID
+; TriggerStackCookieInterrupt (
+; VOID
+; );
+;------------------------------------------------------------------------------
+TriggerStackCookieInterrupt PROC
+ SVC FixedPcdGet8 (PcdStackCookieExceptionVector)
+ RET
+TriggerStackCookieInterrupt ENDP
+
+ END
diff --git a/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S
new file mode 100644
index 0000000..1f10bb8
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.S
@@ -0,0 +1,21 @@
+//------------------------------------------------------------------------------
+// Arm/StackCookieInterrupt.S
+//
+// Copyright (c) Microsoft Corporation.
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//------------------------------------------------------------------------------
+
+ .text
+
+//------------------------------------------------------------------------------
+// Calls an interrupt using the vector specified by PcdStackCookieExceptionVector
+//
+// VOID
+// TriggerStackCookieInterrupt (
+// VOID
+// );
+//------------------------------------------------------------------------------
+.global ASM_PFX(TriggerStackCookieInterrupt)
+ASM_PFX(TriggerStackCookieInterrupt):
+ swi FixedPcdGet8 (PcdStackCookieExceptionVector)
+ bx lr
diff --git a/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm
new file mode 100644
index 0000000..f1b1e53
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/Arm/StackCookieInterrupt.asm
@@ -0,0 +1,25 @@
+;------------------------------------------------------------------------------
+; Arm/StackCookieInterrupt.asm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ EXPORT TriggerStackCookieInterrupt
+
+ AREA |.text|, CODE, READONLY
+
+;------------------------------------------------------------------------------
+; Calls an interrupt using the vector specified by PcdStackCookieExceptionVector
+;
+; VOID
+; TriggerStackCookieInterrupt (
+; VOID
+; );
+;------------------------------------------------------------------------------
+TriggerStackCookieInterrupt PROC
+ SWI FixedPcdGet8 (PcdStackCookieExceptionVector)
+ BX LR
+TriggerStackCookieInterrupt ENDP
+
+ END
diff --git a/MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm b/MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm
new file mode 100644
index 0000000..a52ee90
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/IA32/CheckCookieMsvc.nasm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------
+; IA32/CheckCookieMsvc.nasm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+extern ASM_PFX(StackCheckFailure)
+extern ASM_PFX(__security_cookie)
+extern ASM_PFX(CpuDeadLoop)
+
+; Called when a buffer check fails. This functionality is dependent on MSVC
+; C runtime libraries and so is unsupported in UEFI.
+global ASM_PFX(__report_rangecheckfailure)
+ASM_PFX(__report_rangecheckfailure):
+ jmp ASM_PFX(CpuDeadLoop)
+ ret
+
+; The GS handler is for checking the stack cookie during SEH or
+; EH exceptions and is unsupported in UEFI.
+global ASM_PFX(__GSHandlerCheck)
+ASM_PFX(__GSHandlerCheck):
+ jmp ASM_PFX(CpuDeadLoop)
+ ret
+
+;------------------------------------------------------------------------------
+; Checks the stack cookie value against __security_cookie and calls the
+; stack cookie failure handler if there is a mismatch.
+;
+; VOID
+; EFIAPI
+; __security_check_cookie (
+; IN UINTN CheckValue
+; );
+;------------------------------------------------------------------------------
+global @__security_check_cookie@4
+@__security_check_cookie@4:
+ cmp ecx, [ASM_PFX(__security_cookie)]
+ jne ASM_PFX(StackCheckFailure)
+ ret
diff --git a/MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm b/MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm
new file mode 100644
index 0000000..83a686d
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/IA32/StackCookieInterrupt.nasm
@@ -0,0 +1,23 @@
+;------------------------------------------------------------------------------
+; IA32/StackCookieInterrupt.nasm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; Checks the stack cookie value against __security_cookie and calls the
+; stack cookie failure handler if there is a mismatch.
+;
+; VOID
+; TriggerStackCookieInterrupt (
+; VOID
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(TriggerStackCookieInterrupt)
+ASM_PFX(TriggerStackCookieInterrupt):
+ int FixedPcdGet8 (PcdStackCookieExceptionVector)
+ ret
diff --git a/MdePkg/Library/StackCheckLib/Readme.md b/MdePkg/Library/StackCheckLib/Readme.md
new file mode 100644
index 0000000..636cd04
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/Readme.md
@@ -0,0 +1,126 @@
+# StackCheckLib
+
+## Table of Contents
+
+- [StackCheckLib](#stackchecklib)
+ - [Table of Contents](#table-of-contents)
+ - [Introduction and Library Instances](#introduction-and-library-instances)
+ - [StackCheckLibStaticInit](#stackchecklibstaticinit)
+ - [StackCheckLibDynamicInit](#stackchecklibdynamicinit)
+ - [StackCheckLibNull](#stackchecklibnull)
+ - [How Failures are Handled](#how-failures-are-handled)
+ - [Debugging Stack Cookie Check Failures](#debugging-stack-cookie-check-failures)
+ - [Usage](#usage)
+
+## Introduction and Library Instances
+
+`StackCheckLib` contains the required functionality for initializing the stack cookie
+value, checking the value, and triggering an interrupt when a mismatch occurs.
+The stack cookie is a random value placed on the stack between the stack variables
+and the return address so that continuously writing past the stack variables will
+cause the stack cookie to be overwritten. Before the function returns, the stack
+cookie value will be checked and if there is a mismatch then `StackCheckLib` handles
+the failure.
+
+Because UEFI doesn't use the C runtime libraries provided by MSVC, the stack
+check code is written in assembly within this library. GCC and Clang compilers
+have built-in support for stack cookie checking, so this library only handles failures.
+
+### StackCheckLibStaticInit
+
+`StackCheckLibStaticInit` is an instance of `StackCheckLib` which does not update the
+stack cookie value for the module at runtime. It's always preferable to use
+`StackCheckLibDynamicInit` for improved security but there are cases where the stack
+cookie global cannot be written to such as in execute-in-place (XIP) modules and during
+the Cache-as-RAM (CAR) phase of the boot process. The stack cookie value is initialized
+at compile time via updates to the AutoGen process. Each module will define
+`STACK_COOKIE_VALUE` which is used for the module stack cookie value.
+
+### StackCheckLibDynamicInit
+
+This section is future work. The below is the proposed instance.
+
+`StackCheckLibDynamicInit` is an instance of `StackCheckLib` which updates the stack
+cookie value for the module at runtime. This is the preferred method for stack cookie
+initialization as it provides improved security. The stack cookie value is initialized
+at runtime by calling `GetRandomNumber32()` or `GetRandomNumber64()` to generate a random
+value via the platform's random number generator protocol. If the random number generator
+returns an error, then the value will still have the build-time randomized value to fall
+back on.
+
+### StackCheckLibNull
+
+`StackCheckLibNull` is an instance of `StackCheckLib` which does not perform any stack
+cookie checks. This is useful for modules which will fail if stack cookie checks are
+inserted. Of course, this is not recommended for production code.
+
+## How Failures are Handled
+
+When a stack cookie check fails, the `StackCheckLib` library will first call into a hook
+function `StackCheckFailureHook()` which only has a NULL implementation in edk2.
+The NULL implementation will simply print the failure address and return, but a platform
+can implement their own instance of this library which can perform additional actions
+before the system triggers an interrupt.
+
+After `StackCheckFailureHook()` returns, the library will trigger an interrupt with
+PcdStackCookieExceptionVector.
+
+- On IA32 and X64 platforms, PcdStackCookieExceptionVector is used as an index into the
+Interrupt Descriptor Table.
+- On ARM platforms, a software interrupt (`SWI`) is called with the value of
+PcdStackCookieExceptionVector. The value can be retrieved by the handler by reading
+bits [7:0] of the instruction opcode which will allow the handler to determine if the
+interrupt was triggered by the stack cookie check. Reference:
+[Arm A64 Instruction Set Architecture Version 2024-3](https://developer.arm.com/documentation/ddi0597/2024-03/Base-Instructions/SVC--Supervisor-Call-?lang=en)
+- On AARCH64 platforms, a supervisor call (`SVC`) is called with the value
+of PcdStackCookieExceptionVector. This value can similarly be retrieved by the
+handler to determine if the interrupt was triggered by the stack cookie check. Reference:
+[Arm A64 Instruction Set Architecture Version 2024-3](https://developer.arm.com/documentation/ddi0602/2024-03/Base-Instructions/SVC--Supervisor-Call-?lang=en)
+
+## Debugging Stack Cookie Check Failures
+
+Tracking down the origin of stack cookie failures can be difficult. Programmers may attempt
+printf debugging to determine which function has an overflow only to find that the failure
+disappears on the next boot. This curiosity is usually due to the black-box heuristic used
+by compilers to determine where to put stack cookie checks or compiler optimization features
+removing the failing check. The address where the failed stack cookie check occurred will
+be printed using DebugLib. If .map files are available, the address combined with the image
+offset can be used to determine the function which failed.
+
+GNU-based compilers have the `-fstack-protector-all` flag to force stack cookie checks on
+all functions which could create a more consistent environment for debugging assuming an
+earlier failure doesn't mask the targeted one and the flash space can accommodate the
+increased size.
+
+The Visual Studio (MSVC) toolchain has the ability to generate `.cod` files during compilation
+which interleave C and the generated assembly code. These files will contain the stack cookie
+checks and are useful for determining where the checks are placed. To generate these files,
+append `/FAcs` to the build options for each target module. The easiest way to do this is to
+update the tools_def file so the `<TARGET>_<TOOLCHAIN>_<ARCH>_CC_FLAGS` includes `/FAcs`.
+
+## Usage
+
+edk2 updated the tools_def to add `/GS` to VS2022 and VS2019 IA32/X64 builds and
+`-fstack-protector` to GCC builds. This will cause stack cookie references to be inserted
+throughout the code. Every module should have a `StackCheckLib` instances linked to satisfy
+these references. So every module doesn't need to add `StackCheckLib` to the LibraryClasses
+section of the INF file, `StackCheckLib` instances should be linked as NULL in the platform
+DSC fies. The only exception to this is host-based unit tests as they will be compiled with
+the runtime libraries which already contain the stack cookie definitions and will collide
+with `StackCheckLib`.
+
+SEC and PEI_CORE modules should always use `StackCheckLibNull` and pre-memory modules
+should use `StackCheckLibStaticInit`. All other modules should use `StackCheckLibDynamicInit`.
+Below is an **example** of how to link the `StackCheckLib` instances in the platform DSC file
+but it may need customization based on the platform's requirements:
+
+```text
+[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
+[LibraryClasses.common.PEIM]
+ NULL|MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
+
+[LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.MM_STANDALONE, LibraryClasses.common.DXE_CORE, LibraryClasses.common.SMM_CORE, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SAL_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
+ NULL|MdePkg/Library/StackCheckLib/StackCheckLibDynamicInit.inf
+```
diff --git a/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c b/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c
new file mode 100644
index 0000000..4146012
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/StackCheckLibCommonGcc.c
@@ -0,0 +1,38 @@
+/** @file
+ Provides the required functionality for handling stack
+ cookie check failures in GCC.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/StackCheckFailureHookLib.h>
+
+/**
+ Triggers an interrupt using the vector specified by PcdStackCookieExceptionVector
+**/
+VOID
+TriggerStackCookieInterrupt (
+ VOID
+ );
+
+VOID *__stack_chk_guard = (VOID *)(UINTN)STACK_COOKIE_VALUE;
+
+/**
+ This function gets called when a gcc/clang generated stack cookie fails. This implementation calls into a platform
+ failure hook lib and then triggers the stack cookie interrupt.
+
+**/
+VOID
+__stack_chk_fail (
+ VOID
+ )
+{
+ DEBUG ((DEBUG_ERROR, "Stack cookie check failed at address 0x%llx!\n", RETURN_ADDRESS (0)));
+ StackCheckFailureHook (RETURN_ADDRESS (0));
+ TriggerStackCookieInterrupt ();
+}
diff --git a/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c b/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c
new file mode 100644
index 0000000..406b2d0
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/StackCheckLibCommonMsvc.c
@@ -0,0 +1,40 @@
+/** @file
+ Provides the required functionality for handling stack
+ cookie check failures for MSVC.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/StackCheckFailureHookLib.h>
+
+/**
+ Triggers an interrupt using the vector specified by PcdStackCookieExceptionVector
+**/
+VOID
+TriggerStackCookieInterrupt (
+ VOID
+ );
+
+VOID *__security_cookie = (VOID *)(UINTN)STACK_COOKIE_VALUE;
+
+/**
+ This function gets called when an MSVC generated stack cookie fails. This implementation calls into a platform
+ failure hook lib and then triggers the stack cookie interrupt.
+
+ @param[in] ActualCookieValue The value that was written onto the stack, corrupting the stack cookie.
+
+**/
+VOID
+StackCheckFailure (
+ VOID *ActualCookieValue
+ )
+{
+ DEBUG ((DEBUG_ERROR, "Stack cookie check failed at address 0x%llx!\n", RETURN_ADDRESS (0)));
+ StackCheckFailureHook (RETURN_ADDRESS (0));
+ TriggerStackCookieInterrupt ();
+}
diff --git a/MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf b/MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
new file mode 100644
index 0000000..ce8bc11
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
@@ -0,0 +1,58 @@
+## @file
+# Provides the required functionality for checking the stack cookie.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = StackCheckLibStaticInit
+ FILE_GUID = 2b24dc50-e33d-4c9f-8b62-e826f06e483f
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL
+
+[Sources]
+ StackCheckLibCommonMsvc.c | MSFT
+ StackCheckLibCommonGcc.c | GCC
+
+[Sources.IA32]
+ IA32/CheckCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/CheckCookieMsvc.nasm | MSFT
+
+[Sources.IA32, Sources.X64]
+ IA32/StackCookieInterrupt.nasm
+
+[Sources.ARM]
+ Arm/StackCookieInterrupt.S |GCC
+ Arm/StackCookieInterrupt.asm |MSFT
+
+[Sources.AARCH64]
+ AArch64/StackCookieInterrupt.S |GCC
+ AArch64/StackCookieInterrupt.asm |MSFT
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ StackCheckFailureHookLib
+ BaseLib
+ DebugLib
+
+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdStackCookieExceptionVector
+
+[BuildOptions]
+ # We cannot build the MSVC version with /GL (whole program optimization) because we run into linker error
+ # LNK1237, which is a failure to link against a symbol from a library compiled with /GL. The whole program
+ # optimization tries to do away with references to this symbol. The solution is to not compile the stack
+ # check libs with /GL
+ MSFT:*_*_*_CC_FLAGS = /GL-
+
+ # We cannot build the GCC version with LTO (link time optimization) because we run into linker errors where
+ # the stack cookie variable has been optimized away, as it looks to GCC like the variable is not used, because
+ # the compiler inserts the usage.
+ GCC:*_*_*_CC_FLAGS = -fno-lto
diff --git a/MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm b/MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm
new file mode 100644
index 0000000..ebc4f75
--- /dev/null
+++ b/MdePkg/Library/StackCheckLib/X64/CheckCookieMsvc.nasm
@@ -0,0 +1,43 @@
+;------------------------------------------------------------------------------
+; X64/CheckCookieMsvc.nasm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+extern ASM_PFX(StackCheckFailure)
+extern ASM_PFX(__security_cookie)
+extern ASM_PFX(CpuDeadLoop)
+
+; Called when a buffer check fails. This functionality is dependent on MSVC
+; C runtime libraries and so is unsupported in UEFI.
+global ASM_PFX(__report_rangecheckfailure)
+ASM_PFX(__report_rangecheckfailure):
+ jmp ASM_PFX(CpuDeadLoop)
+ ret
+
+; The GS handler is for checking the stack cookie during SEH or
+; EH exceptions and is unsupported in UEFI.
+global ASM_PFX(__GSHandlerCheck)
+ASM_PFX(__GSHandlerCheck):
+ jmp ASM_PFX(CpuDeadLoop)
+ ret
+
+;------------------------------------------------------------------------------
+; Checks the stack cookie value against __security_cookie and calls the
+; stack cookie failure handler if there is a mismatch.
+;
+; VOID
+; EFIAPI
+; __security_check_cookie (
+; IN UINTN CheckValue
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(__security_check_cookie)
+ASM_PFX(__security_check_cookie):
+ cmp rcx, [ASM_PFX(__security_cookie)]
+ jne ASM_PFX(StackCheckFailure)
+ ret
diff --git a/MdePkg/Library/StackCheckLibNull/IA32/StackCheckFunctionsMsvc.nasm b/MdePkg/Library/StackCheckLibNull/IA32/StackCheckFunctionsMsvc.nasm
new file mode 100644
index 0000000..510d500
--- /dev/null
+++ b/MdePkg/Library/StackCheckLibNull/IA32/StackCheckFunctionsMsvc.nasm
@@ -0,0 +1,21 @@
+;------------------------------------------------------------------------------
+; IA32/StackCheckFunctionsMsvc.nasm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+global ASM_PFX(__report_rangecheckfailure)
+ASM_PFX(__report_rangecheckfailure):
+ ret
+
+global ASM_PFX(__GSHandlerCheck)
+ASM_PFX(__GSHandlerCheck):
+ ret
+
+global @__security_check_cookie@4
+@__security_check_cookie@4:
+ ret
diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibHostApplicationMsvc.c b/MdePkg/Library/StackCheckLibNull/StackCheckLibHostApplicationMsvc.c
new file mode 100644
index 0000000..6af9891
--- /dev/null
+++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibHostApplicationMsvc.c
@@ -0,0 +1,13 @@
+/** @file
+ This file is empty to allow host applications
+ to use the MSVC C runtime lib that provides
+ stack cookie definitions without breaking the
+ build.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+
+extern VOID *__security_cookie;
diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf b/MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
new file mode 100644
index 0000000..bb42833
--- /dev/null
+++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
@@ -0,0 +1,41 @@
+## @file
+# Null library instance for StackCheckLib which can be included
+# when a build needs to include stack check functions but does
+# not want to generate stack check failures.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = StackCheckLibNull
+ FILE_GUID = f6ef2763-ca3b-4c6f-a931-2a48de3ce352
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = StackCheckLib
+
+[Sources]
+ StackCheckLibNullGcc.c | GCC
+ StackCheckLibNullMsvc.c | MSFT
+
+[Sources.IA32]
+ IA32/StackCheckFunctionsMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/StackCheckFunctionsMsvc.nasm | MSFT
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[BuildOptions]
+ # We cannot build the MSVC version with /GL (whole program optimization) because we run into linker error
+ # LNK1237, which is a failure to link against a symbol from a library compiled with /GL. The whole program
+ # optimization tries to do away with references to this symbol. The solution is to not compile the stack
+ # check libs with /GL
+ MSFT:*_*_*_CC_FLAGS = /GL-
+
+ # We cannot build the GCC version with LTO (link time optimization) because we run into linker errors where
+ # the stack cookie variable has been optimized away, as it looks to GCC like the variable is not used, because
+ # the compiler inserts the usage.
+ GCC:*_*_*_CC_FLAGS = -fno-lto
diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c
new file mode 100644
index 0000000..cc30632
--- /dev/null
+++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullGcc.c
@@ -0,0 +1,23 @@
+/** @file
+ Defines the stack cookie variable for GCC and Clang compilers.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+
+VOID *__stack_chk_guard = (VOID *)(UINTN)0x0;
+
+/**
+ This function gets called when a gcc/clang generated stack cookie fails. This implementation does nothing when
+ a stack cookie failure occurs.
+
+**/
+VOID
+EFIAPI
+__stack_chk_fail (
+ VOID
+ )
+{
+}
diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf
new file mode 100644
index 0000000..3e89826
--- /dev/null
+++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf
@@ -0,0 +1,34 @@
+## @file
+# Null library instance for StackCheckLib which can be included
+# when a build needs to include stack check functions but does
+# not want to generate stack check failures. This instance is used
+# for HOST_APPLICATIONS specifically, as MSVC host applications link
+# to the C runtime lib that contains the stack cookie definitions, so
+# must link to a completely null version of this lib, whereas GCC host
+# host applications do not link to a C runtime lib that contains the stack
+# cookie definitions, so we must link against our version.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = StackCheckLibNullHostApplication
+ FILE_GUID = 7EBE7BD1-0D92-4609-89AA-6EA3815CB844
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = StackCheckLib|HOST_APPLICATION
+
+[Sources]
+ StackCheckLibHostApplicationMsvc.c | MSFT
+ StackCheckLibNullGcc.c | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[BuildOptions]
+ # We cannot build the GCC version with LTO (link time optimization) because we run into linker errors where
+ # the stack cookie variable has been optimized away, as it looks to GCC like the variable is not used, because
+ # the compiler inserts the usage. We do not worry about the MSVC version here as it is a no-op.
+ GCC:*_*_*_CC_FLAGS = -fno-lto
diff --git a/MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c
new file mode 100644
index 0000000..ba9a4e6
--- /dev/null
+++ b/MdePkg/Library/StackCheckLibNull/StackCheckLibNullMsvc.c
@@ -0,0 +1,10 @@
+/** @file
+ Defines the stack cookie variable for GCC, Clang and MSVC compilers.
+
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+
+VOID *__security_cookie = (VOID *)(UINTN)0x0;
diff --git a/MdePkg/Library/StackCheckLibNull/X64/StackCheckFunctionsMsvc.nasm b/MdePkg/Library/StackCheckLibNull/X64/StackCheckFunctionsMsvc.nasm
new file mode 100644
index 0000000..f4639a0
--- /dev/null
+++ b/MdePkg/Library/StackCheckLibNull/X64/StackCheckFunctionsMsvc.nasm
@@ -0,0 +1,21 @@
+;------------------------------------------------------------------------------
+; X64/StackCheckFunctionsMsvc.nasm
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+ DEFAULT REL
+ SECTION .text
+
+global ASM_PFX(__report_rangecheckfailure)
+ASM_PFX(__report_rangecheckfailure):
+ ret
+
+global ASM_PFX(__GSHandlerCheck)
+ASM_PFX(__GSHandlerCheck):
+ ret
+
+global ASM_PFX(__security_check_cookie)
+ASM_PFX(__security_check_cookie):
+ ret
diff --git a/MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf b/MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
index 40f14ae..5225d64 100644
--- a/MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
+++ b/MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
@@ -16,7 +16,7 @@
FILE_GUID = eaa4684f-fb4e-41f3-9967-307d5b409182
MODULE_TYPE = MM_STANDALONE
VERSION_STRING = 1.0
- LIBRARY_CLASS = MmServicesTableLib|MM_STANDALONE
+ LIBRARY_CLASS = MmServicesTableLib|MM_STANDALONE MM_CORE_STANDALONE
PI_SPECIFICATION_VERSION = 0x00010032
CONSTRUCTOR = StandaloneMmServicesTableLibConstructor
diff --git a/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLib.c b/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLib.c
index c25199b..3314d3f 100644
--- a/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLib.c
+++ b/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLib.c
@@ -233,8 +233,8 @@ DebugBPrint (
Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
- PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
- DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
+ PcdDebugPropertyMask is set then CpuBreakpoint() is called. Otherwise, if
+ DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugPropertyMask is set then
CpuDeadLoop() is called. If neither of these bits are set, then this function
returns immediately after the message is printed to the debug output device.
DebugAssert() must actively prevent recursion. If DebugAssert() is called while
@@ -327,10 +327,10 @@ DebugClearMemory (
Returns TRUE if ASSERT() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
@@ -346,10 +346,10 @@ DebugAssertEnabled (
Returns TRUE if DEBUG() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
@@ -365,10 +365,10 @@ DebugPrintEnabled (
Returns TRUE if DEBUG_CODE() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
@@ -384,10 +384,10 @@ DebugCodeEnabled (
Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
diff --git a/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c b/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c
index 298d17c..0215c27 100644
--- a/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c
+++ b/MdePkg/Library/UefiDebugLibDebugPortProtocol/DebugLibConstructor.c
@@ -13,7 +13,7 @@
#include <Library/BaseMemoryLib.h>
//
-// BOOLEAN value to indicate if it is at the post ExitBootServices pahse
+// BOOLEAN value to indicate if it is at the post ExitBootServices phase
//
BOOLEAN mPostEBS = FALSE;
@@ -34,9 +34,10 @@ EFI_BOOT_SERVICES *mDebugBS;
@param Context Pointer to the notification function's context.
**/
+static
VOID
EFIAPI
-ExitBootServicesCallback (
+UefiDebugLibDebugPortProtocolExitBootServicesCallback (
EFI_EVENT Event,
VOID *Context
)
@@ -67,7 +68,7 @@ DxeDebugLibConstructor (
mDebugBS->CreateEvent (
EVT_SIGNAL_EXIT_BOOT_SERVICES,
TPL_NOTIFY,
- ExitBootServicesCallback,
+ UefiDebugLibDebugPortProtocolExitBootServicesCallback,
NULL,
&mExitBootServicesEvent
);
diff --git a/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c b/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c
index 5b28cd1..dc9c525 100644
--- a/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c
+++ b/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c
@@ -177,8 +177,8 @@ DebugBPrint (
Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
- PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
- DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
+ PcdDebugPropertyMask is set then CpuBreakpoint() is called. Otherwise, if
+ DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugPropertyMask is set then
CpuDeadLoop() is called. If neither of these bits are set, then this function
returns immediately after the message is printed to the debug output device.
DebugAssert() must actively prevent recursion. If DebugAssert() is called while
@@ -273,10 +273,10 @@ DebugClearMemory (
Returns TRUE if ASSERT() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
@@ -292,10 +292,10 @@ DebugAssertEnabled (
Returns TRUE if DEBUG() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
@@ -311,10 +311,10 @@ DebugPrintEnabled (
Returns TRUE if DEBUG_CODE() macros are enabled.
This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
@@ -330,10 +330,10 @@ DebugCodeEnabled (
Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
- PcdDebugProperyMask is set. Otherwise FALSE is returned.
+ PcdDebugPropertyMask is set. Otherwise FALSE is returned.
- @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
- @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
+ @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is set.
+ @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is clear.
**/
BOOLEAN
diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
index 1aaa968..86ecb66 100644
--- a/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
@@ -922,8 +922,8 @@ DevPathFromTextAcpiExp (
AcpiEx->HID = EisaIdFromText (HIDStr);
//
- // According to UEFI spec, the CID parametr is optional and has a default value of 0.
- // So when the CID parametr is not specified or specified as 0 in the text device node.
+ // According to UEFI spec, the CID parameter is optional and has a default value of 0.
+ // So when the CID parameter is not specified or specified as 0 in the text device node.
// Set the CID to 0 in the ACPI extension device path structure.
//
if ((*CIDStr == L'\0') || (*CIDStr == L'0')) {
diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
index 468baa5..afbd590 100644
--- a/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
@@ -1003,8 +1003,9 @@ DevPathToTextUsbWWID (
//
// In case no NULL terminator in SerialNumber, create a new one with NULL terminator
//
- NewStr = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), SerialNumberStr);
+ NewStr = AllocatePool ((Length + 1) * sizeof (CHAR16));
ASSERT (NewStr != NULL);
+ CopyMem (NewStr, SerialNumberStr, Length * sizeof (CHAR16));
NewStr[Length] = 0;
SerialNumberStr = NewStr;
}
diff --git a/MdePkg/Library/UefiMemoryLib/SetMemNWrapper.c b/MdePkg/Library/UefiMemoryLib/SetMemNWrapper.c
new file mode 100644
index 0000000..8a7cfca
--- /dev/null
+++ b/MdePkg/Library/UefiMemoryLib/SetMemNWrapper.c
@@ -0,0 +1,54 @@
+/** @file
+ SetMemN() implementation.
+
+ The following BaseMemoryLib instances contain the same copy of this file:
+
+ BaseMemoryLib
+ BaseMemoryLibMmx
+ BaseMemoryLibSse2
+ BaseMemoryLibRepStr
+ BaseMemoryLibOptDxe
+ BaseMemoryLibOptPei
+ PeiMemoryLib
+ UefiMemoryLib
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemLibInternals.h"
+
+/**
+ Fills a target buffer with a value that is size UINTN, and returns the target buffer.
+
+ This function fills Length bytes of Buffer with the UINTN sized value specified by
+ Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
+ bytes of Buffer.
+
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+ If Buffer is not aligned on a UINTN boundary, then ASSERT().
+ If Length is not aligned on a UINTN boundary, then ASSERT().
+
+ @param Buffer The pointer to the target buffer to fill.
+ @param Length The number of bytes in Buffer to fill.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @return Buffer.
+
+**/
+VOID *
+EFIAPI
+SetMemN (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINTN Value
+ )
+{
+ if (sizeof (UINTN) == sizeof (UINT64)) {
+ return SetMem64 (Buffer, Length, (UINT64)Value);
+ } else {
+ return SetMem32 (Buffer, Length, (UINT32)Value);
+ }
+}
diff --git a/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c b/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c
index 1d54a8a..df1247d 100644
--- a/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c
+++ b/MdePkg/Library/UefiMemoryLib/SetMemWrapper.c
@@ -1,5 +1,5 @@
/** @file
- SetMem() and SetMemN() implementation.
+ SetMem() implementation.
The following BaseMemoryLib instances contain the same copy of this file:
@@ -49,37 +49,3 @@ SetMem (
return InternalMemSetMem (Buffer, Length, Value);
}
-
-/**
- Fills a target buffer with a value that is size UINTN, and returns the target buffer.
-
- This function fills Length bytes of Buffer with the UINTN sized value specified by
- Value, and returns Buffer. Value is repeated every sizeof(UINTN) bytes for Length
- bytes of Buffer.
-
- If Length > 0 and Buffer is NULL, then ASSERT().
- If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
- If Buffer is not aligned on a UINTN boundary, then ASSERT().
- If Length is not aligned on a UINTN boundary, then ASSERT().
-
- @param Buffer The pointer to the target buffer to fill.
- @param Length The number of bytes in Buffer to fill.
- @param Value The value with which to fill Length bytes of Buffer.
-
- @return Buffer.
-
-**/
-VOID *
-EFIAPI
-SetMemN (
- OUT VOID *Buffer,
- IN UINTN Length,
- IN UINTN Value
- )
-{
- if (sizeof (UINTN) == sizeof (UINT64)) {
- return SetMem64 (Buffer, Length, (UINT64)Value);
- } else {
- return SetMem32 (Buffer, Length, (UINT32)Value);
- }
-}
diff --git a/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf b/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf
index 2556225..35dff7a 100644
--- a/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf
+++ b/MdePkg/Library/UefiMemoryLib/UefiMemoryLib.inf
@@ -32,6 +32,7 @@
ScanMem8Wrapper.c
ZeroMemWrapper.c
CompareMemWrapper.c
+ SetMemNWrapper.c
SetMem64Wrapper.c
SetMem32Wrapper.c
SetMem16Wrapper.c
@@ -47,7 +48,6 @@
[Packages]
MdePkg/MdePkg.dec
-
[LibraryClasses]
BaseLib
UefiBootServicesTableLib
diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc
index ddd2711..4e3858e 100644
--- a/MdePkg/MdeLibs.dsc.inc
+++ b/MdePkg/MdeLibs.dsc.inc
@@ -12,6 +12,7 @@
##
[LibraryClasses]
+ OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
ArmTrngLib|MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf
RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
@@ -19,3 +20,19 @@
SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf
+
+[LibraryClasses.ARM, LibraryClasses.AARCH64]
+ #
+ # It is not possible to prevent the ARM/AARCH64 compilers from inserting generic intrinsic functions.
+ # This library provides the intrinsic functions generated by these compilers.
+ #
+ # Linking this here as a null library will cause all ARM/AARCH64 files to link against it and have
+ # definitions for the intrinsic functions.
+ #
+ NULL|MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+# Stack Cookies cannot be generically applied to SEC modules because they may not define _ModuleEntryPoint and when we
+# link a library in, we have to be able to define the entry point. SEC modules that do define _ModuleEntryPoint can
+# apply a library class override to get StackCheckLibNull.inf
+[LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM, LibraryClasses.common.DXE_CORE, LibraryClasses.common.SMM_CORE, LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.MM_STANDALONE, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
diff --git a/MdePkg/MdePkg.ci.yaml b/MdePkg/MdePkg.ci.yaml
index f2d81af..cebccba 100644
--- a/MdePkg/MdePkg.ci.yaml
+++ b/MdePkg/MdePkg.ci.yaml
@@ -61,7 +61,9 @@
"7007", "_EFI_SPI_NOR_FLASH_PROTOCOL",
"7007", "_EFI_SPI_HC_PROTOCOL",
"8002", "aligned (",
- "4002", "_ReturnAddress"
+ "4002", "_ReturnAddress",
+ "8005", "__security_cookie",
+ "8006", "__stack_chk_fail"
],
## Both file path and directory path are accepted.
"IgnoreFiles": [
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 94170ff..624f626 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -303,6 +303,10 @@
#
TraceHubDebugSysTLib|Include/Library/TraceHubDebugSysTLib.h
+ ## @libraryclass Provides a hook called when a stack cookie check fails.
+ #
+ StackCheckFailureHookLib|Include/Library/StackCheckFailureHookLib.h
+
[LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64]
## @libraryclass Provides services to generate random number.
#
@@ -751,6 +755,16 @@
## Include/Guid/DeviceAuthentication.h
gEfiDeviceSignatureDatabaseGuid = { 0xb9c2b4f4, 0xbf5f, 0x462d, {0x8a, 0xdf, 0xc5, 0xc7, 0xa, 0xc3, 0x5d, 0xad }}
+ ## Include/Guid/ConformanceProfiles.h
+ gEfiConfProfilesTableGuid = { 0x36122546, 0xf7e7, 0x4c8f, { 0xbd, 0x9b, 0xeb, 0x85, 0x25, 0xb5, 0x0c, 0x0b }}
+ gEfiConfProfilesUefiSpecGuid = { 0x523c91af, 0xa195, 0x4382, { 0x81, 0x8d, 0x29, 0x5f, 0xe4, 0x00, 0x64, 0x65 }}
+
+ # GUIDs defined in EBBR
+ #
+ ## Include/Guid/ConformanceProfiles.h
+ gEfiConfProfilesEbbrSpec21Guid = { 0xcce33c35, 0x74ac, 0x4087, { 0xbc, 0xe7, 0x8b, 0x29, 0xb0, 0x2e, 0xeb, 0x27 }}
+ gEfiConfProfilesEbbrSpec22Guid = { 0x9073eed4, 0xe50d, 0x11ee, { 0xb8, 0xb0, 0x8b, 0x68, 0xda, 0x62, 0xfc, 0x80 }}
+
#
# GUID defined in PI1.0
#
@@ -1375,6 +1389,10 @@
## Include/Protocol/MmCommunication.h
gEfiMmCommunicationProtocolGuid = { 0xc68ed8e2, 0x9dc6, 0x4cbd, { 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 }}
+ ## This protocol is a MM protocol published by a standalone MM Foundation code if MM Foundation is loaded in PEI phase.
+ ## This protocol should be installed immediately after DXE IPL installs EFI_PEI_END_OF_PEI_PHASE_PPI
+ gEfiMmEndOfPeiProtocol = { 0xf33e1bf3, 0x980b, 0x4bfb, { 0xa2, 0x9a, 0xb2, 0x9c, 0x86, 0x45, 0x37, 0x32 }}
+
#
# Protocols defined in PI 1.6.
#
@@ -2245,6 +2263,15 @@
# @Prompt Speculation Barrier Type.
gEfiMdePkgTokenSpaceGuid.PcdSpeculationBarrierType|0x01|UINT8|0x30001018
+ ## This PCD specifies the interrupt vector for stack cookie check failures
+ gEfiMdePkgTokenSpaceGuid.PcdStackCookieExceptionVector|0x42|UINT8|0x30001019
+
+ ## Enforces the use of Secure UEFI spec defined RNG algorithms.
+ # TRUE - Enforce the use of Secure UEFI spec defined RNG algorithms.
+ # FALSE - Do not enforce and depend on the default implementation of RNG algorithm from the provider.
+ # @Prompt Enforce the use of Secure UEFI spec defined RNG algorithms.
+ gEfiMdePkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms|TRUE|BOOLEAN|0x1000000D
+
[PcdsFixedAtBuild,PcdsPatchableInModule]
## Indicates the maximum length of unicode string used in the following
# BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), StrnCpy()<BR><BR>
@@ -2420,6 +2447,8 @@
# previous stage has feature enabled and user wants to disable it.
# BIT 2 = Page-Based Memory Types (Pbmt). This bit is relevant only if
# previous stage has feature enabled and user wants to disable it.
+ # BIT 3 = Zkr extension.This bit is relevant only if
+ # previous stage has feature enabled and user wants to disable it.
#
gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride|0xFFFFFFFFFFFFFFFF|UINT64|0x69
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index 109224c..0f00172 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -139,6 +139,10 @@
MdePkg/Library/JedecJep106Lib/JedecJep106Lib.inf
MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
+ MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf
+ MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+ MdePkg/Library/StackCheckLib/StackCheckLibStaticInit.inf
+
[Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
#
# Add UEFI Target Based Unit Tests
@@ -193,7 +197,7 @@
[Components.ARM, Components.AARCH64]
MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
- MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+ MdePkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
[Components.RISCV64]
MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
diff --git a/MdePkg/Test/MdePkgHostTest.dsc b/MdePkg/Test/MdePkgHostTest.dsc
index 6a85d02..1351d19 100644
--- a/MdePkg/Test/MdePkgHostTest.dsc
+++ b/MdePkg/Test/MdePkgHostTest.dsc
@@ -47,3 +47,5 @@
MdePkg/Test/Mock/Library/GoogleTest/MockPeiServicesLib/MockPeiServicesLib.inf
MdePkg/Test/Mock/Library/GoogleTest/MockHobLib/MockHobLib.inf
MdePkg/Test/Mock/Library/GoogleTest/MockFdtLib/MockFdtLib.inf
+
+ MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf
diff --git a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockFdtLib.h b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockFdtLib.h
index 5b21b23..9e9ddc2 100644
--- a/MdePkg/Test/Mock/Include/GoogleTest/Library/MockFdtLib.h
+++ b/MdePkg/Test/Mock/Include/GoogleTest/Library/MockFdtLib.h
@@ -89,7 +89,7 @@ struct MockFdtLib {
);
MOCK_FUNCTION_DECLARATION (
INT32,
- FdtNodeOffsetByPropValue,
+ FdtNodeOffsetByPropertyValue,
(IN CONST VOID *Fdt,
IN INT32 StartOffset,
IN CONST CHAR8 *PropertyName,
@@ -139,7 +139,7 @@ struct MockFdtLib {
);
MOCK_FUNCTION_DECLARATION (
INT32,
- FdtSetProp,
+ FdtSetProperty,
(IN VOID *Fdt,
IN INT32 NodeOffset,
IN CONST CHAR8 *Name,
diff --git a/MdePkg/Test/Mock/Library/GoogleTest/MockFdtLib/MockFdtLib.cpp b/MdePkg/Test/Mock/Library/GoogleTest/MockFdtLib/MockFdtLib.cpp
index a955780..8be9670 100644
--- a/MdePkg/Test/Mock/Library/GoogleTest/MockFdtLib/MockFdtLib.cpp
+++ b/MdePkg/Test/Mock/Library/GoogleTest/MockFdtLib/MockFdtLib.cpp
@@ -22,13 +22,13 @@ MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtNextNode, 3, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtFirstSubnode, 2, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtNextSubnode, 2, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtSubnodeOffsetNameLen, 4, EFIAPI);
-MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtNodeOffsetByPropValue, 5, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtNodeOffsetByPropertyValue, 5, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtGetProperty, 4, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtFirstPropertyOffset, 2, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtNextPropertyOffset, 2, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtGetPropertyByOffset, 3, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtGetString, 3, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtAddSubnode, 3, EFIAPI);
-MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtSetProp, 5, EFIAPI);
+MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtSetProperty, 5, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtGetName, 3, EFIAPI);
MOCK_FUNCTION_DEFINITION (MockFdtLib, FdtNodeDepth, 2, EFIAPI);
diff --git a/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c b/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c
index 9f2d2bd..80d2c9c 100644
--- a/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c
+++ b/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c
@@ -390,7 +390,7 @@ SafeStringContraintCheckTest (
}
/**
- Initialze the unit test framework, suite, and unit tests for the
+ Initialize the unit test framework, suite, and unit tests for the
Base64 conversion APIs of BaseLib and run the unit tests.
@retval EFI_SUCCESS All test cases were dispatched.
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
index f38e3ee..f72bc93 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
@@ -1001,7 +1001,7 @@ Dhcp6AppendETOption (
return EFI_INVALID_PARAMETER;
}
- if ((Elapsed == NULL)) {
+ if (Elapsed == NULL) {
return EFI_INVALID_PARAMETER;
}
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c
index 40f64fc..858e7c2 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootClient.c
+++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c
@@ -923,6 +923,9 @@ HttpBootGetBootFileCallback (
BufferSize has been updated with the size needed to complete
the request.
@retval EFI_ACCESS_DENIED The server needs to authenticate the client.
+ @retval EFI_NOT_READY Data transfer has timed-out, call HttpBootGetBootFile again to resume
+ the download operation using HTTP Range headers.
+ @retval EFI_UNSUPPORTED Some HTTP response header is not supported.
@retval Others Unexpected error happened.
**/
@@ -955,6 +958,10 @@ HttpBootGetBootFile (
CHAR8 BaseAuthValue[80];
EFI_HTTP_HEADER *HttpHeader;
CHAR8 *Data;
+ UINTN HeadersCount;
+ BOOLEAN ResumingOperation;
+ CHAR8 *ContentRangeResponseValue;
+ CHAR8 RangeValue[64];
ASSERT (Private != NULL);
ASSERT (Private->HttpCreated);
@@ -985,6 +992,16 @@ HttpBootGetBootFile (
}
}
+ // Check if this is a previous download that has failed and need to be resumed
+ if ((!HeaderOnly) &&
+ (Private->PartialTransferredSize > 0) &&
+ (Private->BootFileSize == *BufferSize))
+ {
+ ResumingOperation = TRUE;
+ } else {
+ ResumingOperation = FALSE;
+ }
+
//
// Not found in cache, try to download it through HTTP.
//
@@ -1014,8 +1031,23 @@ HttpBootGetBootFile (
// Accept
// User-Agent
// [Authorization]
+ // [Range]
+ // [If-Match]|[If-Unmodified-Since]
//
- HttpIoHeader = HttpIoCreateHeader ((Private->AuthData != NULL) ? 4 : 3);
+ HeadersCount = 3;
+ if (Private->AuthData != NULL) {
+ HeadersCount++;
+ }
+
+ if (ResumingOperation) {
+ HeadersCount++;
+ if (Private->LastModifiedOrEtag) {
+ HeadersCount++;
+ }
+ }
+
+ HttpIoHeader = HttpIoCreateHeader (HeadersCount);
+
if (HttpIoHeader == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ERROR_2;
@@ -1098,6 +1130,62 @@ HttpBootGetBootFile (
}
//
+ // Add HTTP header field 5 (optional): Range
+ //
+ if (ResumingOperation) {
+ // Resuming a failed download. Prepare the HTTP Range Header
+ Status = AsciiSPrint (
+ RangeValue,
+ sizeof (RangeValue),
+ "bytes=%lu-%lu",
+ Private->PartialTransferredSize,
+ Private->BootFileSize - 1
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR_3;
+ }
+
+ Status = HttpIoSetHeader (HttpIoHeader, "Range", RangeValue);
+ if (EFI_ERROR (Status)) {
+ goto ERROR_3;
+ }
+
+ DEBUG (
+ (DEBUG_WARN | DEBUG_INFO,
+ "HttpBootGetBootFile: Resuming failed download. Range: %a\n",
+ RangeValue)
+ );
+
+ //
+ // Add HTTP header field 6 (optional): If-Match or If-Unmodified-Since
+ //
+ if (Private->LastModifiedOrEtag) {
+ if (Private->LastModifiedOrEtag[0] == '"') {
+ // An ETag value starts with "
+ DEBUG (
+ (DEBUG_WARN | DEBUG_INFO,
+ "HttpBootGetBootFile: If-Match=%a\n",
+ Private->LastModifiedOrEtag)
+ );
+ // Add If-Match header with the ETag value got from the first request.
+ Status = HttpIoSetHeader (HttpIoHeader, HTTP_HEADER_IF_MATCH, Private->LastModifiedOrEtag);
+ } else {
+ DEBUG (
+ (DEBUG_WARN | DEBUG_INFO,
+ "HttpBootGetBootFile: If-Unmodified-Since=%a\n",
+ Private->LastModifiedOrEtag)
+ );
+ // Add If-Unmodified-Since header with the timestamp value (Last-Modified) got from the first request.
+ Status = HttpIoSetHeader (HttpIoHeader, HTTP_HEADER_IF_UNMODIFIED_SINCE, Private->LastModifiedOrEtag);
+ }
+
+ if (EFI_ERROR (Status)) {
+ goto ERROR_3;
+ }
+ }
+ }
+
+ //
// 2.2 Build the rest of HTTP request info.
//
RequestData = AllocatePool (sizeof (EFI_HTTP_REQUEST_DATA));
@@ -1245,6 +1333,62 @@ HttpBootGetBootFile (
Cache->ImageType = *ImageType;
}
+ // Cache ETag or Last-Modified response header value to
+ // be used when resuming an interrupted download.
+ HttpHeader = HttpFindHeader (
+ ResponseData->HeaderCount,
+ ResponseData->Headers,
+ HTTP_HEADER_ETAG
+ );
+ if (HttpHeader == NULL) {
+ HttpHeader = HttpFindHeader (
+ ResponseData->HeaderCount,
+ ResponseData->Headers,
+ HTTP_HEADER_LAST_MODIFIED
+ );
+ }
+
+ if (HttpHeader) {
+ if (Private->LastModifiedOrEtag) {
+ FreePool (Private->LastModifiedOrEtag);
+ }
+
+ Private->LastModifiedOrEtag = AllocateCopyPool (AsciiStrSize (HttpHeader->FieldValue), HttpHeader->FieldValue);
+ }
+
+ //
+ // 3.2.2 Validate the range response. If operation is being resumed,
+ // server must respond with Content-Range.
+ //
+ if (ResumingOperation) {
+ HttpHeader = HttpFindHeader (
+ ResponseData->HeaderCount,
+ ResponseData->Headers,
+ HTTP_HEADER_CONTENT_RANGE
+ );
+ if ((HttpHeader == NULL) ||
+ (AsciiStrnCmp (HttpHeader->FieldValue, "bytes", 5) != 0))
+ {
+ Status = EFI_UNSUPPORTED;
+ goto ERROR_5;
+ }
+
+ // Gets the total size of ranged data (Content-Range: <unit> <range-start>-<range-end>/<size>)
+ // and check if it remains the same
+ ContentRangeResponseValue = AsciiStrStr (HttpHeader->FieldValue, "/");
+ if (ContentRangeResponseValue == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ERROR_5;
+ }
+
+ ContentRangeResponseValue++;
+ ContentLength = AsciiStrDecimalToUintn (ContentRangeResponseValue);
+ if (ContentLength != *BufferSize) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ERROR_5;
+ }
+ }
+
//
// 3.3 Init a message-body parser from the header information.
//
@@ -1295,10 +1439,15 @@ HttpBootGetBootFile (
// In identity transfer-coding there is no need to parse the message body,
// just download the message body to the user provided buffer directly.
//
+ if (ResumingOperation && ((ContentLength + Private->PartialTransferredSize) > *BufferSize)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ERROR_6;
+ }
+
ReceivedSize = 0;
while (ReceivedSize < ContentLength) {
- ResponseBody.Body = (CHAR8 *)Buffer + ReceivedSize;
- ResponseBody.BodyLength = *BufferSize - ReceivedSize;
+ ResponseBody.Body = (CHAR8 *)Buffer + (ReceivedSize + Private->PartialTransferredSize);
+ ResponseBody.BodyLength = *BufferSize - (ReceivedSize + Private->PartialTransferredSize);
Status = HttpIoRecvResponse (
&Private->HttpIo,
FALSE,
@@ -1309,6 +1458,20 @@ HttpBootGetBootFile (
Status = ResponseBody.Status;
}
+ if ((Status == EFI_TIMEOUT) || (Status == EFI_DEVICE_ERROR)) {
+ // For EFI_TIMEOUT and EFI_DEVICE_ERROR errors, we may resume the operation.
+ // We will not check if server sent Accept-Ranges header, because some back-ends
+ // do not report this header, even when supporting it. Know example: CloudFlare CDN Cache.
+ Private->PartialTransferredSize = ReceivedSize;
+ DEBUG (
+ (
+ DEBUG_WARN | DEBUG_INFO,
+ "HttpBootGetBootFile: Transfer error. Bytes transferred so far: %lu.\n",
+ ReceivedSize
+ )
+ );
+ }
+
goto ERROR_6;
}
@@ -1326,6 +1489,9 @@ HttpBootGetBootFile (
}
}
}
+
+ // download completed, there is no more partial data
+ Private->PartialTransferredSize = 0;
} else {
//
// In "chunked" transfer-coding mode, so we need to parse the received
@@ -1385,9 +1551,13 @@ HttpBootGetBootFile (
//
// 3.5 Message-body receive & parse is completed, we should be able to get the file size now.
//
- Status = HttpGetEntityLength (Parser, &ContentLength);
- if (EFI_ERROR (Status)) {
- goto ERROR_6;
+ if (!ResumingOperation) {
+ Status = HttpGetEntityLength (Parser, &ContentLength);
+ if (EFI_ERROR (Status)) {
+ goto ERROR_6;
+ }
+ } else {
+ ContentLength = Private->BootFileSize;
}
if (*BufferSize < ContentLength) {
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.h b/NetworkPkg/HttpBootDxe/HttpBootClient.h
index 86a28bc..406eefb 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootClient.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootClient.h
@@ -108,6 +108,7 @@ HttpBootCreateHttpIo (
BufferSize has been updated with the size needed to complete
the request.
@retval EFI_ACCESS_DENIED The server needs to authenticate the client.
+ @retval EFI_UNSUPPORTED Some HTTP response header is not supported.
@retval Others Unexpected error happened.
**/
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.h b/NetworkPkg/HttpBootDxe/HttpBootDxe.h
index 5ff8ad4..193235d 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootDxe.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.h
@@ -214,6 +214,8 @@ struct _HTTP_BOOT_PRIVATE_DATA {
CHAR8 *BootFileUri;
VOID *BootFileUriParser;
UINTN BootFileSize;
+ UINTN PartialTransferredSize;
+ CHAR8 *LastModifiedOrEtag;
BOOLEAN NoGateway;
HTTP_BOOT_IMAGE_TYPE ImageType;
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.inf b/NetworkPkg/HttpBootDxe/HttpBootDxe.inf
index cffa642..3f87e58 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootDxe.inf
+++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.inf
@@ -95,8 +95,10 @@
gEfiAdapterInfoUndiIpv6SupportGuid ## SOMETIMES_CONSUMES ## GUID
[Pcd]
- gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections ## CONSUMES
- gEfiNetworkPkgTokenSpaceGuid.PcdHttpIoTimeout ## CONSUMES
+ gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections ## CONSUMES
+ gEfiNetworkPkgTokenSpaceGuid.PcdHttpIoTimeout ## CONSUMES
+ gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpResumeRetries ## CONSUMES
+ gEfiNetworkPkgTokenSpaceGuid.PcdHttpDelayBetweenResumeRetries ## CONSUMES
[UserExtensions.TianoCore."ExtraFiles"]
HttpBootDxeExtra.uni
diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c
index b4c6192..6f10bcf 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c
+++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c
@@ -77,11 +77,19 @@ HttpBootUninstallCallback (
IN HTTP_BOOT_PRIVATE_DATA *Private
)
{
+ EFI_HANDLE ControllerHandle;
+
if (Private->HttpBootCallback == &Private->LoadFileCallback) {
+ if (!Private->UsingIpv6) {
+ ControllerHandle = Private->Ip4Nic->Controller;
+ } else {
+ ControllerHandle = Private->Ip6Nic->Controller;
+ }
+
gBS->UninstallProtocolInterface (
- Private->Controller,
+ ControllerHandle,
&gEfiHttpBootCallbackProtocolGuid,
- &Private->HttpBootCallback
+ Private->HttpBootCallback
);
Private->HttpBootCallback = NULL;
}
@@ -275,6 +283,147 @@ HttpBootDhcp (
}
/**
+ Issue calls to HttpBootGetBootFile() based on current Boot File State
+ @param[in] Private The pointer to the driver's private data.
+ @param[in, out] BufferSize On input the size of Buffer in bytes. On output with a return
+ code of EFI_SUCCESS, the amount of data transferred to
+ Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
+ the size of Buffer required to retrieve the requested file.
+ @param[in] Buffer The memory buffer to transfer the file to. If Buffer is NULL,
+ then the size of the requested file is returned in
+ BufferSize.
+ @param[out] ImageType The image type of the downloaded file.
+ @retval EFI_SUCCESS The file was loaded.
+ @retval EFI_INVALID_PARAMETER BufferSize is NULL or Buffer Size is not NULL but Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.
+ BufferSize has been updated with the size needed to complete
+ the request.
+ @retval EFI_ACCESS_DENIED Server authentication failed.
+ @retval Others Unexpected error happened.
+**/
+EFI_STATUS
+HttpBootGetBootFileCaller (
+ IN HTTP_BOOT_PRIVATE_DATA *Private,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer OPTIONAL,
+ OUT HTTP_BOOT_IMAGE_TYPE *ImageType
+ )
+{
+ HTTP_GET_BOOT_FILE_STATE State;
+ EFI_STATUS Status;
+ UINT32 Retries;
+
+ if (Private->BootFileSize == 0) {
+ State = GetBootFileHead;
+ } else {
+ State = LoadBootFile;
+ }
+
+ for ( ; ;) {
+ switch (State) {
+ case GetBootFileHead:
+ //
+ // Try to use HTTP HEAD method.
+ //
+ Status = HttpBootGetBootFile (
+ Private,
+ TRUE,
+ &Private->BootFileSize,
+ NULL,
+ &Private->ImageType
+ );
+ if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ if ((Private->AuthData != NULL) && (Status == EFI_ACCESS_DENIED)) {
+ //
+ // Try to use HTTP HEAD method again since the Authentication information is provided.
+ //
+ State = GetBootFileHead;
+ } else {
+ State = GetBootFileGet;
+ }
+ } else {
+ State = LoadBootFile;
+ }
+
+ break;
+
+ case GetBootFileGet:
+ //
+ // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
+ //
+ ASSERT (Private->BootFileSize == 0);
+ Status = HttpBootGetBootFile (
+ Private,
+ FALSE,
+ &Private->BootFileSize,
+ NULL,
+ &Private->ImageType
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ State = GetBootFileError;
+ } else {
+ State = LoadBootFile;
+ }
+
+ break;
+
+ case LoadBootFile:
+ if (*BufferSize < Private->BootFileSize) {
+ *BufferSize = Private->BootFileSize;
+ *ImageType = Private->ImageType;
+ Status = EFI_BUFFER_TOO_SMALL;
+ return Status;
+ }
+
+ //
+ // Load the boot file into Buffer
+ //
+ for (Retries = 1; Retries <= PcdGet32 (PcdMaxHttpResumeRetries); Retries++) {
+ Status = HttpBootGetBootFile (
+ Private,
+ FALSE,
+ BufferSize,
+ Buffer,
+ ImageType
+ );
+ if (!EFI_ERROR (Status) ||
+ ((Status != EFI_TIMEOUT) && (Status != EFI_DEVICE_ERROR)))
+ {
+ break;
+ }
+
+ //
+ // HttpBootGetBootFile returned EFI_TIMEOUT or EFI_DEVICE_ERROR.
+ // We may attempt to resume the interrupted download.
+ //
+
+ Private->HttpCreated = FALSE;
+ HttpIoDestroyIo (&Private->HttpIo);
+ Status = HttpBootCreateHttpIo (Private);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ DEBUG ((DEBUG_WARN | DEBUG_INFO, "HttpBootGetBootFileCaller: NBP file download interrupted, will try to resume the operation.\n"));
+ gBS->Stall (1000 * 1000 * PcdGet32 (PcdHttpDelayBetweenResumeRetries));
+ }
+
+ if (EFI_ERROR (Status) && (Retries >= PcdGet32 (PcdMaxHttpResumeRetries))) {
+ DEBUG ((DEBUG_ERROR, "HttpBootGetBootFileCaller: Error downloading NBP file, even after trying to resume %d times.\n", Retries));
+ }
+
+ return Status;
+
+ case GetBootFileError:
+ default:
+ AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n");
+ return Status;
+ }
+ }
+}
+
+/**
Attempt to download the boot file through HTTP message exchange.
@param[in] Private The pointer to the driver's private data.
@@ -345,68 +494,10 @@ HttpBootLoadFile (
}
}
- if (Private->BootFileSize == 0) {
- //
- // Discover the information about the bootfile if we haven't.
- //
-
- //
- // Try to use HTTP HEAD method.
- //
- Status = HttpBootGetBootFile (
- Private,
- TRUE,
- &Private->BootFileSize,
- NULL,
- &Private->ImageType
- );
- if ((Private->AuthData != NULL) && (Status == EFI_ACCESS_DENIED)) {
- //
- // Try to use HTTP HEAD method again since the Authentication information is provided.
- //
- Status = HttpBootGetBootFile (
- Private,
- TRUE,
- &Private->BootFileSize,
- NULL,
- &Private->ImageType
- );
- } else if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) {
- //
- // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
- //
- ASSERT (Private->BootFileSize == 0);
- Status = HttpBootGetBootFile (
- Private,
- FALSE,
- &Private->BootFileSize,
- NULL,
- &Private->ImageType
- );
- if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
- AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n");
- goto ON_EXIT;
- }
- }
- }
-
- if (*BufferSize < Private->BootFileSize) {
- *BufferSize = Private->BootFileSize;
- *ImageType = Private->ImageType;
- Status = EFI_BUFFER_TOO_SMALL;
- goto ON_EXIT;
- }
-
//
- // Load the boot file into Buffer
+ // Load the boot file
//
- Status = HttpBootGetBootFile (
- Private,
- FALSE,
- BufferSize,
- Buffer,
- ImageType
- );
+ Status = HttpBootGetBootFileCaller (Private, BufferSize, Buffer, ImageType);
ON_EXIT:
HttpBootUninstallCallback (Private);
@@ -467,12 +558,13 @@ HttpBootStop (
ZeroMem (&Private->StationIp, sizeof (EFI_IP_ADDRESS));
ZeroMem (&Private->SubnetMask, sizeof (EFI_IP_ADDRESS));
ZeroMem (&Private->GatewayIp, sizeof (EFI_IP_ADDRESS));
- Private->Port = 0;
- Private->BootFileUri = NULL;
- Private->BootFileUriParser = NULL;
- Private->BootFileSize = 0;
- Private->SelectIndex = 0;
- Private->SelectProxyType = HttpOfferTypeMax;
+ Private->Port = 0;
+ Private->BootFileUri = NULL;
+ Private->BootFileUriParser = NULL;
+ Private->BootFileSize = 0;
+ Private->SelectIndex = 0;
+ Private->SelectProxyType = HttpOfferTypeMax;
+ Private->PartialTransferredSize = 0;
if (!Private->UsingIpv6) {
//
@@ -522,6 +614,11 @@ HttpBootStop (
Private->FilePathUriParser = NULL;
}
+ if (Private->LastModifiedOrEtag != NULL) {
+ FreePool (Private->LastModifiedOrEtag);
+ Private->LastModifiedOrEtag = NULL;
+ }
+
ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer));
Private->OfferNum = 0;
ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));
@@ -710,7 +807,8 @@ HttpBootCallback (
if (Data != NULL) {
HttpMessage = (EFI_HTTP_MESSAGE *)Data;
if ((HttpMessage->Data.Request->Method == HttpMethodGet) &&
- (HttpMessage->Data.Request->Url != NULL))
+ (HttpMessage->Data.Request->Url != NULL) &&
+ (Private->PartialTransferredSize == 0))
{
Print (L"\n URI: %s\n", HttpMessage->Data.Request->Url);
}
@@ -742,6 +840,16 @@ HttpBootCallback (
}
}
+ // If download was resumed, do not change progress variables
+ HttpHeader = HttpFindHeader (
+ HttpMessage->HeaderCount,
+ HttpMessage->Headers,
+ HTTP_HEADER_CONTENT_RANGE
+ );
+ if (HttpHeader) {
+ break;
+ }
+
HttpHeader = HttpFindHeader (
HttpMessage->HeaderCount,
HttpMessage->Headers,
diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.h b/NetworkPkg/HttpBootDxe/HttpBootImpl.h
index 55adc9c..33da4fe 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootImpl.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.h
@@ -11,6 +11,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define HTTP_BOOT_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20)
+typedef enum {
+ GetBootFileHead,
+ GetBootFileGet,
+ LoadBootFile,
+ GetBootFileError
+} HTTP_GET_BOOT_FILE_STATE;
+
/**
Attempt to complete a DHCPv4 D.O.R.A or DHCPv6 S.R.A.A sequence to retrieve the boot resource information.
diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c
index 6606c29..9500f56 100644
--- a/NetworkPkg/HttpDxe/HttpImpl.c
+++ b/NetworkPkg/HttpDxe/HttpImpl.c
@@ -1,7 +1,7 @@
/** @file
Implementation of EFI_HTTP_PROTOCOL protocol interfaces.
- Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
@@ -341,14 +341,18 @@ EfiHttpRequest (
//
Url = HttpInstance->Url;
UrlLen = StrLen (Request->Url) + 1;
- if (UrlLen > HTTP_URL_BUFFER_LEN) {
+ if (UrlLen > HttpInstance->UrlLen) {
Url = AllocateZeroPool (UrlLen);
if (Url == NULL) {
return EFI_OUT_OF_RESOURCES;
}
- FreePool (HttpInstance->Url);
- HttpInstance->Url = Url;
+ if (HttpInstance->Url != NULL) {
+ FreePool (HttpInstance->Url);
+ }
+
+ HttpInstance->Url = Url;
+ HttpInstance->UrlLen = UrlLen;
}
UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);
diff --git a/NetworkPkg/HttpDxe/HttpProto.c b/NetworkPkg/HttpDxe/HttpProto.c
index 9c3b497..75eb068 100644
--- a/NetworkPkg/HttpDxe/HttpProto.c
+++ b/NetworkPkg/HttpDxe/HttpProto.c
@@ -1,7 +1,7 @@
/** @file
Miscellaneous routines for HttpDxe driver.
-Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -738,6 +738,7 @@ HttpInitProtocol (
goto ON_ERROR;
}
+ HttpInstance->UrlLen = HTTP_URL_BUFFER_LEN;
return EFI_SUCCESS;
ON_ERROR:
@@ -847,7 +848,8 @@ HttpCleanProtocol (
if (HttpInstance->Url != NULL) {
FreePool (HttpInstance->Url);
- HttpInstance->Url = NULL;
+ HttpInstance->Url = NULL;
+ HttpInstance->UrlLen = 0;
}
NetMapClean (&HttpInstance->TxTokens);
diff --git a/NetworkPkg/HttpDxe/HttpProto.h b/NetworkPkg/HttpDxe/HttpProto.h
index 7e77b38..e49d2a2 100644
--- a/NetworkPkg/HttpDxe/HttpProto.h
+++ b/NetworkPkg/HttpDxe/HttpProto.h
@@ -1,7 +1,7 @@
/** @file
The header files of miscellaneous routines for HttpDxe driver.
-Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -165,6 +165,7 @@ typedef struct _HTTP_PROTOCOL {
NET_MAP RxTokens;
CHAR8 *Url;
+ UINTN UrlLen;
//
// Https Support
diff --git a/NetworkPkg/Include/Library/HttpLib.h b/NetworkPkg/Include/Library/HttpLib.h
index f8505ab..a6894d3 100644
--- a/NetworkPkg/Include/Library/HttpLib.h
+++ b/NetworkPkg/Include/Library/HttpLib.h
@@ -444,6 +444,9 @@ HttpGenRequestMessage (
Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined
in UEFI 2.5 specification.
+ The official HTTP status codes can be found here:
+ https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+
@param[in] StatusCode The status code value in HTTP message.
@return Value defined in EFI_HTTP_STATUS_CODE .
diff --git a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
index 2181346..edb8f58 100644
--- a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
+++ b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
@@ -1927,6 +1927,11 @@ HttpGenRequestMessage (
CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength);
RequestPtr += StrLength;
break;
+ case HttpMethodConnect:
+ StrLength = sizeof (HTTP_METHOD_CONNECT) - 1;
+ CopyMem (RequestPtr, HTTP_METHOD_CONNECT, StrLength);
+ RequestPtr += StrLength;
+ break;
default:
ASSERT (FALSE);
Status = EFI_INVALID_PARAMETER;
@@ -1990,6 +1995,9 @@ Exit:
Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined
in UEFI 2.5 specification.
+ The official HTTP status codes can be found here:
+ https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+
@param[in] StatusCode The status code value in HTTP message.
@return Value defined in EFI_HTTP_STATUS_CODE .
@@ -2072,6 +2080,8 @@ HttpMappingToStatusCode (
return HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED;
case 417:
return HTTP_STATUS_417_EXPECTATION_FAILED;
+ case 429:
+ return HTTP_STATUS_429_TOO_MANY_REQUESTS;
case 500:
return HTTP_STATUS_500_INTERNAL_SERVER_ERROR;
case 501:
diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c
index 4dfbe91..cf875d7 100644
--- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.c
+++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.c
@@ -133,10 +133,16 @@ GLOBAL_REMOVE_IF_UNREFERENCED VLAN_DEVICE_PATH mNetVlanDevicePathTemplate = {
// These represent UEFI SPEC defined algorithms that should be supported by
// the RNG protocol and are generally considered secure.
//
-// The order of the algorithms in this array is important. This order is the order
-// in which the algorithms will be tried by the RNG protocol.
-// If your platform needs to use a specific algorithm for the random number generator,
-// then you should place that algorithm first in the array.
+// Assuming that PcdEnforceSecureRngAlgorithms is TRUE (the default) then
+// only the algorithms defined here will be used by the network stack, and
+// none of these being available will result in an error condition (even if
+// some other RNG implementation is available).
+//
+// If PcdEnforceSecureRngAlgorithms is FALSE this list is not consulted,
+// and the first available RNG algorithm is used.
+//
+// If your platform needs to use a specific algorithm for the random number
+// generator, then you should modify this array.
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID *mSecureHashAlgorithms[] = {
&gEfiRngAlgorithmSp80090Ctr256Guid, // SP800-90A DRBG CTR using AES-256
diff --git a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf
index a8f534a..54dcb97 100644
--- a/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf
+++ b/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf
@@ -67,7 +67,7 @@
gEfiRngProtocolGuid ## CONSUMES
[FixedPcd]
- gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES
[Depex]
gEfiRngProtocolGuid
diff --git a/NetworkPkg/MnpDxe/MnpConfig.c b/NetworkPkg/MnpDxe/MnpConfig.c
index 93587d5..d0e3f82 100644
--- a/NetworkPkg/MnpDxe/MnpConfig.c
+++ b/NetworkPkg/MnpDxe/MnpConfig.c
@@ -234,7 +234,7 @@ MnpAddFreeTxBuf (
break;
}
- DEBUG ((DEBUG_INFO, "MnpAddFreeTxBuf: Add TxBufWrap %p, TxBuf %p\n", TxBufWrap, TxBufWrap->TxBuf));
+ DEBUG ((DEBUG_VERBOSE, "MnpAddFreeTxBuf: Add TxBufWrap %p, TxBuf %p\n", TxBufWrap, TxBufWrap->TxBuf));
TxBufWrap->Signature = MNP_TX_BUF_WRAP_SIGNATURE;
TxBufWrap->InUse = FALSE;
InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry);
diff --git a/NetworkPkg/NetworkPcds.dsc.inc b/NetworkPkg/NetworkPcds.dsc.inc
index f874b38..c6299ad 100644
--- a/NetworkPkg/NetworkPcds.dsc.inc
+++ b/NetworkPkg/NetworkPcds.dsc.inc
@@ -11,6 +11,6 @@
#
##
-!if $(NETWORK_ALLOW_HTTP_CONNECTIONS) == TRUE
+!if ($(NETWORK_ENABLE) == TRUE) AND ($(NETWORK_ALLOW_HTTP_CONNECTIONS) == TRUE)
gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|TRUE
!endif
diff --git a/NetworkPkg/NetworkPkg.ci.yaml b/NetworkPkg/NetworkPkg.ci.yaml
index 076424e..5626e94 100644
--- a/NetworkPkg/NetworkPkg.ci.yaml
+++ b/NetworkPkg/NetworkPkg.ci.yaml
@@ -7,6 +7,9 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "NetworkPkg.dsc",
+ },
"LicenseCheck": {
"IgnoreFiles": []
},
diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
index 7c4289b..5db7aa1 100644
--- a/NetworkPkg/NetworkPkg.dec
+++ b/NetworkPkg/NetworkPkg.dec
@@ -104,6 +104,16 @@
# @Prompt Max size of total HTTP chunk transfer. the default value is 12MB.
gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpChunkTransfer|0x0C00000|UINT32|0x0000000E
+ ## The maximum number of retries while attempting to resume an
+ # interrupted HTTP download using a HTTP Range request header.
+ # @Prompt Max number of HTTP download resume retries. Default value is 5.
+ gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpResumeRetries|0x00000005|UINT32|0x00000012
+
+ ## Delay in seconds between each attempt to resume an
+ # interrupted HTTP download.
+ # @Prompt Delay in seconds between each HTTP resume retry. Default value is 2s.
+ gEfiNetworkPkgTokenSpaceGuid.PcdHttpDelayBetweenResumeRetries|0x00000002|UINT32|0x00000013
+
[PcdsFixedAtBuild, PcdsPatchableInModule]
## Indicates whether HTTP connections (i.e., unsecured) are permitted or not.
# TRUE - HTTP connections are allowed. Both the "https://" and "http://" URI schemes are permitted.
@@ -131,12 +141,6 @@
# @Prompt Indicates whether SnpDxe creates event for ExitBootServices() call.
gEfiNetworkPkgTokenSpaceGuid.PcdSnpCreateExitBootServicesEvent|TRUE|BOOLEAN|0x1000000C
- ## Enforces the use of Secure UEFI spec defined RNG algorithms for all network connections.
- # TRUE - Enforce the use of Secure UEFI spec defined RNG algorithms.
- # FALSE - Do not enforce and depend on the default implementation of RNG algorithm from the provider.
- # @Prompt Enforce the use of Secure UEFI spec defined RNG algorithms.
- gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms|TRUE|BOOLEAN|0x1000000D
-
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
## IPv6 DHCP Unique Identifier (DUID) Type configuration (From RFCs 3315 and 6355).
# 01 = DUID Based on Link-layer Address Plus Time [DUID-LLT]
diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc
index 808c6bf..f008790 100644
--- a/NetworkPkg/NetworkPkg.dsc
+++ b/NetworkPkg/NetworkPkg.dsc
@@ -62,6 +62,10 @@
FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.UEFI_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -72,13 +76,6 @@
ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
[LibraryClasses.ARM, LibraryClasses.AARCH64]
- #
- # It is not possible to prevent ARM compiler calls to generic intrinsic functions.
- # This library provides the instrinsic functions generated by a given compiler.
- # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
- #
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
[LibraryClasses.ARM]
diff --git a/NetworkPkg/SnpDxe/Reset.c b/NetworkPkg/SnpDxe/Reset.c
index 2ff6853..72f3142 100644
--- a/NetworkPkg/SnpDxe/Reset.c
+++ b/NetworkPkg/SnpDxe/Reset.c
@@ -2,6 +2,7 @@
Implementation of resetting a network adapter.
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -93,10 +94,12 @@ SnpUndi32Reset (
EFI_STATUS Status;
//
- // Resolve Warning 4 unreferenced parameter problem
+ // There is no support when ExtendedVerification is set to FALSE.
//
- ExtendedVerification = 0;
- DEBUG ((DEBUG_WARN, "ExtendedVerification = %d is not implemented!\n", ExtendedVerification));
+ if (!ExtendedVerification) {
+ DEBUG ((DEBUG_WARN, "ExtendedVerification = %d is not implemented!\n", ExtendedVerification));
+ return EFI_INVALID_PARAMETER;
+ }
if (This == NULL) {
return EFI_INVALID_PARAMETER;
diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc
index 1772afb..667be95 100644
--- a/NetworkPkg/Test/NetworkPkgHostTest.dsc
+++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc
@@ -83,21 +83,14 @@
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
+
[LibraryClasses.common.UEFI_APPLICATION]
DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
-[LibraryClasses.ARM, LibraryClasses.AARCH64]
- #
- # It is not possible to prevent ARM compiler calls to generic intrinsic functions.
- # This library provides the instrinsic functions generated by a given compiler.
- # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
- #
-!if $(TOOL_CHAIN_TAG) != VS2017 and $(TOOL_CHAIN_TAG) != VS2015 and $(TOOL_CHAIN_TAG) != VS2019
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-!endif
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
[LibraryClasses.ARM]
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
+
[LibraryClasses.RISCV64]
RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
diff --git a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
index 61736ff..e529bc6 100644
--- a/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
+++ b/NetworkPkg/UefiPxeBcDxe/GoogleTest/PxeBcDhcp6GoogleTest.cpp
@@ -290,15 +290,9 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, AttemptUnderflowTest) {
// Test Description
// Test that we can handle recursive dns (multiple dns entries)
TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) {
- EFI_DHCP6_PACKET_OPTION Option = { 0 };
+ EFI_DHCP6_PACKET_OPTION *Option = NULL;
PXEBC_DHCP6_PACKET_CACHE *Cache6 = NULL;
- Private.SelectIndex = 1; // SelectIndex is 1-based
- Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
- Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = &Option;
- // Setup the DHCPv6 offer packet
- Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
-
EFI_IPv6_ADDRESS addresses[2] = {
// 2001:db8:85a3::8a2e:370:7334
{ 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 },
@@ -306,7 +300,18 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) {
{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x78, 0x91, 0xc3, 0xec, 0xd7, 0x4f, 0xf9 }
};
- CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, &addresses, sizeof (addresses));
+ Option = (EFI_DHCP6_PACKET_OPTION *)AllocatePool (sizeof (*Option) + sizeof (addresses));
+ if (Option == NULL) {
+ ASSERT_NE (Option, nullptr);
+ }
+
+ Private.SelectIndex = 1; // SelectIndex is 1-based
+ Cache6 = &Private.OfferBuffer[Private.SelectIndex - 1].Dhcp6;
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] = Option;
+ // Setup the DHCPv6 offer packet
+ Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpCode = DHCP6_OPT_SERVER_ID;
+
+ CopyMem (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, addresses, sizeof (addresses));
Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen = NTOHS (sizeof (addresses));
@@ -327,6 +332,10 @@ TEST_F (PxeBcCacheDnsServerAddressesTest, MultipleDnsEntries) {
if (Private.DnsServer) {
FreePool (Private.DnsServer);
}
+
+ if (Option) {
+ FreePool (Option);
+ }
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c
index f22a151..0af791d 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c
@@ -1268,5 +1268,12 @@ ON_EXIT:
AsciiPrint ("\n PXE-E99: Unexpected network error.\n");
}
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_ERROR_CODE,
+ (EFI_STATUS_CODE_VALUE)(EFI_IO_BUS_IP_NETWORK | EFI_OEM_SPECIFIC | ((EFI_STATUS_CODE_VALUE)(Status & 0x1F))),
+ (VOID *)&(PxeBcMode->UsingIpv6),
+ sizeof (PxeBcMode->UsingIpv6)
+ );
+
return Status;
}
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c
index 0a4baf6..e296474 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c
@@ -72,6 +72,13 @@ EfiPxeBcStart (
return EFI_UNSUPPORTED;
}
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_PROGRESS_CODE,
+ EFI_IO_BUS_IP_NETWORK | EFI_IOB_PC_RECONFIG,
+ (VOID *)&(Mode->UsingIpv6),
+ sizeof (Mode->UsingIpv6)
+ );
+
if (Mode->UsingIpv6) {
AsciiPrint ("\n>>Start PXE over IPv6");
//
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h
index 732889f..cdb9b34 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h
@@ -48,6 +48,7 @@
#include <Library/DpcLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PcdLib.h>
+#include <Library/ReportStatusCodeLib.h>
typedef struct _PXEBC_PRIVATE_DATA PXEBC_PRIVATE_DATA;
typedef struct _PXEBC_PRIVATE_PROTOCOL PXEBC_PRIVATE_PROTOCOL;
diff --git a/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf b/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
index 3371c15..d5aba13 100644
--- a/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+++ b/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
@@ -62,6 +62,7 @@
DpcLib
DevicePathLib
PcdLib
+ ReportStatusCodeLib
[Protocols]
## TO_START
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c
index f242bdf..00804e5 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c
@@ -1490,6 +1490,7 @@ WifiMgrDxeHiiConfigAccessCallback (
} else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
switch (QuestionId) {
case KEY_EAP_ENROLL_CERT_FROM_FILE:
+ case KEY_REFRESH_NETWORK_LIST:
if (Private->CurrentNic->UserSelectedProfile == NULL) {
break;
@@ -1911,39 +1912,6 @@ WifiMgrDxeHiiConfigAccessCallback (
NULL
);
}
-
- if (Private->CurrentNic->UserSelectedProfile == NULL) {
- break;
- }
-
- Profile = Private->CurrentNic->UserSelectedProfile;
-
- //
- // Enter the network connection configuration page
- // Recovery from restored data
- //
- if (HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_SSID), Profile->SSId, NULL) == 0) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- IfrNvData->SecurityType = Profile->SecurityType;
- if (HiiSetString (
- Private->RegisteredHandle,
- STRING_TOKEN (STR_SECURITY_TYPE),
- mSecurityType[IfrNvData->SecurityType],
- NULL
- ) == 0)
- {
- return EFI_OUT_OF_RESOURCES;
- }
-
- if ( (IfrNvData->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE)
- || (IfrNvData->SecurityType == SECURITY_TYPE_WPA3_ENTERPRISE))
- {
- IfrNvData->EapAuthMethod = Profile->EapAuthMethod;
- IfrNvData->EapSecondAuthMethod = Profile->EapSecondAuthMethod;
- StrCpyS (IfrNvData->EapIdentity, EAP_IDENTITY_SIZE, Profile->EapIdentity);
- }
}
break;
diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc
index 40553c0..1f5837d 100644
--- a/OvmfPkg/AmdSev/AmdSevX64.dsc
+++ b/OvmfPkg/AmdSev/AmdSevX64.dsc
@@ -232,6 +232,9 @@
CcExitLib|OvmfPkg/Library/CcExitLib/SecCcExitLib.inf
MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
+ # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.PEI_CORE]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
diff --git a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
index bc2d5da..7bc9f89 100644
--- a/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
+++ b/OvmfPkg/AmdSev/BlobVerifierLibSevHashes/BlobVerifierSevHashes.c
@@ -156,16 +156,6 @@ VerifyBlob (
DEBUG ((DEBUG_INFO, "%a: Found GUID %g in table\n", __func__, Guid));
- if (BufSize == 0) {
- DEBUG ((
- DEBUG_ERROR,
- "%a: Blob Specified in Hash Table was not Provided",
- __func__
- ));
-
- CpuDeadLoop ();
- }
-
EntrySize = Entry->Len - sizeof Entry->Guid - sizeof Entry->Len;
if (EntrySize != SHA256_DIGEST_SIZE) {
DEBUG ((
diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc
index 0689d64..2f5fb46 100644
--- a/OvmfPkg/Bhyve/BhyveX64.dsc
+++ b/OvmfPkg/Bhyve/BhyveX64.dsc
@@ -256,6 +256,9 @@
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
+ # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.PEI_CORE]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc
index 0ad4955..1a8d3c4 100644
--- a/OvmfPkg/CloudHv/CloudHvX64.dsc
+++ b/OvmfPkg/CloudHv/CloudHvX64.dsc
@@ -269,6 +269,9 @@
CcExitLib|OvmfPkg/Library/CcExitLib/SecCcExitLib.inf
MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
+ # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.PEI_CORE]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
@@ -632,9 +635,11 @@
!include OvmfPkg/Include/Dsc/OvmfTpmPcds.dsc.inc
+!if $(NETWORK_ENABLE) == TRUE
# IPv4 and IPv6 PXE Boot support.
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
+!endif
# Set ConfidentialComputing defaults
gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr|0
diff --git a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c
index d504163..5af7821 100644
--- a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c
+++ b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c
@@ -355,6 +355,11 @@ EjectCpu (
//
QemuSelector = mCpuHotEjectData->QemuSelectorMap[ProcessorNum];
if (QemuSelector == CPU_EJECT_QEMU_SELECTOR_INVALID) {
+ /* wait until BSP is done */
+ while (mCpuHotEjectData->Handler != NULL) {
+ CpuPause ();
+ }
+
return;
}
diff --git a/OvmfPkg/Include/Guid/XenInfo.h b/OvmfPkg/Include/Guid/XenInfo.h
index a8f6a36..c5de783 100644
--- a/OvmfPkg/Include/Guid/XenInfo.h
+++ b/OvmfPkg/Include/Guid/XenInfo.h
@@ -14,10 +14,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
typedef struct {
///
- /// Beginning of the hypercall page.
- ///
- VOID *HyperPages;
- ///
/// Hypervisor major version.
///
UINT16 VersionMajor;
diff --git a/OvmfPkg/Include/IndustryStandard/Xen/sched.h b/OvmfPkg/Include/IndustryStandard/Xen/sched.h
new file mode 100644
index 0000000..5ca0017
--- /dev/null
+++ b/OvmfPkg/Include/IndustryStandard/Xen/sched.h
@@ -0,0 +1,50 @@
+/******************************************************************************
+ * sched.h
+ *
+ * Scheduler state interactions
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (c) 2005, Keir Fraser <keir@xensource.com>
+ */
+
+#ifndef __XEN_PUBLIC_SCHED_H__
+#define __XEN_PUBLIC_SCHED_H__
+
+#include "event_channel.h"
+
+/*
+ * Halt execution of this domain (all VCPUs) and notify the system controller.
+ * @arg == pointer to sched_shutdown_t structure.
+ *
+ * If the sched_shutdown_t reason is SHUTDOWN_suspend then
+ * x86 PV guests must also set RDX (EDX for 32-bit guests) to the MFN
+ * of the guest's start info page. RDX/EDX is the third hypercall
+ * argument.
+ *
+ * In addition, which reason is SHUTDOWN_suspend this hypercall
+ * returns 1 if suspend was cancelled or the domain was merely
+ * checkpointed, and 0 if it is resuming in a new domain.
+ */
+#define XEN_SCHEDOP_SHUTDOWN 2
+
+struct _XEN_SCHED_SHUTDOWN {
+ UINT32 Reason; /* SHUTDOWN_* => enum sched_shutdown_reason */
+};
+
+typedef struct _XEN_SCHED_SHUTDOWN XEN_SCHED_SHUTDOWN;
+DEFINE_XEN_GUEST_HANDLE (XEN_SCHED_SHUTDOWN);
+
+/*
+ * Reason codes for SCHEDOP_shutdown. These may be interpreted by control
+ * software to determine the appropriate action. For the most part, Xen does
+ * not care about the shutdown code.
+ */
+/* ` enum sched_shutdown_reason { */
+#define XEN_SHED_SHUTDOWN_POWEROFF 0 /* Domain exited normally. Clean up and kill. */
+#define XEN_SHED_SHUTDOWN_REBOOT 1 /* Clean up, kill, and then restart. */
+#define XEN_SHED_SHUTDOWN_SUSPEND 2 /* Clean up, save suspend info, kill. */
+#define XEN_SHED_SHUTDOWN_CRASH 3 /* Tell controller we've crashed. */
+#define XEN_SHED_SHUTDOWN_WATCHDOG 4 /* Restart because watchdog time expired. */
+
+#endif /* __XEN_PUBLIC_SCHED_H__ */
diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/Library/MemEncryptSevLib.h
index 4fa9c0d..c565353 100644
--- a/OvmfPkg/Include/Library/MemEncryptSevLib.h
+++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h
@@ -167,6 +167,18 @@ MemEncryptSevGetEncryptionMask (
);
/**
+ Returns a boolean to indicate whether DebugVirtualization is enabled.
+
+ @retval TRUE DebugVirtualization is enabled
+ @retval FALSE DebugVirtualization is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevEsDebugVirtualizationIsEnabled (
+ VOID
+ );
+
+/**
Returns the encryption state of the specified virtual address range.
@param[in] Cr3BaseAddress Cr3 Base Address (if zero then use
diff --git a/OvmfPkg/Include/Library/XenHypercallLib.h b/OvmfPkg/Include/Library/XenHypercallLib.h
index 28eee8c..d7cf2c0 100644
--- a/OvmfPkg/Include/Library/XenHypercallLib.h
+++ b/OvmfPkg/Include/Library/XenHypercallLib.h
@@ -101,4 +101,11 @@ XenHypercallEventChannelOp (
IN OUT VOID *Arguments
);
+INTN
+EFIAPI
+XenHypercallSchedOp (
+ IN INTN Operation,
+ IN OUT VOID *Arguments
+ );
+
#endif
diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
index fc13325..fbda01b 100644
--- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc
+++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc
@@ -240,6 +240,9 @@
PeilessStartupLib|OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf
CcProbeLib|OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf
+ # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
diff --git a/OvmfPkg/IntelTdx/README.md b/OvmfPkg/IntelTdx/README.md
index c168167..6e13c17 100644
--- a/OvmfPkg/IntelTdx/README.md
+++ b/OvmfPkg/IntelTdx/README.md
@@ -61,8 +61,8 @@ Build
cd /path/to/edk2
source edksetup.sh
-## without CC_MEASUREMENT enabled
-build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC5 -b RELEASE
+## CC_MEASUREMENT disabled
+build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC5 -D CC_MEASUREMENT_ENABLE=FALSE -b RELEASE
## CC_MEASUREMENT enabled
build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC5 -D CC_MEASUREMENT_ENABLE=TRUE -b RELEASE
diff --git a/OvmfPkg/IntelTdx/Sec/SecMain.c b/OvmfPkg/IntelTdx/Sec/SecMain.c
index 95a31af..7f2d28a 100644
--- a/OvmfPkg/IntelTdx/Sec/SecMain.c
+++ b/OvmfPkg/IntelTdx/Sec/SecMain.c
@@ -68,6 +68,18 @@ SecMtrrSetup (
return;
}
+ if (CcProbe () == CcGuestTypeIntelTdx) {
+ //
+ // According to TDX Spec, the default MTRR type is enforced to WB
+ // and CR0.CD is enforced to 0.
+ // The TD guest has to disable MTRR otherwise it tries to
+ // program MTRRs to disable caching. CR0.CD=1 results in the
+ // unexpected #VE.
+ //
+ DEBUG ((DEBUG_INFO, "%a: Skip TD-Guest\n", __func__));
+ return;
+ }
+
DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE);
DefType.Bits.Type = MSR_IA32_MTRR_CACHE_WRITE_BACK;
DefType.Bits.E = 1; /* enable */
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
index 4aba007..9947d66 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLibInternal.c
@@ -40,19 +40,25 @@ AmdMemEncryptionAttrCheck (
IN CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr
)
{
+ UINT64 CurrentLevel;
+
+ CurrentLevel = CurrentAttr & CCAttrTypeMask;
+
switch (Attr) {
case CCAttrAmdSev:
//
// SEV is automatically enabled if SEV-ES or SEV-SNP is active.
//
- return CurrentAttr >= CCAttrAmdSev;
+ return CurrentLevel >= CCAttrAmdSev;
case CCAttrAmdSevEs:
//
// SEV-ES is automatically enabled if SEV-SNP is active.
//
- return CurrentAttr >= CCAttrAmdSevEs;
+ return CurrentLevel >= CCAttrAmdSevEs;
case CCAttrAmdSevSnp:
- return CurrentAttr == CCAttrAmdSevSnp;
+ return CurrentLevel == CCAttrAmdSevSnp;
+ case CCAttrFeatureAmdSevEsDebugVirtualization:
+ return !!(CurrentAttr & CCAttrFeatureAmdSevEsDebugVirtualization);
default:
return FALSE;
}
@@ -159,3 +165,18 @@ MemEncryptSevGetEncryptionMask (
return mSevEncryptionMask;
}
+
+/**
+ Returns a boolean to indicate whether DebugVirtualization is enabled.
+
+ @retval TRUE DebugVirtualization is enabled
+ @retval FALSE DebugVirtualization is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevEsDebugVirtualizationIsEnabled (
+ VOID
+ )
+{
+ return ConfidentialComputingGuestHas (CCAttrFeatureAmdSevEsDebugVirtualization);
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
index 41d1246..f381b92 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/PeiMemEncryptSevLibInternal.c
@@ -141,3 +141,22 @@ MemEncryptSevGetEncryptionMask (
return SevEsWorkArea->EncryptionMask;
}
+
+/**
+ Returns a boolean to indicate whether DebugVirtualization is enabled.
+
+ @retval TRUE DebugVirtualization is enabled
+ @retval FALSE DebugVirtualization is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevEsDebugVirtualizationIsEnabled (
+ VOID
+ )
+{
+ MSR_SEV_STATUS_REGISTER Msr;
+
+ Msr.Uint32 = InternalMemEncryptSevStatus ();
+
+ return Msr.Bits.DebugVirtualization ? TRUE : FALSE;
+}
diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
index 27148c7..946bed2 100644
--- a/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
+++ b/OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLibInternal.c
@@ -143,6 +143,25 @@ MemEncryptSevGetEncryptionMask (
}
/**
+ Returns a boolean to indicate whether DebugVirtualization is enabled.
+
+ @retval TRUE DebugVirtualization is enabled
+ @retval FALSE DebugVirtualization is not enabled
+**/
+BOOLEAN
+EFIAPI
+MemEncryptSevEsDebugVirtualizationIsEnabled (
+ VOID
+ )
+{
+ MSR_SEV_STATUS_REGISTER Msr;
+
+ Msr.Uint32 = InternalMemEncryptSevStatus ();
+
+ return Msr.Bits.DebugVirtualization ? TRUE : FALSE;
+}
+
+/**
Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM
Save State Map.
diff --git a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
index da8f1e5..2031fa9 100644
--- a/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
+++ b/OvmfPkg/Library/CcExitLib/CcExitVcHandler.c
@@ -1609,6 +1609,10 @@ Dr7WriteExit (
UINT64 *Register;
UINT64 Status;
+ if (MemEncryptSevEsDebugVirtualizationIsEnabled ()) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+
Ext = &InstructionData->Ext;
SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);
@@ -1659,6 +1663,10 @@ Dr7ReadExit (
SEV_ES_PER_CPU_DATA *SevEsData;
UINT64 *Register;
+ if (MemEncryptSevEsDebugVirtualizationIsEnabled ()) {
+ return UnsupportedExit (Ghcb, Regs, InstructionData);
+ }
+
Ext = &InstructionData->Ext;
SevEsData = (SEV_ES_PER_CPU_DATA *)(Ghcb + 1);
diff --git a/OvmfPkg/Library/HardwareInfoLib/HardwareInfoDxe.c b/OvmfPkg/Library/HardwareInfoLib/HardwareInfoDxe.c
index 5a1a69d..b4dc927 100644
--- a/OvmfPkg/Library/HardwareInfoLib/HardwareInfoDxe.c
+++ b/OvmfPkg/Library/HardwareInfoLib/HardwareInfoDxe.c
@@ -89,7 +89,7 @@ FreeResources:
FailedAllocate:
DEBUG ((
- EFI_D_ERROR,
+ DEBUG_ERROR,
"%a: Failed to allocate memory for hardware info\n",
__func__
));
diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
index 1632a23..42db1a6 100644
--- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
+++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartup.c
@@ -109,7 +109,6 @@ InitializePlatform (
if (TdIsEnabled ()) {
PlatformInfoHob->PcdConfidentialComputingGuestAttr = CCAttrIntelTdx;
PlatformInfoHob->PcdTdxSharedBitMask = TdSharedPageMask ();
- PlatformInfoHob->PcdSetNxForStack = TRUE;
}
PlatformMiscInitialization (PlatformInfoHob);
diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
index e561cee..12e4501 100644
--- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
+++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c
@@ -154,6 +154,18 @@ PlatformTdxPublishRamRegions (
TransferTdxHobList ();
//
+ // Reserve the initial page tables built by the reset vector code.
+ //
+ // Since this memory range will be used by APs on Mailbox
+ // wakeup, it must be reserved as ACPI NVS.
+ //
+ BuildMemoryAllocationHob (
+ (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdOvmfSecPageTablesBase),
+ (UINT64)(UINTN)PcdGet32 (PcdOvmfSecPageTablesSize),
+ EfiACPIMemoryNVS
+ );
+
+ //
// The memory region defined by PcdOvmfSecGhcbBackupBase is pre-allocated by
// host VMM and used as the td mailbox at the beginning of system boot.
//
diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
index bd6c79e..b6aefb3 100644
--- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c
+++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c
@@ -107,6 +107,36 @@ typedef VOID (*E820_SCAN_CALLBACK) (
EFI_HOB_PLATFORM_INFO *PlatformInfoHob
);
+STATIC
+EFI_STATUS
+PlatformScanE820Tdx (
+ IN E820_SCAN_CALLBACK Callback,
+ IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
+ )
+{
+ EFI_E820_ENTRY64 E820Entry;
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = (UINT8 *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
+
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED) ||
+ (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY))
+ {
+ E820Entry.BaseAddr = Hob.ResourceDescriptor->PhysicalStart;
+ E820Entry.Length = Hob.ResourceDescriptor->ResourceLength;
+ E820Entry.Type = EfiAcpiAddressRangeMemory;
+ Callback (&E820Entry, PlatformInfoHob);
+ }
+ }
+
+ Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength);
+ }
+
+ return EFI_SUCCESS;
+}
+
/**
Store first address not used by e820 RAM entries in
PlatformInfoHob->FirstNonAddress
@@ -347,6 +377,10 @@ PlatformScanE820 (
return PlatformScanE820Pvh (Callback, PlatformInfoHob);
}
+ if (TdIsEnabled ()) {
+ return PlatformScanE820Tdx (Callback, PlatformInfoHob);
+ }
+
Status = QemuFwCfgFindFile ("etc/e820", &FwCfgItem, &FwCfgSize);
if (EFI_ERROR (Status)) {
return Status;
@@ -898,6 +932,111 @@ PlatformScanHostProvided64BitPciMmioEnd (
return EFI_NOT_FOUND;
}
+VOID
+EFIAPI
+Switch4Level (
+ VOID
+ );
+
+/**
+ Configure x64 paging levels.
+
+
+ The OVMF ResetVector code will enter long mode with 5-level paging if the
+ following conditions are true:
+
+ (1) OVMF has been built with PcdUse5LevelPageTable = TRUE, and
+ (2) the CPU supports 5-level paging (aka la57), and
+ (3) the CPU supports gigabyte pages, and
+ (4) the VM is not running in SEV mode.
+
+ Condition (4) is a temporary stopgap for BaseMemEncryptSevLib not supporting
+ 5-level paging yet.
+
+
+ This function looks at the virtual machine configuration, then decides
+ whenever it will continue to use 5-level paging or downgrade to 4-level
+ paging for better compatibility with older guest OS versions.
+
+ There is a fw_cfg config option to explicitly request 4 or 5-level paging
+ using 'qemu -fw_cfg name=opt/org.tianocode/PagingLevel,string=4|5'. If the
+ option is present the requested paging level will be used.
+
+ Should that not be the case the function checks the size of the address space
+ needed, which is the RAM installed plus fw_cfg reservations. The downgrade
+ to 4-level paging will happen for small guests where the address space needed
+ is lower than 1TB.
+
+
+ This function will also log the paging level used and the reason for that.
+**/
+STATIC
+VOID
+PlatformSetupPagingLevel (
+ IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
+ )
+{
+ #ifdef MDE_CPU_X64
+ UINT32 PagingLevel;
+ EFI_STATUS Status;
+ IA32_CR4 Cr4;
+
+ Cr4.UintN = AsmReadCr4 ();
+ if (!Cr4.Bits.LA57) {
+ /* The OvmfPkg ResetVector has NOT turned on 5-level paging, log the reason. */
+ if (!PcdGetBool (PcdUse5LevelPageTable)) {
+ DEBUG ((DEBUG_INFO, "%a: using 4-level paging (PcdUse5LevelPageTable disabled)\n", __func__));
+ } else {
+ DEBUG ((DEBUG_INFO, "%a: using 4-level paging (la57 not supported by cpu)\n", __func__));
+ }
+
+ return;
+ }
+
+ Status = QemuFwCfgParseUint32 (
+ "opt/org.tianocode/PagingLevel",
+ FALSE,
+ &PagingLevel
+ );
+ switch (Status) {
+ case EFI_NOT_FOUND:
+ if (PlatformInfoHob->FirstNonAddress < (1ll << 40)) {
+ //
+ // If the highest address actually used is below 1TB switch back into
+ // 4-level paging mode for better compatibility with older guests.
+ //
+ DEBUG ((DEBUG_INFO, "%a: using 4-level paging (default for small guest)\n", __func__));
+ PagingLevel = 4;
+ } else {
+ DEBUG ((DEBUG_INFO, "%a: using 5-level paging (default for large guest)\n", __func__));
+ PagingLevel = 5;
+ }
+
+ break;
+ case EFI_SUCCESS:
+ if ((PagingLevel != 4) && (PagingLevel != 5)) {
+ DEBUG ((DEBUG_INFO, "%a: invalid paging level in fw_cfg: %d\n", __func__, PagingLevel));
+ return;
+ }
+
+ DEBUG ((DEBUG_INFO, "%a: using %d-level paging (fw_cfg override)\n", __func__, PagingLevel));
+ break;
+ default:
+ DEBUG ((DEBUG_WARN, "%a: QemuFwCfgParseUint32: %r\n", __func__, Status));
+ return;
+ }
+
+ if (PagingLevel == 4) {
+ Switch4Level ();
+ }
+
+ if (PagingLevel == 5) {
+ /* The OvmfPkg ResetVector has turned on 5-level paging, nothing to do here. */
+ }
+
+ #endif
+}
+
/**
Initialize the PhysMemAddressWidth field in PlatformInfoHob based on guest RAM size.
**/
@@ -946,6 +1085,8 @@ PlatformAddressWidthInitialization (
PlatformGetFirstNonAddress (PlatformInfoHob);
}
+ PlatformSetupPagingLevel (PlatformInfoHob);
+
PlatformAddressWidthFromCpuid (PlatformInfoHob, TRUE);
if (PlatformInfoHob->PhysMemAddressWidth != 0) {
// physical address width is known
diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c b/OvmfPkg/Library/PlatformInitLib/Platform.c
index f48bf16..10fc173 100644
--- a/OvmfPkg/Library/PlatformInitLib/Platform.c
+++ b/OvmfPkg/Library/PlatformInitLib/Platform.c
@@ -33,6 +33,7 @@
#include <Guid/SystemNvDataGuid.h>
#include <Guid/VariableFormat.h>
#include <OvmfPlatforms.h>
+#include <Library/TdxLib.h>
#include <Library/PlatformInitLib.h>
@@ -261,6 +262,11 @@ PlatformNoexecDxeInitialization (
IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob
)
{
+ if (TdIsEnabled ()) {
+ PlatformInfoHob->PcdSetNxForStack = TRUE;
+ return EFI_SUCCESS;
+ }
+
return QemuFwCfgParseBool ("opt/ovmf/PcdSetNxForStack", &PlatformInfoHob->PcdSetNxForStack);
}
@@ -558,6 +564,20 @@ PlatformMaxCpuCountInitialization (
UINT16 BootCpuCount = 0;
UINT32 MaxCpuCount;
+ if (TdIsEnabled ()) {
+ BootCpuCount = (UINT16)TdVCpuNum ();
+ MaxCpuCount = TdMaxVCpuNum ();
+
+ if (BootCpuCount > MaxCpuCount) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed with BootCpuCount (%d) more than MaxCpuCount(%u) \n", __func__, BootCpuCount, MaxCpuCount));
+ ASSERT (FALSE);
+ }
+
+ PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber = MaxCpuCount;
+ PlatformInfoHob->PcdCpuBootLogicalProcessorNumber = BootCpuCount;
+ return;
+ }
+
//
// Try to fetch the boot CPU count.
//
diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
index 21e6efa..3e63ef4 100644
--- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
+++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf
@@ -32,6 +32,7 @@
[Sources.X64]
IntelTdx.c
+ X64/Paging.nasm
[Packages]
EmbeddedPkg/EmbeddedPkg.dec
@@ -52,8 +53,6 @@
PcdLib
PciLib
PeiHardwareInfoLib
-
-[LibraryClasses.X64]
TdxLib
[Guids]
@@ -63,6 +62,7 @@
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable
[FixedPcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase
diff --git a/OvmfPkg/Library/PlatformInitLib/X64/Paging.nasm b/OvmfPkg/Library/PlatformInitLib/X64/Paging.nasm
new file mode 100644
index 0000000..895a809
--- /dev/null
+++ b/OvmfPkg/Library/PlatformInitLib/X64/Paging.nasm
@@ -0,0 +1,76 @@
+;------------------------------------------------------------------------------
+; @file
+;
+; Switch from 5-level paging mode to 4-level paging mode.
+;
+; This assumes everything (code, stack, page tables) is in 32-bit
+; address space. Which is true for PEI phase even in X64 builds
+; because low memory is used for early firmware setup.
+;
+; This also assumes the standard ResetVector GDT is active.
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;------------------------------------------------------------------------------
+
+SECTION .text
+BITS 64
+
+global ASM_PFX(Switch4Level)
+ASM_PFX(Switch4Level):
+
+ ; save regs
+ push rax
+ push rbx
+ push rcx
+ push rdx
+
+ ; cs:ip for long mode
+ lea rax, [rel Switch4Level64]
+ mov rbx, 0x3800000000 ; LINEAR_CODE64_SEL << 32
+ or rax, rbx
+ push rax
+
+ ; cs:ip for 32-bit mode
+ lea rax, [rel Switch4Level32]
+ mov rbx, 0x1000000000 ; LINEAR_CODE_SEL << 32
+ or rax, rbx
+ push rax
+
+ ; enter 32-bit mode
+ retf
+
+Switch4Level64:
+ ; restore regs
+ pop rdx
+ pop rcx
+ pop rbx
+ pop rax
+
+ ret
+
+BITS 32
+
+Switch4Level32:
+ ; disable paging
+ mov eax, cr0
+ btc eax, 31 ; clear PG
+ mov cr0, eax
+
+ ; disable 5-level paging
+ mov eax, cr4
+ btc eax, 12 ; clear la57
+ mov cr4, eax
+
+ ; fixup cr3 (dereference 5th level)
+ mov eax, cr3
+ mov eax, [ eax ]
+ and eax, 0xfffff000
+ mov cr3, eax
+
+ ; enable paging
+ mov eax, cr0
+ bts eax, 31 ; set PG
+ mov cr0, eax
+
+ ; back to long mode
+ retf
diff --git a/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c
index 270f050..e0c2146 100644
--- a/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c
+++ b/OvmfPkg/Library/QemuFwCfgS3Lib/QemuFwCfgS3PeiDxe.c
@@ -7,6 +7,7 @@
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
+#include <Library/BaseLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/QemuFwCfgS3Lib.h>
@@ -32,6 +33,10 @@ QemuFwCfgS3Enabled (
UINTN FwCfgSize;
UINT8 SystemStates[6];
+ if (TdIsEnabled ()) {
+ return FALSE;
+ }
+
Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize);
if ((Status != RETURN_SUCCESS) || (FwCfgSize != sizeof SystemStates)) {
return FALSE;
diff --git a/OvmfPkg/Library/ResetSystemLib/BaseResetShutdownXen.c b/OvmfPkg/Library/ResetSystemLib/BaseResetShutdownXen.c
new file mode 100644
index 0000000..f45d912
--- /dev/null
+++ b/OvmfPkg/Library/ResetSystemLib/BaseResetShutdownXen.c
@@ -0,0 +1,65 @@
+/** @file
+ Base Reset System Library Shutdown API implementation for OVMF.
+
+ Copyright (C) 2020, Red Hat, Inc.
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2022, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h> // BIT13
+
+#include <Library/BaseLib.h> // CpuDeadLoop()
+#include <Library/DebugLib.h> // ASSERT()
+#include <Library/IoLib.h> // IoOr16()
+#include <Library/PciLib.h> // PciRead16()
+#include <Library/ResetSystemLib.h> // ResetShutdown()
+#include <Library/XenHypercallLib.h>
+#include <OvmfPlatforms.h> // OVMF_HOSTBRIDGE_DID
+
+/**
+ Calling this function causes the system to enter a power state equivalent
+ to the ACPI G2/S5 or G3 states.
+
+ System shutdown should not return, if it returns, it means the system does
+ not support shut down reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+ VOID
+ )
+{
+ UINT16 AcpiPmBaseAddress;
+ UINT16 HostBridgeDevId;
+
+ AcpiPmBaseAddress = 0;
+ HostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
+ switch (HostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ AcpiPmBaseAddress = PIIX4_PMBA_VALUE;
+ break;
+ case INTEL_Q35_MCH_DEVICE_ID:
+ AcpiPmBaseAddress = ICH9_PMBASE_VALUE;
+ break;
+ default:
+ {
+ //
+ // Fallback to using hypercall.
+ // Necessary for PVH guest, but should work for HVM guest.
+ //
+ INTN ReturnCode;
+ XEN_SCHED_SHUTDOWN ShutdownOp = {
+ .Reason = XEN_SHED_SHUTDOWN_POWEROFF,
+ };
+ ReturnCode = XenHypercallSchedOp (XEN_SCHEDOP_SHUTDOWN, ShutdownOp);
+ ASSERT (ReturnCode == 0);
+ CpuDeadLoop ();
+ }
+ }
+
+ IoBitFieldWrite16 (AcpiPmBaseAddress + 4, 10, 13, 0);
+ IoOr16 (AcpiPmBaseAddress + 4, BIT13);
+ CpuDeadLoop ();
+}
diff --git a/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf b/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf
new file mode 100644
index 0000000..8d75dd5
--- /dev/null
+++ b/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf
@@ -0,0 +1,41 @@
+## @file
+# Base library instance for ResetSystem library class for Xen
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2022, Citrix Systems, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseResetSystemLib
+ FILE_GUID = 9ef32aa1-9e82-4fb1-9c49-0eff538601f8
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ResetSystemLib|SEC PEI_CORE PEIM DXE_CORE
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ BaseResetShutdownXen.c
+ ResetSystemLib.c
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
+ PciLib
+ TimerLib
+ XenHypercallLib
diff --git a/OvmfPkg/Library/ResetSystemLib/DxeResetShutdownXen.c b/OvmfPkg/Library/ResetSystemLib/DxeResetShutdownXen.c
new file mode 100644
index 0000000..f7f3276
--- /dev/null
+++ b/OvmfPkg/Library/ResetSystemLib/DxeResetShutdownXen.c
@@ -0,0 +1,77 @@
+/** @file
+ DXE Reset System Library Shutdown API implementation for OVMF.
+
+ Copyright (C) 2020, Red Hat, Inc.
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h> // BIT13
+
+#include <IndustryStandard/Xen/sched.h>
+#include <Library/BaseLib.h> // CpuDeadLoop()
+#include <Library/DebugLib.h> // ASSERT()
+#include <Library/IoLib.h> // IoOr16()
+#include <Library/PcdLib.h> // PcdGet16()
+#include <Library/ResetSystemLib.h> // ResetShutdown()
+#include <Library/XenHypercallLib.h>
+#include <OvmfPlatforms.h> // PIIX4_PMBA_VALUE
+
+STATIC UINT16 mAcpiPmBaseAddress;
+
+EFI_STATUS
+EFIAPI
+DxeResetInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ UINT16 HostBridgeDevId;
+
+ HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);
+ switch (HostBridgeDevId) {
+ case INTEL_82441_DEVICE_ID:
+ mAcpiPmBaseAddress = PIIX4_PMBA_VALUE;
+ break;
+ case INTEL_Q35_MCH_DEVICE_ID:
+ mAcpiPmBaseAddress = ICH9_PMBASE_VALUE;
+ break;
+ default:
+ //
+ // Fallback to using hypercall.
+ // Necessary for PVH guest, but should work for HVM guest.
+ //
+ mAcpiPmBaseAddress = 0xffff;
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Calling this function causes the system to enter a power state equivalent
+ to the ACPI G2/S5 or G3 states.
+
+ System shutdown should not return, if it returns, it means the system does
+ not support shut down reset.
+**/
+VOID
+EFIAPI
+ResetShutdown (
+ VOID
+ )
+{
+ if (mAcpiPmBaseAddress != 0xffff) {
+ IoBitFieldWrite16 (mAcpiPmBaseAddress + 4, 10, 13, 0);
+ IoOr16 (mAcpiPmBaseAddress + 4, BIT13);
+ } else {
+ INTN ReturnCode;
+ XEN_SCHED_SHUTDOWN ShutdownOp = {
+ .Reason = XEN_SHED_SHUTDOWN_POWEROFF,
+ };
+ ReturnCode = XenHypercallSchedOp (XEN_SCHEDOP_SHUTDOWN, &ShutdownOp);
+ ASSERT (ReturnCode == 0);
+ }
+
+ CpuDeadLoop ();
+}
diff --git a/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf b/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
new file mode 100644
index 0000000..ccee69e
--- /dev/null
+++ b/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
@@ -0,0 +1,46 @@
+## @file
+# DXE library instance for ResetSystem library class for Xen
+#
+# Copyright (C) 2020, Red Hat, Inc.
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2022, Citrix Systems, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = DxeResetSystemLibXen
+ FILE_GUID = a5ac25e6-4dc5-4fd9-92cd-74e46bd2e72a
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ResetSystemLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
+ CONSTRUCTOR = DxeResetInit
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ DxeResetShutdownXen.c
+ ResetSystemLib.c
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
+ PcdLib
+ TimerLib
+ XenHypercallLib
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId ## CONSUMES
diff --git a/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm b/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm
index e0fa71b..abcfcb5 100644
--- a/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm
+++ b/OvmfPkg/Library/XenHypercallLib/Ia32/hypercall.nasm
@@ -2,24 +2,47 @@ SECTION .text
; INTN
; EFIAPI
-; __XenHypercall2 (
-; IN VOID *HypercallAddr,
+; __XenVmmcall2 (
+; IN INTN HypercallNum,
; IN OUT INTN Arg1,
; IN OUT INTN Arg2
; );
-global ASM_PFX(__XenHypercall2)
-ASM_PFX(__XenHypercall2):
+global ASM_PFX(__XenVmmcall2)
+ASM_PFX(__XenVmmcall2):
; Save only ebx, ecx is supposed to be a scratch register and needs to be
; saved by the caller
push ebx
- ; Copy HypercallAddr to eax
+ ; Copy HypercallNum to eax
mov eax, [esp + 8]
; Copy Arg1 to the register expected by Xen
mov ebx, [esp + 12]
; Copy Arg2 to the register expected by Xen
mov ecx, [esp + 16]
- ; Call HypercallAddr
- call eax
+ ; Call Hypercall
+ vmmcall
+ pop ebx
+ ret
+
+; INTN
+; EFIAPI
+; __XenVmcall2 (
+; IN INTN HypercallNum,
+; IN OUT INTN Arg1,
+; IN OUT INTN Arg2
+; );
+global ASM_PFX(__XenVmcall2)
+ASM_PFX(__XenVmcall2):
+ ; Save only ebx, ecx is supposed to be a scratch register and needs to be
+ ; saved by the caller
+ push ebx
+ ; Copy HypercallNum to eax
+ mov eax, [esp + 8]
+ ; Copy Arg1 to the register expected by Xen
+ mov ebx, [esp + 12]
+ ; Copy Arg2 to the register expected by Xen
+ mov ecx, [esp + 16]
+ ; Call Hypercall
+ vmcall
pop ebx
ret
diff --git a/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm b/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm
index 5e6a0c0..469ac21 100644
--- a/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm
+++ b/OvmfPkg/Library/XenHypercallLib/X64/hypercall.nasm
@@ -3,23 +3,46 @@ SECTION .text
; INTN
; EFIAPI
-; __XenHypercall2 (
-; IN VOID *HypercallAddr,
+; __XenVmmcall2 (
+; IN INTN HypercallNum,
; IN OUT INTN Arg1,
; IN OUT INTN Arg2
; );
-global ASM_PFX(__XenHypercall2)
-ASM_PFX(__XenHypercall2):
+global ASM_PFX(__XenVmmcall2)
+ASM_PFX(__XenVmmcall2):
push rdi
push rsi
- ; Copy HypercallAddr to rax
+ ; Copy HypercallNum to rax
mov rax, rcx
; Copy Arg1 to the register expected by Xen
mov rdi, rdx
; Copy Arg2 to the register expected by Xen
mov rsi, r8
- ; Call HypercallAddr
- call rax
+ ; Call HypercallNum
+ vmmcall
+ pop rsi
+ pop rdi
+ ret
+
+; INTN
+; EFIAPI
+; __XenVmcall2 (
+; IN INTN HypercallNum,
+; IN OUT INTN Arg1,
+; IN OUT INTN Arg2
+; );
+global ASM_PFX(__XenVmcall2)
+ASM_PFX(__XenVmcall2):
+ push rdi
+ push rsi
+ ; Copy HypercallNum to rax
+ mov rax, rcx
+ ; Copy Arg1 to the register expected by Xen
+ mov rdi, rdx
+ ; Copy Arg2 to the register expected by Xen
+ mov rsi, r8
+ ; Call HypercallNum
+ vmcall
pop rsi
pop rdi
ret
diff --git a/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c b/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c
index dcc6575..a07d9e4 100644
--- a/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c
+++ b/OvmfPkg/Library/XenHypercallLib/X86XenHypercall.c
@@ -7,11 +7,31 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiDxe.h>
-#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
-#include <Guid/XenInfo.h>
+#include <Library/CpuLib.h>
-STATIC VOID *HyperPage;
+static INTN mUseVmmCall = -1;
+static BOOLEAN mHypercallAvail;
+
+//
+// Interface exposed by the ASM implementation of the core hypercall
+//
+INTN
+EFIAPI
+__XenVmmcall2 (
+ IN INTN HypercallNum,
+ IN OUT INTN Arg1,
+ IN OUT INTN Arg2
+ );
+
+INTN
+EFIAPI
+__XenVmcall2 (
+ IN INTN HypercallNum,
+ IN OUT INTN Arg1,
+ IN OUT INTN Arg2
+ );
/**
Check if the Xen Hypercall library is able to make calls to the Xen
@@ -29,23 +49,38 @@ XenHypercallIsAvailable (
VOID
)
{
- return HyperPage != NULL;
+ return mHypercallAvail;
}
-//
-// Interface exposed by the ASM implementation of the core hypercall
-//
-INTN
-EFIAPI
-__XenHypercall2 (
- IN VOID *HypercallAddr,
- IN OUT INTN Arg1,
- IN OUT INTN Arg2
- );
+STATIC
+UINT32
+XenCpuidLeaf (
+ VOID
+ )
+{
+ UINT8 Signature[13];
+ UINT32 XenLeaf;
+
+ Signature[12] = '\0';
+ for (XenLeaf = 0x40000000; XenLeaf < 0x40010000; XenLeaf += 0x100) {
+ AsmCpuid (
+ XenLeaf,
+ NULL,
+ (UINT32 *)&Signature[0],
+ (UINT32 *)&Signature[4],
+ (UINT32 *)&Signature[8]
+ );
+
+ if (!AsciiStrCmp ((CHAR8 *)Signature, "XenVMMXenVMM")) {
+ return XenLeaf;
+ }
+ }
+
+ return 0;
+}
/**
- Library constructor: retrieves the Hyperpage address
- from the gEfiXenInfoGuid HOB
+ Library constructor: Check for Xen leaf in CPUID
**/
RETURN_STATUS
EFIAPI
@@ -53,16 +88,41 @@ XenHypercallLibInit (
VOID
)
{
- EFI_HOB_GUID_TYPE *GuidHob;
- EFI_XEN_INFO *XenInfo;
+ UINT32 XenLeaf;
+ CHAR8 sig[13];
- GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
- if (GuidHob == NULL) {
+ XenLeaf = XenCpuidLeaf ();
+ if (XenLeaf == 0) {
return RETURN_NOT_FOUND;
}
- XenInfo = (EFI_XEN_INFO *)GET_GUID_HOB_DATA (GuidHob);
- HyperPage = XenInfo->HyperPages;
+ sig[12] = '\0';
+ AsmCpuid (
+ 0,
+ NULL,
+ (UINT32 *)&sig[0],
+ (UINT32 *)&sig[8],
+ (UINT32 *)&sig[4]
+ );
+
+ DEBUG ((DEBUG_INFO, "Detected CPU \"%12a\"\n", sig));
+
+ if ((AsciiStrCmp ("AuthenticAMD", sig) == 0) ||
+ (AsciiStrCmp ("HygonGenuine", sig) == 0))
+ {
+ mUseVmmCall = TRUE;
+ } else if ((AsciiStrCmp ("GenuineIntel", sig) == 0) ||
+ (AsciiStrCmp ("CentaurHauls", sig) == 0) ||
+ (AsciiStrCmp (" Shanghai ", sig) == 0))
+ {
+ mUseVmmCall = FALSE;
+ } else {
+ DEBUG ((DEBUG_ERROR, "Unsupported CPU vendor\n"));
+ return RETURN_NOT_FOUND;
+ }
+
+ mHypercallAvail = TRUE;
+
return RETURN_SUCCESS;
}
@@ -84,7 +144,9 @@ XenHypercall2 (
IN OUT INTN Arg2
)
{
- ASSERT (HyperPage != NULL);
-
- return __XenHypercall2 ((UINT8 *)HyperPage + HypercallID * 32, Arg1, Arg2);
+ if (mUseVmmCall) {
+ return __XenVmmcall2 (HypercallID, Arg1, Arg2);
+ } else {
+ return __XenVmcall2 (HypercallID, Arg1, Arg2);
+ }
}
diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercall.c b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
index 65b14a1..b1a1299 100644
--- a/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercall.c
@@ -87,3 +87,17 @@ XenHypercallEventChannelOp (
(INTN)Arguments
);
}
+
+INTN
+EFIAPI
+XenHypercallSchedOp (
+ IN INTN Operation,
+ IN OUT VOID *Arguments
+ )
+{
+ return XenHypercall2 (
+ __HYPERVISOR_sched_op,
+ Operation,
+ (INTN)Arguments
+ );
+}
diff --git a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
index edb7787..2321b61 100644
--- a/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+++ b/OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
@@ -13,11 +13,6 @@
MODULE_TYPE = BASE
VERSION_STRING = 1.0
CONSTRUCTOR = XenHypercallLibConstruct
-
-[Defines.IA32, Defines.X64]
- LIBRARY_CLASS = XenHypercallLib|PEIM DXE_DRIVER UEFI_DRIVER
-
-[Defines.ARM, Defines.AARCH64]
LIBRARY_CLASS = XenHypercallLib
#
@@ -52,6 +47,7 @@
OvmfPkg/OvmfPkg.dec
[LibraryClasses.IA32, LibraryClasses.X64]
+ CpuLib
BaseLib
HobLib
DebugLib
diff --git a/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c b/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c
index be2d98c..9091b70 100644
--- a/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c
+++ b/OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInit.c
@@ -141,6 +141,12 @@ ConfigureMemoryManagementUnit (
return EFI_UNSUPPORTED;
}
+ //
+ // Clear PGD series registers.
+ //
+ CsrWrite (LOONGARCH_CSR_PGDL, 0x0);
+ CsrWrite (LOONGARCH_CSR_PGDH, 0x0);
+
PageTable = 0;
while (MemoryTable->NumberOfPages != 0) {
DEBUG ((
diff --git a/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c
index baaa7ae..8a73b8f 100644
--- a/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c
+++ b/OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.c
@@ -26,13 +26,13 @@ PlatformHookSerialPortInitialize (
VOID
)
{
- UINT64 *UartBase;
+ UINT64 UartBase;
if (PcdGet64 (PcdSerialRegisterBase) != 0) {
return RETURN_SUCCESS;
}
- *UartBase = CsrRead (LOONGARCH_CSR_KS1);
+ UartBase = CsrRead (LOONGARCH_CSR_KS1);
- return (RETURN_STATUS)PcdSet64S (PcdSerialRegisterBase, (UINTN)*UartBase);
+ return (RETURN_STATUS)PcdSet64S (PcdSerialRegisterBase, (UINTN)UartBase);
}
diff --git a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c
index 0925ab1..d1cce9a 100644
--- a/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c
+++ b/OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.c
@@ -49,7 +49,7 @@ InitRtc (
MmioWrite32 (mRtcBase + RTC_CTRL_REG, Val);
mInitialized = TRUE;
} else {
- DebugPrint (EFI_D_INFO, "RTC register address not found!\n");
+ DebugPrint (DEBUG_INFO, "RTC register address not found!\n");
ASSERT (FALSE);
}
}
diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc b/OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc
index 22373be..6d68a9e 100644
--- a/OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc
+++ b/OvmfPkg/LoongArchVirt/LoongArchVirt.fdf.inc
@@ -15,18 +15,8 @@ DEFINE FW_BLOCKS = 0x400
DEFINE FW_SIZE = 0x400000
############################################################################
-#Flash code layout
-#Set Sec size in flash
-DEFINE SECFV_SIZE = 0x00010000
-
-#Set Pei size in flash
-DEFINE PEIFV_SIZE = 0x00040000
-
-#Set Dxe size in flash
-DEFINE DXEFV_SIZE = 0x00350000
-
#Set FVMAIN size
-DEFINE FVMAIN_SIZE = $(SECFV_SIZE) + $(PEIFV_SIZE) +$(DXEFV_SIZE)
+DEFINE FVMAIN_SIZE = $(FW_SIZE)
#Set Memory layout
DEFINE SEC_PEI_TEMP_RAM_BASE = 0x10000
diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc
index 90be933..7558927 100644
--- a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc
+++ b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.dsc
@@ -102,9 +102,6 @@
TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
!endif
- # For stack protector support
- NULL | MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
BaseLib | MdePkg/Library/BaseLib/BaseLib.inf
SafeIntLib | MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
TimeBaseLib | EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
@@ -130,8 +127,7 @@
IoLib | MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
FdtSerialPortAddressLib | OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf
PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/Fdt16550SerialPortHookLib.inf
- SerialPortLib | MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
- EfiResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf
+ SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf
ResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/BaseResetSystemAcpiGedLib.inf
UefiLib | MdePkg/Library/UefiLib/UefiLib.inf
@@ -196,9 +192,11 @@
MemoryAllocationLib | MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
PeiServicesTablePointerLib | MdePkg/Library/PeiServicesTablePointerLibKs0/PeiServicesTablePointerLibKs0.inf
PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf
- SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf
CpuExceptionHandlerLib | UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+ # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+ NULL | MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.PEI_CORE]
PcdLib | MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
HobLib | MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -210,7 +208,6 @@
PeCoffGetEntryPointLib | MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioPeiLib.inf
PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf
- SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf
[LibraryClasses.common.PEIM]
HobLib | MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -229,14 +226,12 @@
CpuMmuInitLib | OvmfPkg/LoongArchVirt/Library/CpuMmuInitLib/CpuMmuInitLib.inf
MpInitLib | UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
PlatformHookLib | OvmfPkg/LoongArchVirt/Library/Fdt16550SerialPortHookLib/EarlyFdt16550SerialPortHookLib.inf
- SerialPortLib | OvmfPkg/LoongArchVirt/Library/EarlyFdtSerialPortLib16550/EarlyFdtSerialPortLib16550.inf
[LibraryClasses.common.DXE_CORE]
HobLib | MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
DxeCoreEntryPoint | MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
MemoryAllocationLib | MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
ReportStatusCodeLib | MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
- PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
CpuExceptionHandlerLib | UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
@@ -252,9 +247,7 @@
RealTimeClockLib | OvmfPkg/LoongArchVirt/Library/LsRealTimeClockLib/LsRealTimeClockLib.inf
VariablePolicyLib | MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxeLib.inf
- EfiResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf
ResetSystemLib | OvmfPkg/LoongArchVirt/Library/ResetSystemAcpiLib/DxeResetSystemAcpiGedLib.inf
- PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
!if $(TARGET) != RELEASE
DebugLib | MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
!endif
@@ -281,7 +274,6 @@
QemuFwCfgS3Lib | OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf
QemuFwCfgLib | OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgMmioDxeLib.inf
PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
- PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
AcpiPlatformLib | OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf
MpInitLib | UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
@@ -291,7 +283,6 @@
MemoryAllocationLib | MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
ExtractGuidedSectionLib | MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
PciPcdProducerLib | OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
- PciExpressLib | MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
################################################################################
#
@@ -426,8 +417,10 @@
#
# IPv4 and IPv6 PXE Boot support.
#
+!if $(NETWORK_ENABLE) == TRUE
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport | 0x01
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport | 0x01
+!endif
#
# SMBIOS entry point version
@@ -559,12 +552,12 @@
#
# Network Support
#
-#!include NetworkPkg/NetworkComponents.dsc.inc
+!include NetworkPkg/NetworkComponents.dsc.inc
-# NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf {
-# <LibraryClasses>
-# NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf
-# }
+ NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf {
+ <LibraryClasses>
+ NULL|OvmfPkg/Library/PxeBcPcdProducerLib/PxeBcPcdProducerLib.inf
+ }
!if $(NETWORK_TLS_ENABLE) == TRUE
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {
@@ -601,18 +594,15 @@
UefiCpuPkg/CpuMmio2Dxe/CpuMmio2Dxe.inf {
<LibraryClasses>
NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
- NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf
}
EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf
MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
<LibraryClasses>
NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
- NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf
}
MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
<LibraryClasses>
NULL|OvmfPkg/Fdt/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
- NULL|OvmfPkg/Library/BaseCachingPciExpressLib/BaseCachingPciExpressLib.inf
}
OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
OvmfPkg/Virtio10Dxe/Virtio10.inf
diff --git a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf
index ca28e6e..ac197ad 100644
--- a/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf
+++ b/OvmfPkg/LoongArchVirt/LoongArchVirtQemu.fdf
@@ -159,7 +159,7 @@ INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
#
# Network modules
-#!include NetworkPkg/Network.fdf.inc
+!include NetworkPkg/Network.fdf.inc
#
# File system
diff --git a/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S b/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S
index dd74c6b..dd59821 100644
--- a/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S
+++ b/OvmfPkg/LoongArchVirt/Sec/LoongArch64/Start.S
@@ -105,7 +105,7 @@ ASM_PFX(EnableIPI):
# )
#**/
ASM_PFX(GetApicId):
- csrrd $a0, LOONGARCH_CSR_CPUNUM
+ csrrd $a0, LOONGARCH_CSR_CPUID
andi $a0, $a0, 0x3ff
jirl $zero, $ra, 0
# End of GetApicId
diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc
index 3b2312d..6fe8dfd 100644
--- a/OvmfPkg/Microvm/MicrovmX64.dsc
+++ b/OvmfPkg/Microvm/MicrovmX64.dsc
@@ -277,6 +277,9 @@
CcExitLib|OvmfPkg/Library/CcExitLib/SecCcExitLib.inf
MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
+ # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.PEI_CORE]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
@@ -647,9 +650,11 @@
gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00
+!if $(NETWORK_ENABLE) == TRUE
# IPv4 and IPv6 PXE Boot support.
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
+!endif
# Set ConfidentialComputing defaults
gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr|0
diff --git a/OvmfPkg/OvmfPkg.ci.yaml b/OvmfPkg/OvmfPkg.ci.yaml
index ff02224..7ce1be2 100644
--- a/OvmfPkg/OvmfPkg.ci.yaml
+++ b/OvmfPkg/OvmfPkg.ci.yaml
@@ -11,7 +11,8 @@
{
## options defined .pytool/Plugin/LicenseCheck
"LicenseCheck": {
- "IgnoreFiles": []
+ ## Imported from Xen and MIT licensed.
+ "IgnoreFiles": ["OvmfPkg/Include/IndustryStandard/Xen"]
},
"EccCheck": {
## Exception sample looks like below:
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index bd6e8ab..34f7b99 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -251,6 +251,7 @@
AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf
+ TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
TdxMailboxLib|OvmfPkg/Library/TdxMailboxLib/TdxMailboxLibNull.inf
[LibraryClasses.common.SEC]
@@ -658,9 +659,11 @@
!include OvmfPkg/Include/Dsc/OvmfTpmPcds.dsc.inc
+!if $(NETWORK_ENABLE) == TRUE
# IPv4 and IPv6 PXE Boot support.
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
+!endif
# Set ConfidentialComputing defaults
gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr|0
@@ -684,6 +687,7 @@
OvmfPkg/Sec/SecMain.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
}
#
@@ -704,7 +708,10 @@
}
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
- OvmfPkg/PlatformPei/PlatformPei.inf
+ OvmfPkg/PlatformPei/PlatformPei.inf {
+ <LibraryClasses>
+ NULL|OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf
+ }
UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
<LibraryClasses>
!if $(SMM_REQUIRE) == TRUE
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index f28049a..ef04ae2 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -676,9 +676,11 @@
gEfiMdePkgTokenSpaceGuid.PcdFSBClock|1000000000
[PcdsDynamicDefault.X64]
+!if $(NETWORK_ENABLE) == TRUE
# IPv4 and IPv6 PXE Boot support.
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
+!endif
[PcdsDynamicHii]
!include OvmfPkg/Include/Dsc/OvmfTpmPcdsHii.dsc.inc
@@ -697,6 +699,7 @@
OvmfPkg/Sec/SecMain.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
}
#
@@ -717,7 +720,10 @@
}
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
- OvmfPkg/PlatformPei/PlatformPei.inf
+ OvmfPkg/PlatformPei/PlatformPei.inf {
+ <LibraryClasses>
+ NULL|OvmfPkg/IntelTdx/TdxHelperLib/TdxHelperLibNull.inf
+ }
UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
<LibraryClasses>
!if $(SMM_REQUIRE) == TRUE
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index f131328..e7fc7a9 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -32,7 +32,7 @@
DEFINE SECURE_BOOT_ENABLE = FALSE
DEFINE SMM_REQUIRE = FALSE
DEFINE SOURCE_DEBUG_ENABLE = FALSE
- DEFINE CC_MEASUREMENT_ENABLE = FALSE
+ DEFINE CC_MEASUREMENT_ENABLE = TRUE
!include OvmfPkg/Include/Dsc/OvmfTpmDefines.dsc.inc
@@ -690,9 +690,11 @@
!include OvmfPkg/Include/Dsc/OvmfTpmPcds.dsc.inc
+!if $(NETWORK_ENABLE) == TRUE
# IPv4 and IPv6 PXE Boot support.
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
+!endif
# Set ConfidentialComputing defaults
gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr|0
@@ -718,6 +720,7 @@
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
NULL|OvmfPkg/IntelTdx/TdxHelperLib/SecTdxHelperLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
}
#
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index c6fc303..ac7d181 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -120,7 +120,7 @@
[LibraryClasses]
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
- ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf
+ ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibXen.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
@@ -302,7 +302,7 @@
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
- ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+ ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
@@ -315,7 +315,7 @@
[LibraryClasses.common.UEFI_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
- ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+ ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
@@ -326,7 +326,7 @@
[LibraryClasses.common.DXE_DRIVER]
AcpiPlatformLib|OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.inf
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
- ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+ ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -346,7 +346,7 @@
[LibraryClasses.common.UEFI_APPLICATION]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
- ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf
+ ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibXen.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -525,6 +525,7 @@
OvmfPkg/Sec/SecMain.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
}
#
diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c
index 88ca145..8562787 100644
--- a/OvmfPkg/PlatformPei/AmdSev.c
+++ b/OvmfPkg/PlatformPei/AmdSev.c
@@ -434,6 +434,7 @@ AmdSevInitialize (
)
{
UINT64 EncryptionMask;
+ UINT64 CCGuestAttr;
RETURN_STATUS PcdStatus;
//
@@ -517,13 +518,19 @@ AmdSevInitialize (
// technology is active.
//
if (MemEncryptSevSnpIsEnabled ()) {
- PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSevSnp);
+ CCGuestAttr = CCAttrAmdSevSnp;
} else if (MemEncryptSevEsIsEnabled ()) {
- PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSevEs);
+ CCGuestAttr = CCAttrAmdSevEs;
} else {
- PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrAmdSev);
+ CCGuestAttr = CCAttrAmdSev;
}
+ if (MemEncryptSevEsDebugVirtualizationIsEnabled ()) {
+ CCGuestAttr |= CCAttrFeatureAmdSevEsDebugVirtualization;
+ }
+
+ PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCGuestAttr);
+
ASSERT_RETURN_ERROR (PcdStatus);
}
diff --git a/OvmfPkg/PlatformPei/IntelTdx.c b/OvmfPkg/PlatformPei/IntelTdx.c
index 3d625ca..8aa796b 100644
--- a/OvmfPkg/PlatformPei/IntelTdx.c
+++ b/OvmfPkg/PlatformPei/IntelTdx.c
@@ -40,15 +40,11 @@ IntelTdxInitialize (
return;
}
- TdxHelperBuildGuidHobForTdxMeasurement ();
-
PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrIntelTdx);
ASSERT_RETURN_ERROR (PcdStatus);
PcdStatus = PcdSet64S (PcdTdxSharedBitMask, TdSharedPageMask ());
ASSERT_RETURN_ERROR (PcdStatus);
- PcdStatus = PcdSetBoolS (PcdSetNxForStack, TRUE);
- ASSERT_RETURN_ERROR (PcdStatus);
#endif
}
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 0114529..dc81ce9 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -38,6 +38,7 @@
#include <IndustryStandard/QemuCpuHotplug.h>
#include <Library/MemEncryptSevLib.h>
#include <OvmfPlatforms.h>
+#include <Library/TdxHelperLib.h>
#include "Platform.h"
#include "PlatformId.h"
@@ -311,6 +312,10 @@ InitializePlatform (
DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));
PlatformInfoHob = BuildPlatformInfoHob ();
+ if (TdIsEnabled ()) {
+ TdxHelperBuildGuidHobForTdxMeasurement ();
+ }
+
PlatformInfoHob->SmmSmramRequire = FeaturePcdGet (PcdSmmSmramRequire);
PlatformInfoHob->SevEsIsEnabled = MemEncryptSevEsIsEnabled ();
PlatformInfoHob->PcdPciMmio64Size = PcdGet64 (PcdPciMmio64Size);
diff --git a/OvmfPkg/QemuVideoDxe/Initialize.c b/OvmfPkg/QemuVideoDxe/Initialize.c
index 050ae87..2d1f506 100644
--- a/OvmfPkg/QemuVideoDxe/Initialize.c
+++ b/OvmfPkg/QemuVideoDxe/Initialize.c
@@ -293,6 +293,8 @@ QemuVideoBochsEdid (
)
{
EFI_STATUS Status;
+ UINT32 X;
+ UINT32 Y;
if (Private->Variant != QEMU_VIDEO_BOCHS_MMIO) {
return;
@@ -344,16 +346,24 @@ QemuVideoBochsEdid (
return;
}
- *XRes = Private->Edid[56] | ((Private->Edid[58] & 0xf0) << 4);
- *YRes = Private->Edid[59] | ((Private->Edid[61] & 0xf0) << 4);
+ X = Private->Edid[56] | ((Private->Edid[58] & 0xf0) << 4);
+ Y = Private->Edid[59] | ((Private->Edid[61] & 0xf0) << 4);
DEBUG ((
DEBUG_INFO,
"%a: default resolution: %dx%d\n",
__func__,
- *XRes,
- *YRes
+ X,
+ Y
));
+ if ((X < 640) || (Y < 480)) {
+ /* ignore hint, GraphicsConsoleDxe needs 640x480 or larger */
+ return;
+ }
+
+ *XRes = X;
+ *YRes = Y;
+
if (PcdGet8 (PcdVideoResolutionSource) == 0) {
Status = PcdSet32S (PcdVideoHorizontalResolution, *XRes);
ASSERT_RETURN_ERROR (Status);
diff --git a/OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm b/OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm
index 2511073..09e9cf9 100644
--- a/OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm
+++ b/OvmfPkg/ResetVector/X64/OvmfSevMetadata.asm
@@ -76,6 +76,12 @@ SvsmCaa:
DD SVSM_CAA_SIZE
DD OVMF_SECTION_TYPE_SVSM_CAA
+; Region need to be pre-validated by the hypervisor
+PreValidate3:
+ DD SNP_SEC_MEM_BASE_DESC_3
+ DD SNP_SEC_MEM_SIZE_DESC_3
+ DD OVMF_SECTION_TYPE_SNP_SEC_MEM
+
%if (SEV_SNP_KERNEL_HASHES_BASE > 0)
; Kernel hashes for measured direct boot, or zero page if
; there are no kernel hashes / SEV secrets
@@ -85,10 +91,5 @@ SevSnpKernelHashes:
DD OVMF_SECTION_TYPE_KERNEL_HASHES
%endif
-; Region need to be pre-validated by the hypervisor
-PreValidate3:
- DD SNP_SEC_MEM_BASE_DESC_3
- DD SNP_SEC_MEM_SIZE_DESC_3
- DD OVMF_SECTION_TYPE_SNP_SEC_MEM
OvmfSevGuidedStructureEnd:
ALIGN 16
diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
index b8338d2..b521570 100644
--- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
+++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc
@@ -71,15 +71,10 @@
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
# Networking Requirements
-!include NetworkPkg/NetworkLibs.dsc.inc
!if $(NETWORK_TLS_ENABLE) == TRUE
TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
!endif
-
- # Add support for GCC stack protector
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
# RISC-V Architectural Libraries
CpuExceptionHandlerLib|UefiCpuPkg/Library/BaseRiscV64CpuExceptionHandlerLib/BaseRiscV64CpuExceptionHandlerLib.inf
RiscVSbiLib|MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
@@ -156,6 +151,9 @@
PrePiHobListPointerLib|OvmfPkg/RiscVVirt/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+ # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.DXE_CORE]
PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
@@ -203,7 +201,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
[PcdsFixedAtBuild.common]
- gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride|0xFFFFFFFFFFFFFFF8
+ gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride|0xFFFFFFFFFFFFFFF0
gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|0
diff --git a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
index e0ed6fb..63d8965 100644
--- a/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
+++ b/OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc
@@ -217,11 +217,13 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
+!if $(NETWORK_ENABLE) == TRUE
#
# IPv4 and IPv6 PXE Boot support.
#
gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01
gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01
+!endif
#
# TPM2 support
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index c1c08a9..d13a948 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -764,6 +764,21 @@ SecMtrrSetup (
return;
}
+ #if defined (TDX_GUEST_SUPPORTED)
+ if (CcProbe () == CcGuestTypeIntelTdx) {
+ //
+ // According to TDX Spec, the default MTRR type is enforced to WB
+ // and CR0.CD is enforced to 0.
+ // The TD guest has to disable MTRR otherwise it tries to
+ // program MTRRs to disable caching. CR0.CD=1 results in the
+ // unexpected #VE.
+ //
+ DEBUG ((DEBUG_INFO, "%a: Skip TD-Guest\n", __func__));
+ return;
+ }
+
+ #endif
+
DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE);
DefType.Bits.Type = MSR_IA32_MTRR_CACHE_WRITE_BACK;
DefType.Bits.E = 1; /* enable */
diff --git a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c
index 0a23bff..6d2de0e 100644
--- a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c
+++ b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.c
@@ -2160,11 +2160,17 @@ OnReadyToBoot (
//
// 2. Draw a line between pre-boot env and entering post-boot env.
- // PCR[7] (is RTMR[0]) is already done.
//
- Status = MeasureSeparatorEvent (1);
+ // According to UEFI Spec 2.10 Section 38.4.1 the mapping between MrIndex and Intel
+ // TDX Measurement Register is:
+ // MrIndex 0 <--> MRTD
+ // MrIndex 1-3 <--> RTMR[0-2]
+ // RTMR[0] (i.e. MrIndex 1) is already done. So SepartorEvent shall be extended to
+ // RTMR[1] (i.e. MrIndex 2) as well.
+ //
+ Status = MeasureSeparatorEvent (CC_MR_INDEX_2_RTMR1);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Separator Event not Measured. Error!\n"));
+ DEBUG ((DEBUG_ERROR, "Separator Event not Measured to RTMR[1]. Error!\n"));
}
//
diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
index 74ed52f..f881cde 100644
--- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
+++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
@@ -13,6 +13,7 @@
Copyright (C) 2012, Red Hat, Inc.
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
+ Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -240,7 +241,7 @@ SynchronousRequest (
)
{
UINT32 BlockSize;
- volatile VIRTIO_BLK_REQ Request;
+ volatile VIRTIO_BLK_REQ *Request;
volatile UINT8 *HostStatus;
VOID *HostStatusBuffer;
DESC_INDICES Indices;
@@ -273,15 +274,20 @@ SynchronousRequest (
//
ASSERT (BufferSize % BlockSize == 0);
+ Request = AllocateZeroPool (sizeof (*Request));
+ if (Request == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
//
// Prepare virtio-blk request header, setting zero size for flush.
// IO Priority is homogeneously 0.
//
- Request.Type = RequestIsWrite ?
- (BufferSize == 0 ? VIRTIO_BLK_T_FLUSH : VIRTIO_BLK_T_OUT) :
- VIRTIO_BLK_T_IN;
- Request.IoPrio = 0;
- Request.Sector = MultU64x32 (Lba, BlockSize / 512);
+ Request->Type = RequestIsWrite ?
+ (BufferSize == 0 ? VIRTIO_BLK_T_FLUSH : VIRTIO_BLK_T_OUT) :
+ VIRTIO_BLK_T_IN;
+ Request->IoPrio = 0;
+ Request->Sector = MultU64x32 (Lba, BlockSize / 512);
//
// Host status is bi-directional (we preset with a value and expect the
@@ -294,7 +300,8 @@ SynchronousRequest (
&HostStatusBuffer
);
if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
+ Status = EFI_DEVICE_ERROR;
+ goto FreeBlkRequest;
}
HostStatus = HostStatusBuffer;
@@ -306,8 +313,8 @@ SynchronousRequest (
Status = VirtioMapAllBytesInSharedBuffer (
Dev->VirtIo,
VirtioOperationBusMasterRead,
- (VOID *)&Request,
- sizeof Request,
+ (VOID *)Request,
+ sizeof (*Request),
&RequestDeviceAddress,
&RequestMapping
);
@@ -372,7 +379,7 @@ SynchronousRequest (
VirtioAppendDesc (
&Dev->Ring,
RequestDeviceAddress,
- sizeof Request,
+ sizeof (*Request),
VRING_DESC_F_NEXT,
&Indices
);
@@ -454,6 +461,9 @@ FreeHostStatusBuffer:
HostStatusBuffer
);
+FreeBlkRequest:
+ FreePool ((VOID *)Request);
+
return Status;
}
diff --git a/OvmfPkg/VirtioGpuDxe/Gop.c b/OvmfPkg/VirtioGpuDxe/Gop.c
index f64dfce..d767114 100644
--- a/OvmfPkg/VirtioGpuDxe/Gop.c
+++ b/OvmfPkg/VirtioGpuDxe/Gop.c
@@ -265,7 +265,8 @@ GopInitialize (
// query host for display resolution
//
GopNativeResolution (VgpuGop, &XRes, &YRes);
- if ((XRes == 0) || (YRes == 0)) {
+ if ((XRes < 640) || (YRes < 480)) {
+ /* ignore hint, GraphicsConsoleDxe needs 640x480 or larger */
return;
}
diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
index 3705f5f..ac8c576 100644
--- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
+++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
@@ -28,6 +28,7 @@
Copyright (C) 2012, Red Hat, Inc.
Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Inc, All rights reserved.<BR>
+ Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -430,7 +431,7 @@ VirtioScsiPassThru (
VSCSI_DEV *Dev;
UINT16 TargetValue;
EFI_STATUS Status;
- volatile VIRTIO_SCSI_REQ Request;
+ volatile VIRTIO_SCSI_REQ *Request;
volatile VIRTIO_SCSI_RESP *Response;
VOID *ResponseBuffer;
DESC_INDICES Indices;
@@ -455,7 +456,10 @@ VirtioScsiPassThru (
InDataDeviceAddress = 0;
OutDataDeviceAddress = 0;
- ZeroMem ((VOID *)&Request, sizeof (Request));
+ Request = AllocateZeroPool (sizeof (*Request));
+ if (Request == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
Dev = VIRTIO_SCSI_FROM_PASS_THRU (This);
CopyMem (&TargetValue, Target, sizeof TargetValue);
@@ -464,9 +468,9 @@ VirtioScsiPassThru (
OutDataBufferIsMapped = FALSE;
InDataNumPages = 0;
- Status = PopulateRequest (Dev, TargetValue, Lun, Packet, &Request);
+ Status = PopulateRequest (Dev, TargetValue, Lun, Packet, Request);
if (EFI_ERROR (Status)) {
- return Status;
+ goto FreeScsiRequest;
}
//
@@ -475,13 +479,14 @@ VirtioScsiPassThru (
Status = VirtioMapAllBytesInSharedBuffer (
Dev->VirtIo,
VirtioOperationBusMasterRead,
- (VOID *)&Request,
- sizeof Request,
+ (VOID *)Request,
+ sizeof (*Request),
&RequestDeviceAddress,
&RequestMapping
);
if (EFI_ERROR (Status)) {
- return ReportHostAdapterError (Packet);
+ Status = ReportHostAdapterError (Packet);
+ goto FreeScsiRequest;
}
//
@@ -605,7 +610,7 @@ VirtioScsiPassThru (
VirtioAppendDesc (
&Dev->Ring,
RequestDeviceAddress,
- sizeof Request,
+ sizeof (*Request),
VRING_DESC_F_NEXT,
&Indices
);
@@ -702,6 +707,9 @@ FreeInDataBuffer:
UnmapRequestBuffer:
Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, RequestMapping);
+FreeScsiRequest:
+ FreePool ((VOID *)Request);
+
return Status;
}
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
index 7f00eef..a54fd55 100644
--- a/OvmfPkg/XenPlatformPei/Xen.c
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -128,9 +128,6 @@ EFI_STATUS
XenConnect (
)
{
- UINT32 Index;
- UINT32 TransferReg;
- UINT32 TransferPages;
UINT32 XenVersion;
EFI_XEN_OVMF_INFO *Info;
CHAR8 Sig[sizeof (Info->Signature) + 1];
@@ -140,24 +137,6 @@ XenConnect (
ASSERT (mXenLeaf != 0);
//
- // Prepare HyperPages to be able to make hypercalls
- //
-
- AsmCpuid (mXenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
- mXenInfo.HyperPages = AllocatePages (TransferPages);
- if (!mXenInfo.HyperPages) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- for (Index = 0; Index < TransferPages; Index++) {
- AsmWriteMsr64 (
- TransferReg,
- (UINTN)mXenInfo.HyperPages +
- (Index << EFI_PAGE_SHIFT) + Index
- );
- }
-
- //
// Find out the Xen version
//
@@ -283,7 +262,7 @@ XenPvhDetected (
//
// This function should only be used after XenConnect
//
- ASSERT (mXenInfo.HyperPages != NULL);
+ ASSERT (mXenInfo.VersionMajor);
return mXenHvmloaderInfo == NULL;
}
diff --git a/PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml b/PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml
index 61f3fd7..278bb439 100644
--- a/PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml
+++ b/PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml
@@ -6,6 +6,9 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "PcAtChipsetPkg.dsc",
+ },
## options defined .pytool/Plugin/LicenseCheck
"LicenseCheck": {
"IgnoreFiles": []
diff --git a/PcAtChipsetPkg/PcAtChipsetPkg.dsc b/PcAtChipsetPkg/PcAtChipsetPkg.dsc
index 2f02ecf..73f8198 100644
--- a/PcAtChipsetPkg/PcAtChipsetPkg.dsc
+++ b/PcAtChipsetPkg/PcAtChipsetPkg.dsc
@@ -45,6 +45,10 @@
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[Components]
PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf
PcAtChipsetPkg/Bus/Pci/IdeControllerDxe/IdeControllerDxe.inf
diff --git a/PrmPkg/PrmConfigDxe/PrmConfigDxe.c b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
index 550ee64..7a3913e 100644
--- a/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
+++ b/PrmPkg/PrmConfigDxe/PrmConfigDxe.c
@@ -152,10 +152,15 @@ SetRuntimeMemoryRangeAttributes (
continue;
}
+ // The memory space descriptor access attributes are not accurate. Don't pass
+ // in access attributes so SetMemorySpaceAttributes() doesn't update them.
+ // EFI_MEMORY_RUNTIME is not a CPU arch attribute, so calling
+ // SetMemorySpaceAttributes() with only it set will not clear existing page table
+ // attributes for this region, such as EFI_MEMORY_XP
Status = gDS->SetMemorySpaceAttributes (
RuntimeMmioRanges->Range[Index].PhysicalBaseAddress,
(UINT64)RuntimeMmioRanges->Range[Index].Length,
- Descriptor.Attributes | EFI_MEMORY_RUNTIME
+ EFI_MEMORY_RUNTIME
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
diff --git a/PrmPkg/PrmPkg.ci.yaml b/PrmPkg/PrmPkg.ci.yaml
index b4b5aad..a55abd2 100644
--- a/PrmPkg/PrmPkg.ci.yaml
+++ b/PrmPkg/PrmPkg.ci.yaml
@@ -49,7 +49,6 @@
## options defined .pytool/Plugin/DependencyCheck
"DependencyCheck": {
"AcceptableDependencies": [
- "ArmPkg/ArmPkg.dec",
"MdeModulePkg/MdeModulePkg.dec",
"MdePkg/MdePkg.dec",
"PrmPkg/PrmPkg.dec",
diff --git a/PrmPkg/PrmPkg.dsc b/PrmPkg/PrmPkg.dsc
index 6771005..8eeb393 100644
--- a/PrmPkg/PrmPkg.dsc
+++ b/PrmPkg/PrmPkg.dsc
@@ -18,6 +18,8 @@
DEFINE PLATFORM_PACKAGE = $(PLATFORM_NAME)Pkg
+!include MdePkg/MdeLibs.dsc.inc
+
[LibraryClasses.common]
#
# EDK II Packages
@@ -38,13 +40,13 @@
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.IA32, LibraryClasses.X64]
MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
-[LibraryClasses.AARCH64]
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
#
# EDK II Packages
@@ -148,12 +150,6 @@
#
$(PLATFORM_PACKAGE)/Samples/PrmSampleHardwareAccessModule/PrmSampleHardwareAccessModule.inf
-[Components.AARCH64]
- ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- # Add support for GCC stack protector
- MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
[BuildOptions]
# Force deprecated interfaces off
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/RedfishPkg/Include/Protocol/EdkIIRedfishCredential2.h b/RedfishPkg/Include/Protocol/EdkIIRedfishCredential2.h
new file mode 100644
index 0000000..b2b3799
--- /dev/null
+++ b/RedfishPkg/Include/Protocol/EdkIIRedfishCredential2.h
@@ -0,0 +1,128 @@
+/** @file
+ This file defines the EDKII_REDFISH_CREDENTIAL2_PROTOCOL interface.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+ (C) Copyright 2024 American Megatrends International LLC<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_CREDENTIAL2_H_
+#define EDKII_REDFISH_CREDENTIAL2_H_
+
+#include <Protocol/EdkIIRedfishCredential.h>
+#include <RedfishServiceData.h>
+
+typedef struct _EDKII_REDFISH_CREDENTIAL2_PROTOCOL EDKII_REDFISH_CREDENTIAL2_PROTOCOL;
+
+#define REDFISH_CREDENTIAL_PROTOCOL_REVISION 0x00010000
+
+#define EDKII_REDFISH_CREDENTIAL2_PROTOCOL_GUID \
+ { \
+ 0x936b81dc, 0x348c, 0x42e3, { 0x9e, 0x82, 0x2, 0x91, 0x4f, 0xd3, 0x48, 0x86 } \
+ }
+
+/**
+ 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_CREDENTIAL2_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_CREDENTIAL2_PROTOCOL_GET_AUTH_INFO)(
+ IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
+ OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod,
+ OUT CHAR8 **UserId,
+ OUT CHAR8 **Password
+ );
+
+/**
+ Notifies the Redfish service provider to stop providing configuration service to this platform.
+ Deletes the bootstrap account on BMC side, so it will not be used by any other driver.
+
+ This function should be called when the platfrom is about to leave the safe environment.
+ It will delete the bootstrap account sending DELETE request to BMC.
+ 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_CREDENTIAL2_PROTOCOL instance.
+ @param[in] ServiceStopType Reason of stopping Redfish service.
+
+ @retval EFI_SUCCESS Service has been stopped successfully.
+ @retval EFI_INVALID_PARAMETER This is NULL.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_CREDENTIAL2_PROTOCOL_STOP_SERVICE)(
+ IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
+ IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType
+ );
+
+/**
+ Register Redfish service instance so protocol knows that some module uses bootstrap account .
+
+ @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance.
+ @param[in] RedfishService Redfish service instance to register.
+
+ @retval EFI_SUCCESS This Redfish service instance has been registered successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_CREDENTIAL2_PROTOCOL_REGISTER_REDFISH_SERVICE)(
+ IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
+ IN REDFISH_SERVICE RedfishService
+ );
+
+/**
+ Unregister Redfish service instance and delete the bootstrap account
+ when all registered services unregistered.
+
+ @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance.
+ @param[in] RedfishService Redfish service instance to unregister.
+
+ @retval EFI_SUCCESS This Redfish service instance has been unregistered successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_CREDENTIAL2_PROTOCOL_UNREGISTER_REDFISH_SERVICE)(
+ IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
+ IN REDFISH_SERVICE RedfishService
+ );
+
+struct _EDKII_REDFISH_CREDENTIAL2_PROTOCOL {
+ UINT64 Revision;
+ EDKII_REDFISH_CREDENTIAL2_PROTOCOL_GET_AUTH_INFO GetAuthInfo;
+ EDKII_REDFISH_CREDENTIAL2_PROTOCOL_STOP_SERVICE StopService;
+ EDKII_REDFISH_CREDENTIAL2_PROTOCOL_REGISTER_REDFISH_SERVICE RegisterRedfishService;
+ EDKII_REDFISH_CREDENTIAL2_PROTOCOL_UNREGISTER_REDFISH_SERVICE UnregisterRedfishService;
+};
+
+extern EFI_GUID gEdkIIRedfishCredential2ProtocolGuid;
+
+#endif
diff --git a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
index a1d5592..9e28c4b 100644
--- a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
+++ b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
@@ -13,6 +13,11 @@
typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL;
+//
+// Redfish Platform Config Protocol interface version.
+//
+#define REDFISH_PLATFORM_CONFIG_VERSION 0x00010000
+
///
/// Definition of EDKII_REDFISH_TYPE_VALUE
///
diff --git a/RedfishPkg/Include/RedfishCommon.h b/RedfishPkg/Include/RedfishCommon.h
new file mode 100644
index 0000000..18244e9
--- /dev/null
+++ b/RedfishPkg/Include/RedfishCommon.h
@@ -0,0 +1,17 @@
+/** @file
+ This header file defines common macros for the use in RedfishPkg.
+
+ Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef REDFISH_COMMON_H_
+#define REDFISH_COMMON_H_
+
+#ifndef IS_EMPTY_STRING
+#define IS_EMPTY_STRING(a) ((a) == NULL || (a)[0] == '\0')
+#endif
+
+#endif
diff --git a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c
index c73e76d..5c3f8f9 100644
--- a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c
+++ b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.c
@@ -23,7 +23,7 @@ static LIST_ENTRY mBmcIpmiLan;
Bootstrapping.
@retval TRUE Yes, it is supported.
- TRUE No, it is not supported.
+ FALSE No, it is not supported.
**/
BOOLEAN
@@ -31,47 +31,53 @@ ProbeRedfishCredentialBootstrap (
VOID
)
{
- EFI_STATUS Status;
- IPMI_BOOTSTRAP_CREDENTIALS_COMMAND_DATA CommandData;
- IPMI_BOOTSTRAP_CREDENTIALS_RESULT_RESPONSE ResponseData;
- UINT32 ResponseSize;
- BOOLEAN ReturnBool;
+ EDKII_REDFISH_AUTH_METHOD AuthMethod;
+ EDKII_REDFISH_CREDENTIAL2_PROTOCOL *CredentialProtocol;
+ CHAR8 *UserName;
+ CHAR8 *Password;
+ BOOLEAN ReturnBool;
+ EFI_STATUS Status;
DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry\n", __func__));
+ ReturnBool = FALSE;
//
- // IPMI callout to NetFn 2C, command 02
- // Request data:
- // Byte 1: REDFISH_IPMI_GROUP_EXTENSION
- // Byte 2: DisableBootstrapControl
+ // Locate HII credential protocol.
//
- CommandData.GroupExtensionId = REDFISH_IPMI_GROUP_EXTENSION;
- CommandData.DisableBootstrapControl = REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_ENABLE;
- ResponseData.CompletionCode = IPMI_COMP_CODE_UNSPECIFIED;
- ResponseSize = sizeof (ResponseData);
- //
- // Response data: Ignored.
- //
- Status = IpmiSubmitCommand (
- IPMI_NETFN_GROUP_EXT,
- REDFISH_IPMI_GET_BOOTSTRAP_CREDENTIALS_CMD,
- (UINT8 *)&CommandData,
- sizeof (CommandData),
- (UINT8 *)&ResponseData,
- &ResponseSize
- );
- if (!EFI_ERROR (Status) &&
- ((ResponseData.CompletionCode == IPMI_COMP_CODE_NORMAL) ||
- (ResponseData.CompletionCode == REDFISH_IPMI_COMP_CODE_BOOTSTRAP_CREDENTIAL_DISABLED)
- ))
- {
- DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Redfish Credential Bootstrapping is supported\n"));
+ Status = gBS->LocateProtocol (
+ &gEdkIIRedfishCredential2ProtocolGuid,
+ NULL,
+ (VOID **)&CredentialProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return FALSE;
+ }
+
+ Status = CredentialProtocol->GetAuthInfo (
+ CredentialProtocol,
+ &AuthMethod,
+ &UserName,
+ &Password
+ );
+ if (!EFI_ERROR (Status)) {
+ ZeroMem (Password, AsciiStrSize (Password));
+ FreePool (Password);
+ ZeroMem (UserName, AsciiStrSize (UserName));
+ FreePool (UserName);
ReturnBool = TRUE;
} else {
- DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Redfish Credential Bootstrapping is not supported\n"));
- ReturnBool = FALSE;
+ if (Status == EFI_ACCESS_DENIED) {
+ // bootstrap credential support was disabled
+ ReturnBool = TRUE;
+ }
}
+ DEBUG ((
+ DEBUG_REDFISH_HOST_INTERFACE,
+ " Redfish Credential Bootstrapping is %a\n",
+ ReturnBool ? "supported" : "not supported"
+ ));
return ReturnBool;
}
@@ -1201,8 +1207,9 @@ CheckBmcUsbNic (
DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry, the registration key - 0x%08x.\n", __func__, Registration));
- Handle = NULL;
- Status = EFI_SUCCESS;
+ Handle = NULL;
+ HandleBuffer = NULL;
+ Status = EFI_SUCCESS;
do {
BufferSize = 0;
diff --git a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.h b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.h
index 669c304..96b2bdf 100644
--- a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.h
+++ b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.h
@@ -21,7 +21,6 @@
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
-#include <Library/IpmiLib.h>
#include <Library/IpmiCommandLib.h>
#include <Library/RedfishHostInterfaceLib.h>
#include <Library/MemoryAllocationLib.h>
@@ -29,6 +28,7 @@
#include <Library/DevicePathLib.h>
#include <Library/RedfishDebugLib.h>
+#include <Protocol/EdkIIRedfishCredential2.h>
#include <Protocol/SimpleNetwork.h>
#include <Protocol/UsbIo.h>
diff --git a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.inf b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.inf
index 3660249..c379119 100644
--- a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.inf
+++ b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterfaceBmcUsbNicLib.inf
@@ -29,7 +29,6 @@
[LibraryClasses]
BaseMemoryLib
DebugLib
- IpmiLib
IpmiCommandLib
MemoryAllocationLib
UefiLib
@@ -39,6 +38,7 @@
gEfiSimpleNetworkProtocolGuid ## CONSUMED
gEfiUsbIoProtocolGuid ## CONSUMED
gEfiDevicePathProtocolGuid ## CONSUMED
+ gEdkIIRedfishCredential2ProtocolGuid ## CONSUMED
[Pcd]
gEfiRedfishPkgTokenSpaceGuid.PcdRedfishHostName ## CONSUMED
@@ -47,3 +47,4 @@
[Depex]
gIpmiProtocolGuid
+ AND gEdkIIRedfishCredential2ProtocolGuid
diff --git a/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c b/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c
index f8bb51f..694a087 100644
--- a/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c
+++ b/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c
@@ -9,7 +9,7 @@
**/
#include <Uefi.h>
-
+#include <RedfishCommon.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
@@ -17,10 +17,6 @@
#include <Library/RedfishHttpLib.h>
#include <Library/UefiLib.h>
-#ifndef IS_EMPTY_STRING
-#define IS_EMPTY_STRING(a) ((a) == NULL || (a)[0] == '\0')
-#endif
-
#define REDFISH_JSON_STRING_LENGTH 200
#define REDFISH_JSON_OUTPUT_FORMAT (EDKII_JSON_COMPACT | EDKII_JSON_INDENT(2))
#define REDFISH_PRINT_BUFFER_BYTES_PER_ROW 16
diff --git a/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c
index 5e03132..d6498b5 100644
--- a/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c
+++ b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c
@@ -412,7 +412,7 @@ AcquireRedfishServiceOnNetworkInterfaceCallback (
EFI_ERROR (ThisRedfishDiscoveredToken->DiscoverList.RedfishInstances->Status))
{
gBS->CloseEvent (ThisRedfishDiscoveredToken->Event);
- DEBUG ((DEBUG_ERROR, "%a: Free Redfish discovered token - %x.\n", __func__, ThisRedfishDiscoveredToken));
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: Free Redfish discovered token - %x.\n", __func__, ThisRedfishDiscoveredToken));
FreePool (ThisRedfishDiscoveredToken);
}
diff --git a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c
index 91bffa8..23201e1 100644
--- a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c
+++ b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c
@@ -3,6 +3,7 @@
to get the Redfish credential Info and to restrict Redfish access from UEFI side.
(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+ (C) Copyright 2024 American Megatrends International LLC<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -10,10 +11,9 @@
#include <RedfishCredentialDxe.h>
-EDKII_REDFISH_CREDENTIAL_PROTOCOL mRedfishCredentialProtocol = {
- RedfishCredentialGetAuthInfo,
- RedfishCredentialStopService
-};
+#define REDFISH_VERSION_DEFAULT_STRING L"v1"
+
+REDFISH_CREDENTIAL_PRIVATE *mCredentialPrivate = NULL;
/**
Callback function executed when the ExitBootServices event group is signaled.
@@ -52,6 +52,15 @@ RedfishCredentialEndOfDxeEventNotify (
gBS->CloseEvent (Event);
}
+EFI_STATUS
+ReleaseCredentialPrivate (
+ );
+
+EFI_STATUS
+IterateThroughBootstrapAccounts (
+ IN REDFISH_SERVICE RedfishService
+ );
+
/**
Retrieve platform's Redfish authentication information.
@@ -93,7 +102,7 @@ RedfishCredentialGetAuthInfo (
}
/**
- Notify the Redfish service provide to stop provide configuration service to this platform.
+ Notify the Redfish service provider 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
@@ -124,6 +133,668 @@ RedfishCredentialStopService (
}
/**
+ 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_CREDENTIAL2_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
+RedfishCredential2GetAuthInfo (
+ IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
+ 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;
+ }
+
+ if (mCredentialPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
+ return EFI_NOT_STARTED;
+ }
+
+ Status = mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo (
+ &mCredentialPrivate->RedfishCredentialProtocol,
+ AuthMethod,
+ UserId,
+ Password
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to retrieve Redfish credential - %r\n", __func__, Status));
+ }
+
+ return Status;
+}
+
+/**
+ Notifies the Redfish service provider to stop providing configuration service to this platform.
+ Deletes the bootstrap account on BMC side, so it will not be used by any other driver.
+
+ This function should be called when the platfrom is about to leave the safe environment.
+ It will delete the bootstrap account sending DELETE request to BMC.
+ 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_CREDENTIAL2_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
+RedfishCredential2StopService (
+ IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
+ IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_SERVICE_LIST *Instance;
+
+ if (mCredentialPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
+ return EFI_NOT_STARTED;
+ }
+
+ if ((ServiceStopType == ServiceStopTypeExitBootService) ||
+ (ServiceStopType == ServiceStopTypeNone))
+ {
+ // Check PCD and skip the action if platform library is responsible for deleting account
+ // on exit boot service event
+ if (FixedPcdGetBool (PcdRedfishCredentialDeleteAccount)) {
+ if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
+ Instance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
+ IterateThroughBootstrapAccounts (Instance->RedfishService);
+ }
+
+ ReleaseCredentialPrivate ();
+ }
+ }
+
+ Status = mCredentialPrivate->RedfishCredentialProtocol.StopService (
+ &mCredentialPrivate->RedfishCredentialProtocol,
+ ServiceStopType
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to stop service - %r\n", __func__, Status));
+ }
+
+ return Status;
+}
+
+/**
+ Function sends DELETE request to BMC for the account defined by the target URI.
+
+ @param[in] RedfishService Pointer to Redfish Service to be used
+ for sending DELETE request to BMC.
+ @param[in] TargetUri URI of bootstrap account to send DELETE request to.
+
+**/
+EFI_STATUS
+EFIAPI
+DeleteRedfishBootstrapAccount (
+ IN REDFISH_SERVICE RedfishService,
+ IN CHAR16 *TargetUri
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_RESPONSE RedfishResponse;
+
+ if (mCredentialPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
+ return EFI_NOT_STARTED;
+ }
+
+ if ((RedfishService == NULL) || (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic)) {
+ DEBUG ((DEBUG_ERROR, "%a: Redfish service is not available\n", __func__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Remove bootstrap account at /redfish/v1/AccountService/AccountId
+ //
+ ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE));
+ Status = RedfishHttpDeleteResourceEx (
+ RedfishService,
+ TargetUri,
+ "{}",
+ 2,
+ NULL,
+ &RedfishResponse
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: can not remove bootstrap account at BMC: %r", __func__, Status));
+ DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse);
+ } else {
+ DEBUG (
+ (REDFISH_CREDENTIAL_DEBUG, "%a: bootstrap account: %a is removed from: %s\nURI - %s",
+ __func__, mCredentialPrivate->AccountName, REDFISH_MANAGER_ACCOUNT_COLLECTION_URI, TargetUri)
+ );
+ }
+
+ RedfishHttpFreeResponse (&RedfishResponse);
+
+ return Status;
+}
+
+/**
+ Get the information about specific Account.
+ Checks the User Name and if name matches delete that account
+
+
+ @param[in] RedfishService Pointer to Redfish Service to be used
+ for sending DELETE request to BMC.
+ @param[in] AccountUri URI of bootstrap account to verify.
+
+**/
+BOOLEAN
+ProcessRedfishBootstarpAccount (
+ IN REDFISH_SERVICE RedfishService,
+ IN EFI_STRING AccountUri
+ )
+{
+ EDKII_JSON_VALUE JsonUserName;
+ EDKII_JSON_VALUE JsonValue;
+ EFI_STATUS Status;
+ REDFISH_RESPONSE RedfishResponse;
+ REDFISH_REQUEST RedfishRequest;
+ BOOLEAN Ret;
+
+ if (mCredentialPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
+ return FALSE;
+ }
+
+ if ((RedfishService == NULL) || IS_EMPTY_STRING (AccountUri) ||
+ (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic))
+ {
+ return FALSE;
+ }
+
+ ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE));
+ ZeroMem (&RedfishRequest, sizeof (REDFISH_REQUEST));
+ Status = RedfishHttpGetResource (RedfishService, AccountUri, &RedfishRequest, &RedfishResponse, FALSE);
+ if (EFI_ERROR (Status) || (RedfishResponse.Payload == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a: can not get account from BMC: %r", __func__, Status));
+ DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse);
+ return FALSE;
+ }
+
+ Ret = FALSE;
+ JsonValue = RedfishJsonInPayload (RedfishResponse.Payload);
+ if (JsonValueIsObject (JsonValue)) {
+ JsonUserName = JsonObjectGetValue (JsonValueGetObject (JsonValue), "UserName");
+ if (JsonValueIsString (JsonUserName) && (JsonValueGetAsciiString (JsonUserName) != NULL)) {
+ if (AsciiStrCmp (mCredentialPrivate->AccountName, JsonValueGetAsciiString (JsonUserName)) == 0) {
+ DeleteRedfishBootstrapAccount (RedfishService, AccountUri);
+ Ret = TRUE;
+ }
+ }
+ }
+
+ RedfishHttpFreeResponse (&RedfishResponse);
+ RedfishHttpFreeRequest (&RedfishRequest);
+
+ return Ret;
+}
+
+/**
+ This function returns the string of Redfish service version.
+
+ @param[out] ServiceVersionStr Redfish service string.
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+RedfishGetServiceVersion (
+ OUT CHAR16 **ServiceVersionStr
+ )
+{
+ *ServiceVersionStr = (CHAR16 *)PcdGetPtr (PcdDefaultRedfishVersion);
+ if (*ServiceVersionStr == NULL) {
+ *ServiceVersionStr = REDFISH_VERSION_DEFAULT_STRING;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Iterates through all account in the account collection
+ Get the information about specific Account.
+ Checks the User Name and if name matches delete that account
+
+
+ @param[in] RedfishService Pointer to Redfish Service to be used
+ for sending DELETE request to BMC.
+
+**/
+EFI_STATUS
+IterateThroughBootstrapAccounts (
+ IN REDFISH_SERVICE RedfishService
+ )
+{
+ EFI_STATUS Status;
+ EDKII_JSON_VALUE JsonMembers;
+ EDKII_JSON_VALUE JsonValue;
+ EDKII_JSON_VALUE OdataId;
+ CHAR16 TargetUri[REDFISH_URI_LENGTH];
+ CHAR16 *RedfishVersion;
+ REDFISH_RESPONSE RedfishResponse;
+ REDFISH_REQUEST RedfishRequest;
+ UINTN MembersCount, Index;
+
+ RedfishVersion = NULL;
+ Status = EFI_NOT_FOUND;
+
+ if (mCredentialPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
+ return EFI_NOT_STARTED;
+ }
+
+ if ((RedfishService == NULL) || (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic) ||
+ IS_EMPTY_STRING (mCredentialPrivate->AccountName))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Carving the URI
+ //
+
+ Status = RedfishGetServiceVersion (&RedfishVersion);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: can not get Redfish version\n", __func__));
+ return Status;
+ }
+
+ UnicodeSPrint (
+ TargetUri,
+ (sizeof (CHAR16) * REDFISH_URI_LENGTH),
+ L"/redfish/%s/%s",
+ RedfishVersion,
+ REDFISH_MANAGER_ACCOUNT_COLLECTION_URI
+ );
+
+ DEBUG ((REDFISH_CREDENTIAL_DEBUG, "%a: account collection URI: %s\n", __func__, TargetUri));
+
+ ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE));
+ ZeroMem (&RedfishRequest, sizeof (REDFISH_REQUEST));
+ Status = RedfishHttpGetResource (RedfishService, TargetUri, &RedfishRequest, &RedfishResponse, FALSE);
+ if (EFI_ERROR (Status) || (RedfishResponse.Payload == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a: can not get accounts from BMC: %r\n", __func__, Status));
+ DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse);
+ return Status;
+ }
+
+ JsonValue = RedfishJsonInPayload (RedfishResponse.Payload);
+ if (!JsonValueIsObject (JsonValue)) {
+ Status = EFI_LOAD_ERROR;
+ goto ON_EXIT;
+ }
+
+ JsonMembers = JsonObjectGetValue (JsonValueGetObject (JsonValue), "Members");
+ if (!JsonValueIsArray (JsonMembers)) {
+ Status = EFI_LOAD_ERROR;
+ goto ON_EXIT;
+ }
+
+ Status = EFI_NOT_FOUND;
+
+ MembersCount = JsonArrayCount (JsonValueGetArray (JsonMembers));
+ for (Index = 0; Index < MembersCount; Index++) {
+ JsonValue = JsonArrayGetValue (JsonValueGetArray (JsonMembers), Index);
+ if (!JsonValueIsObject (JsonValue)) {
+ Status = EFI_LOAD_ERROR;
+ goto ON_EXIT;
+ }
+
+ OdataId = JsonObjectGetValue (JsonValueGetObject (JsonValue), "@odata.id");
+ if (!JsonValueIsString (OdataId) || (JsonValueGetAsciiString (OdataId) == NULL)) {
+ Status = EFI_LOAD_ERROR;
+ goto ON_EXIT;
+ }
+
+ UnicodeSPrint (
+ TargetUri,
+ (sizeof (CHAR16) * REDFISH_URI_LENGTH),
+ L"%a",
+ JsonValueGetAsciiString (OdataId)
+ );
+ DEBUG ((REDFISH_CREDENTIAL_DEBUG, "%a: account URI: %s\n", __func__, TargetUri));
+ // Verify bootstrap account User Name and delete the account if User Name matches
+ if (ProcessRedfishBootstarpAccount (RedfishService, TargetUri)) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+
+ON_EXIT:
+
+ RedfishHttpFreeResponse (&RedfishResponse);
+ RedfishHttpFreeRequest (&RedfishRequest);
+
+ return Status;
+}
+
+/**
+ Retrieve platform's Redfish authentication information.
+
+ This functions returns the Redfish authentication method together with the user Id.
+ For AuthMethodNone, UserId will point to NULL which means authentication
+ is not required to access the Redfish service.
+ Callers are responsible for freeing the returned string storage pointed by UserId.
+
+ @param[out] AuthMethod Type of Redfish authentication method.
+ @param[out] UserId The pointer to store the returned UserId 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
+RedfishGetAuthConfig (
+ OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod,
+ OUT CHAR8 **UserId
+ )
+{
+ EFI_STATUS Status;
+ CHAR8 *Password;
+
+ Password = NULL;
+
+ if ((AuthMethod == NULL) || (UserId == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mCredentialPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
+ return EFI_NOT_STARTED;
+ }
+
+ Status = mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo (
+ &mCredentialPrivate->RedfishCredentialProtocol,
+ AuthMethod,
+ UserId,
+ &Password
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: failed to retrieve Redfish credential - %r\n", __func__, Status));
+ return Status;
+ }
+
+ if (Password != NULL) {
+ ZeroMem (Password, AsciiStrSize (Password));
+ FreePool (Password);
+ }
+
+ return Status;
+}
+
+/**
+ This function clears Redfish service internal list.
+
+ @retval EFI_SUCCESS Redfish service is deleted from list successfully.
+ @retval Others Fail to remove the entry
+
+**/
+EFI_STATUS
+ClearRedfishServiceList (
+ )
+{
+ REDFISH_SERVICE_LIST *Instance;
+ REDFISH_SERVICE_LIST *NextInstance;
+
+ if (mCredentialPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
+ return EFI_NOT_STARTED;
+ }
+
+ if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
+ //
+ // Free memory of REDFISH_SERVICE_LIST instance.
+ //
+ Instance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
+ do {
+ NextInstance = NULL;
+ if (!IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &Instance->NextInstance)) {
+ NextInstance = (REDFISH_SERVICE_LIST *)GetNextNode (
+ &mCredentialPrivate->RedfishServiceList,
+ &Instance->NextInstance
+ );
+ }
+
+ RemoveEntryList (&Instance->NextInstance);
+ FreePool ((VOID *)Instance);
+ Instance = NextInstance;
+ } while (Instance != NULL);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The function adds a new Redfish service to internal list
+
+ @param[in] RedfishService Pointer to REDFISH_SERVICE to be added to the list.
+
+ @retval EFI_SUCCESS Redfish service is added to list successfully.
+ @retval EFI_OUT_OF_RESOURCES Out of resources error.
+**/
+EFI_STATUS
+AddRedfishServiceToList (
+ IN REDFISH_SERVICE RedfishService
+ )
+{
+ BOOLEAN ServiceFound;
+ REDFISH_SERVICE_LIST *RedfishServiceInstance;
+
+ RedfishServiceInstance = NULL;
+ ServiceFound = FALSE;
+
+ if (mCredentialPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
+ return EFI_NOT_STARTED;
+ }
+
+ if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
+ RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
+ do {
+ if (RedfishServiceInstance->RedfishService == RedfishService) {
+ ServiceFound = TRUE;
+ break;
+ }
+
+ if (IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance)) {
+ break;
+ }
+
+ RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetNextNode (
+ &mCredentialPrivate->RedfishServiceList,
+ &RedfishServiceInstance->NextInstance
+ );
+ } while (TRUE);
+ }
+
+ if (!ServiceFound) {
+ RedfishServiceInstance = (REDFISH_SERVICE_LIST *)AllocateZeroPool (sizeof (REDFISH_SERVICE_LIST));
+ if (RedfishServiceInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ RedfishServiceInstance->RedfishService = RedfishService;
+ InsertTailList (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function deletes Redfish service from internal list.
+
+ @param[in] RedfishService Pointer to REDFISH_SERVICE to be delete from the list.
+
+ @retval EFI_SUCCESS Redfish service is deleted from list successfully.
+ @retval Others Fail to remove the entry
+
+**/
+EFI_STATUS
+DeleteRedfishServiceFromList (
+ IN REDFISH_SERVICE RedfishService
+ )
+{
+ REDFISH_SERVICE_LIST *RedfishServiceInstance;
+
+ if (mCredentialPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
+ return EFI_NOT_STARTED;
+ }
+
+ if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
+ RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
+ do {
+ if (RedfishServiceInstance->RedfishService == RedfishService) {
+ RemoveEntryList (&RedfishServiceInstance->NextInstance);
+ FreePool (RedfishServiceInstance);
+ return EFI_SUCCESS;
+ }
+
+ if (IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance)) {
+ break;
+ }
+
+ RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetNextNode (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance);
+ } while (TRUE);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Register Redfish service instance so protocol knows that some module uses bootstrap account.
+
+ @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
+ @param[in] RedfishService Redfish service instance to register.
+
+ @retval EFI_SUCCESS This Redfish service instance has been registered successfully.
+ @retval Others Fail to register Redfish Service
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishCredential2RegisterService (
+ IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
+ IN REDFISH_SERVICE RedfishService
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ if (mCredentialPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
+ return EFI_NOT_STARTED;
+ }
+
+ // Check if AuthMethod has been initialized yet
+ if (mCredentialPrivate->AuthMethod == AuthMethodMax) {
+ Status = RedfishGetAuthConfig (
+ &mCredentialPrivate->AuthMethod,
+ &mCredentialPrivate->AccountName
+ );
+ }
+
+ // Bootstrap account should be deleted only if Basic Authentication is used.
+ if (!EFI_ERROR (Status) && (mCredentialPrivate->AuthMethod == AuthMethodHttpBasic)) {
+ Status = AddRedfishServiceToList (RedfishService);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to register Redfish service - %r\n", __func__, Status));
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Unregister Redfish service instance and delete the bootstrap account
+ when all registered services unregistered.
+
+ @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
+ @param[in] RedfishService Redfish service instance to unregister.
+
+ @retval EFI_SUCCESS This Redfish service instance has been unregistered successfully.
+ @retval Others Fail to unregister Redfish Service
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishCredential2UnregisterService (
+ IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
+ IN REDFISH_SERVICE RedfishService
+ )
+{
+ EFI_STATUS Status;
+
+ // Bootstrap account should be deleted only if Basic Authentication is used.
+ if (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic) {
+ return EFI_SUCCESS;
+ }
+
+ // Delete Redfish Service from the registered list
+ Status = DeleteRedfishServiceFromList (RedfishService);
+ // Check if registered list is empty
+ if (IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
+ // Iterate through all accounts in the account collection and delete the bootstrap account
+ Status = IterateThroughBootstrapAccounts (RedfishService);
+ if (!EFI_ERROR (Status)) {
+ if (mCredentialPrivate->AccountName != NULL) {
+ ZeroMem (mCredentialPrivate->AccountName, AsciiStrSize (mCredentialPrivate->AccountName));
+ FreePool (mCredentialPrivate->AccountName);
+ mCredentialPrivate->AccountName = NULL;
+ }
+
+ mCredentialPrivate->AuthMethod = AuthMethodMax;
+ Status = mCredentialPrivate->RedfishCredentialProtocol.StopService (
+ &mCredentialPrivate->RedfishCredentialProtocol,
+ ServiceStopTypeNone
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to stop service - %r\n", __func__, Status));
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
Main entry for this driver.
@param ImageHandle Image handle this driver.
@@ -140,19 +811,33 @@ RedfishCredentialDxeDriverEntryPoint (
)
{
EFI_STATUS Status;
- EFI_HANDLE Handle;
- EFI_EVENT EndOfDxeEvent;
- EFI_EVENT ExitBootServiceEvent;
- Handle = NULL;
+ mCredentialPrivate = (REDFISH_CREDENTIAL_PRIVATE *)AllocateZeroPool (sizeof (REDFISH_CREDENTIAL_PRIVATE));
+ if (mCredentialPrivate == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mCredentialPrivate->AuthMethod = AuthMethodMax;
+ InitializeListHead (&mCredentialPrivate->RedfishServiceList);
+
+ mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo = RedfishCredentialGetAuthInfo;
+ mCredentialPrivate->RedfishCredentialProtocol.StopService = RedfishCredentialStopService;
+
+ mCredentialPrivate->RedfishCredential2Protocol.Revision = REDFISH_CREDENTIAL_PROTOCOL_REVISION;
+ mCredentialPrivate->RedfishCredential2Protocol.GetAuthInfo = RedfishCredential2GetAuthInfo;
+ mCredentialPrivate->RedfishCredential2Protocol.StopService = RedfishCredential2StopService;
+ mCredentialPrivate->RedfishCredential2Protocol.RegisterRedfishService = RedfishCredential2RegisterService;
+ mCredentialPrivate->RedfishCredential2Protocol.UnregisterRedfishService = RedfishCredential2UnregisterService;
//
// Install the RedfishCredentialProtocol onto Handle.
//
Status = gBS->InstallMultipleProtocolInterfaces (
- &Handle,
+ &mCredentialPrivate->Handle,
&gEdkIIRedfishCredentialProtocolGuid,
- &mRedfishCredentialProtocol,
+ &mCredentialPrivate->RedfishCredentialProtocol,
+ &gEdkIIRedfishCredential2ProtocolGuid,
+ &mCredentialPrivate->RedfishCredential2Protocol,
NULL
);
if (EFI_ERROR (Status)) {
@@ -169,9 +854,9 @@ RedfishCredentialDxeDriverEntryPoint (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
RedfishCredentialEndOfDxeEventNotify,
- (VOID *)&mRedfishCredentialProtocol,
+ (VOID *)&mCredentialPrivate->RedfishCredentialProtocol,
&gEfiEndOfDxeEventGroupGuid,
- &EndOfDxeEvent
+ &mCredentialPrivate->EndOfDxeEvent
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
@@ -185,12 +870,13 @@ RedfishCredentialDxeDriverEntryPoint (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
RedfishCredentialExitBootServicesEventNotify,
- (VOID *)&mRedfishCredentialProtocol,
+ (VOID *)&mCredentialPrivate->RedfishCredentialProtocol,
&gEfiEventExitBootServicesGuid,
- &ExitBootServiceEvent
+ &mCredentialPrivate->ExitBootServiceEvent
);
if (EFI_ERROR (Status)) {
- gBS->CloseEvent (EndOfDxeEvent);
+ gBS->CloseEvent (mCredentialPrivate->EndOfDxeEvent);
+ mCredentialPrivate->EndOfDxeEvent = NULL;
goto ON_ERROR;
}
@@ -199,11 +885,87 @@ RedfishCredentialDxeDriverEntryPoint (
ON_ERROR:
gBS->UninstallMultipleProtocolInterfaces (
- Handle,
+ mCredentialPrivate->Handle,
&gEdkIIRedfishCredentialProtocolGuid,
- &mRedfishCredentialProtocol,
+ &mCredentialPrivate->RedfishCredentialProtocol,
+ &gEdkIIRedfishCredential2ProtocolGuid,
+ &mCredentialPrivate->RedfishCredential2Protocol,
NULL
);
+ FreePool (mCredentialPrivate);
+
return Status;
}
+
+/**
+ Releases all resources allocated by the module.
+ Uninstall all the protocols installed in the driver entry point.
+
+ @retval EFI_SUCCESS The resources are released.
+ @retval Others Failed to release the resources.
+
+**/
+EFI_STATUS
+ReleaseCredentialPrivate (
+ )
+{
+ if (mCredentialPrivate != NULL) {
+ if (mCredentialPrivate->AccountName != NULL) {
+ ZeroMem (mCredentialPrivate->AccountName, AsciiStrSize (mCredentialPrivate->AccountName));
+ FreePool (mCredentialPrivate->AccountName);
+ mCredentialPrivate->AccountName = NULL;
+ }
+
+ ClearRedfishServiceList (mCredentialPrivate);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the unload handle for Redfish Credentials module.
+
+ Uninstall all the protocols installed in the driver entry point.
+ Clear all allocated resources.
+
+ @param[in] ImageHandle The drivers' driver image.
+
+ @retval EFI_SUCCESS The image is unloaded.
+ @retval Others Failed to unload the image.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishCredentialDxeDriverUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ if (mCredentialPrivate != NULL) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ mCredentialPrivate->Handle,
+ &gEdkIIRedfishCredentialProtocolGuid,
+ &mCredentialPrivate->RedfishCredentialProtocol,
+ &gEdkIIRedfishCredential2ProtocolGuid,
+ &mCredentialPrivate->RedfishCredential2Protocol,
+ NULL
+ );
+
+ if (mCredentialPrivate->EndOfDxeEvent != NULL) {
+ gBS->CloseEvent (mCredentialPrivate->EndOfDxeEvent);
+ mCredentialPrivate->EndOfDxeEvent = NULL;
+ }
+
+ if (mCredentialPrivate->ExitBootServiceEvent != NULL) {
+ gBS->CloseEvent (mCredentialPrivate->ExitBootServiceEvent);
+ mCredentialPrivate->ExitBootServiceEvent = NULL;
+ }
+
+ ReleaseCredentialPrivate ();
+
+ FreePool (mCredentialPrivate);
+ mCredentialPrivate = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h
index dc765d5..271f884 100644
--- a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h
+++ b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h
@@ -2,6 +2,8 @@
Definition of Redfish Credential DXE driver.
(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+ (C) Copyright 2024 American Megatrends International LLC<BR>
+ Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -10,7 +12,8 @@
#ifndef EDKII_REDFISH_CREDENTIAL_DXE_H_
#define EDKII_REDFISH_CREDENTIAL_DXE_H_
-#include <Protocol/EdkIIRedfishCredential.h>
+#include <RedfishCommon.h>
+#include <Protocol/EdkIIRedfishCredential2.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
@@ -18,60 +21,36 @@
#include <Library/RedfishCredentialLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
-
-/**
- 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
- );
+#include <Library/RedfishHttpLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/RedfishDebugLib.h>
+
+#define REDFISH_CREDENTIAL_DEBUG DEBUG_VERBOSE
+#define REDFISH_MANAGER_ACCOUNT_COLLECTION_URI L"AccountService/Accounts"
+#define REDFISH_URI_LENGTH 128
+
+///
+/// Definition of REDFISH_SERVICE_LIST
+///
+typedef struct {
+ LIST_ENTRY NextInstance;
+ REDFISH_SERVICE RedfishService;
+} REDFISH_SERVICE_LIST;
+
+//
+// Definitions of REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE
+//
+typedef struct {
+ EFI_HANDLE Handle;
+ EFI_EVENT EndOfDxeEvent;
+ EFI_EVENT ExitBootServiceEvent;
+ EDKII_REDFISH_AUTH_METHOD AuthMethod;
+ CHAR8 *AccountName;
+ EDKII_REDFISH_CREDENTIAL_PROTOCOL RedfishCredentialProtocol;
+ EDKII_REDFISH_CREDENTIAL2_PROTOCOL RedfishCredential2Protocol;
+ LIST_ENTRY RedfishServiceList;
+} REDFISH_CREDENTIAL_PRIVATE;
#endif
diff --git a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf
index 707d9a0..c872aa8 100644
--- a/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf
+++ b/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf
@@ -15,6 +15,7 @@
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = RedfishCredentialDxeDriverEntryPoint
+ UNLOAD_IMAGE = RedfishCredentialDxeDriverUnload
#
# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64
@@ -38,14 +39,22 @@
UefiDriverEntryPoint
UefiRuntimeServicesTableLib
UefiLib
+ RedfishHttpLib
+ RedfishDebugLib
+ JsonLib
[Protocols]
gEdkIIRedfishCredentialProtocolGuid ## BY_START
+ gEdkIIRedfishCredential2ProtocolGuid ## BY_START
[Guids]
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
gEfiEventExitBootServicesGuid ## CONSUMES ## Event
+[Pcd]
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishCredentialDeleteAccount
+ gEfiRedfishPkgTokenSpaceGuid.PcdDefaultRedfishVersion
+
[Depex]
TRUE
diff --git a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
index f56ef0e..22fdbb7 100644
--- a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
+++ b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
@@ -570,9 +570,9 @@ DiscoverRedfishHostInterface (
}
if (MacCompareStatus != 0) {
- DEBUG ((DEBUG_ERROR, "%a: MAC address is not matched.\n", __func__));
+ DEBUG ((DEBUG_MANAGEABILITY, "%a: MAC address is not matched.\n", __func__));
DEBUG ((
- DEBUG_ERROR,
+ DEBUG_MANAGEABILITY,
" NetworkInterface: %02x %02x %02x %02x %02x %02x.\n",
Instance->NetworkInterface->MacAddress.Addr[0],
Instance->NetworkInterface->MacAddress.Addr[1],
@@ -582,7 +582,7 @@ DiscoverRedfishHostInterface (
Instance->NetworkInterface->MacAddress.Addr[5]
));
DEBUG ((
- DEBUG_ERROR,
+ DEBUG_MANAGEABILITY,
" Redfish Host interface: %02x %02x %02x %02x %02x %02x.\n",
DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress[0],
DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress[1],
@@ -1559,7 +1559,7 @@ RedfishServiceAcquireService (
FreePool ((VOID *)Instance);
}
- DEBUG ((DEBUG_ERROR, "%a:Something wrong on Redfish service discovery Status1=%r.\n", __func__, Status1));
+ DEBUG ((DEBUG_MANAGEABILITY, "%a:Something wrong on Redfish service discovery Status1=%r.\n", __func__, Status1));
} else {
if (NewInstance) {
InsertTailList (&mRedfishDiscoverList, &Instance->Entry);
@@ -1855,6 +1855,7 @@ BuildupNetworkInterface (
ListCount = (sizeof (mRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL));
NewNetworkInterfaceInstalled = FALSE;
Index = 0;
+ RestExInstance = NULL;
for (Index = 0; Index < ListCount; Index++) {
Status = gBS->OpenProtocol (
diff --git a/RedfishPkg/RedfishHttpDxe/RedfishHttpData.h b/RedfishPkg/RedfishHttpDxe/RedfishHttpData.h
index 6be6101..cb956a4 100644
--- a/RedfishPkg/RedfishHttpDxe/RedfishHttpData.h
+++ b/RedfishPkg/RedfishHttpDxe/RedfishHttpData.h
@@ -77,14 +77,14 @@ typedef struct {
/// Definition of REDFISH_HTTP_CACHE_PRIVATE
///
typedef struct {
- UINT32 Signature;
- EFI_HANDLE ImageHandle;
- BOOLEAN CacheDisabled;
- EFI_EVENT NotifyEvent;
- REDFISH_HTTP_CACHE_LIST CacheList;
- EDKII_REDFISH_HTTP_PROTOCOL Protocol;
- EDKII_REDFISH_CREDENTIAL_PROTOCOL *CredentialProtocol;
- REDFISH_HTTP_RETRY_SETTING RetrySetting;
+ UINT32 Signature;
+ EFI_HANDLE ImageHandle;
+ BOOLEAN CacheDisabled;
+ EFI_EVENT NotifyEvent;
+ REDFISH_HTTP_CACHE_LIST CacheList;
+ EDKII_REDFISH_HTTP_PROTOCOL Protocol;
+ EDKII_REDFISH_CREDENTIAL2_PROTOCOL *CredentialProtocol;
+ REDFISH_HTTP_RETRY_SETTING RetrySetting;
} REDFISH_HTTP_CACHE_PRIVATE;
#define REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS(a) CR (a, REDFISH_HTTP_CACHE_PRIVATE, Protocol, REDFISH_HTTP_DRIVER_SIGNATURE)
diff --git a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c
index 8dcdf55..2de5443 100644
--- a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c
+++ b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.c
@@ -94,6 +94,67 @@ RedfishRetryRequired (
/**
+ This function follows below sections in Redfish specification to
+ check HTTP status code and see if this is success response or not.
+
+ 7.5.2 Modification success responses
+ 7.11 POST (action)
+
+ @param[in] Method HTTP method of this status code.
+ @param[in] StatusCode HTTP status code.
+
+ @retval BOOLEAN Return true when this is success response.
+ Return false when this is not success response.
+
+**/
+BOOLEAN
+RedfishSuccessResponse (
+ IN EFI_HTTP_METHOD Method,
+ IN EFI_HTTP_STATUS_CODE *StatusCode
+ )
+{
+ BOOLEAN SuccessResponse;
+
+ if (StatusCode == NULL) {
+ return TRUE;
+ }
+
+ SuccessResponse = FALSE;
+ switch (Method) {
+ case HttpMethodPost:
+ if ((*StatusCode == HTTP_STATUS_200_OK) ||
+ (*StatusCode == HTTP_STATUS_201_CREATED) ||
+ (*StatusCode == HTTP_STATUS_202_ACCEPTED) ||
+ (*StatusCode == HTTP_STATUS_204_NO_CONTENT))
+ {
+ SuccessResponse = TRUE;
+ }
+
+ break;
+ case HttpMethodPatch:
+ case HttpMethodPut:
+ case HttpMethodDelete:
+ if ((*StatusCode == HTTP_STATUS_200_OK) ||
+ (*StatusCode == HTTP_STATUS_202_ACCEPTED) ||
+ (*StatusCode == HTTP_STATUS_204_NO_CONTENT))
+ {
+ SuccessResponse = TRUE;
+ }
+
+ break;
+ default:
+ //
+ // Return true for unsupported method to prevent false alarm.
+ //
+ SuccessResponse = TRUE;
+ break;
+ }
+
+ return SuccessResponse;
+}
+
+/**
+
Convert Unicode string to ASCII string. It's call responsibility to release returned buffer.
@param[in] UnicodeStr Unicode string to convert.
@@ -313,10 +374,10 @@ RedfishCreateRedfishService (
&Username,
&Password
);
- if (EFI_ERROR (Status) || IS_EMPTY_STRING (Username) || IS_EMPTY_STRING (Password)) {
+ if (EFI_ERROR (Status) || ((AuthMethod != AuthMethodNone) && (IS_EMPTY_STRING (Username) || IS_EMPTY_STRING (Password)))) {
DEBUG ((DEBUG_ERROR, "%a: cannot get authentication information: %r\n", __func__, Status));
goto ON_RELEASE;
- } else {
+ } else if (AuthMethod != AuthMethodNone) {
DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Auth method: 0x%x username: %a password: %a\n", __func__, AuthMethod, Username, Password));
//
@@ -371,6 +432,14 @@ RedfishCreateRedfishService (
NewService = CreateRedfishService (Host, AsciiLocation, EncodedAuthString, NULL, RestEx);
if (NewService == NULL) {
DEBUG ((DEBUG_ERROR, "%a: CreateRedfishService\n", __func__));
+ goto ON_RELEASE;
+ }
+
+ if (Private->CredentialProtocol != NULL) {
+ Status = Private->CredentialProtocol->RegisterRedfishService (Private->CredentialProtocol, NewService);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to register Redfish service - %r\n", __func__, Status));
+ }
}
ON_RELEASE:
@@ -424,17 +493,33 @@ RedfishFreeRedfishService (
IN REDFISH_SERVICE RedfishService
)
{
- REDFISH_SERVICE_PRIVATE *Service;
+ EFI_STATUS Status;
+ REDFISH_SERVICE_PRIVATE *Service;
+ REDFISH_HTTP_CACHE_PRIVATE *Private;
if ((This == NULL) || (RedfishService == NULL)) {
return EFI_INVALID_PARAMETER;
}
+ Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
+
Service = (REDFISH_SERVICE_PRIVATE *)RedfishService;
if (Service->Signature != REDFISH_HTTP_SERVICE_SIGNATURE) {
DEBUG ((DEBUG_ERROR, "%a: signature check failure\n", __func__));
}
+ if (Private->CredentialProtocol != NULL) {
+ Status = Private->CredentialProtocol->UnregisterRedfishService (Private->CredentialProtocol, RedfishService);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to unregister Redfish service - %r\n", __func__, Status));
+ } else {
+ if (Service->RestEx != NULL) {
+ Status = Service->RestEx->Configure (Service->RestEx, NULL);
+ DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: release RestEx instance: %r\n", __func__, Status));
+ }
+ }
+ }
+
return ReleaseRedfishService (Service);
}
@@ -800,7 +885,7 @@ RedfishPatchResource (
DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
RedfishExpireResponse (This, Uri);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodPatch, Response->StatusCode)) {
DEBUG_CODE (
DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
);
@@ -917,7 +1002,7 @@ RedfishPutResource (
DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
RedfishExpireResponse (This, Uri);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodPut, Response->StatusCode)) {
DEBUG_CODE (
DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
);
@@ -1034,7 +1119,7 @@ RedfishPostResource (
DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
RedfishExpireResponse (This, Uri);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodPost, Response->StatusCode)) {
DEBUG_CODE (
DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
);
@@ -1153,7 +1238,7 @@ RedfishDeleteResource (
DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
RedfishExpireResponse (This, Uri);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodDelete, Response->StatusCode)) {
DEBUG_CODE (
DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
);
@@ -1245,10 +1330,10 @@ CredentialProtocolInstalled (
}
//
- // Locate HII database protocol.
+ // Locate HII credential protocol.
//
Status = gBS->LocateProtocol (
- &gEdkIIRedfishCredentialProtocolGuid,
+ &gEdkIIRedfishCredential2ProtocolGuid,
NULL,
(VOID **)&Private->CredentialProtocol
);
@@ -1327,14 +1412,14 @@ RedfishHttpEntryPoint (
// Install protocol notification if credential protocol is installed.
//
mRedfishHttpCachePrivate->NotifyEvent = EfiCreateProtocolNotifyEvent (
- &gEdkIIRedfishCredentialProtocolGuid,
+ &gEdkIIRedfishCredential2ProtocolGuid,
TPL_CALLBACK,
CredentialProtocolInstalled,
mRedfishHttpCachePrivate,
&Registration
);
if (mRedfishHttpCachePrivate->NotifyEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: failed to create protocol notification for gEdkIIRedfishCredentialProtocolGuid\n", __func__));
+ DEBUG ((DEBUG_ERROR, "%a: failed to create protocol notification for gEdkIIRedfishCredential2ProtocolGuid\n", __func__));
ASSERT (FALSE);
RedfishHttpDriverUnload (ImageHandle);
return Status;
diff --git a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.h b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.h
index cf6ba9c..38c3cd2 100644
--- a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.h
+++ b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.h
@@ -11,6 +11,7 @@
#define EDKII_REDFISH_HTTP_DXE_H_
#include <Uefi.h>
+#include <RedfishCommon.h>
#include <IndustryStandard/Http11.h>
#include <Library/UefiLib.h>
@@ -28,10 +29,9 @@
#include <Protocol/Http.h>
#include <Protocol/EdkIIRedfishHttpProtocol.h>
-#include <Protocol/EdkIIRedfishCredential.h>
+#include <Protocol/EdkIIRedfishCredential2.h>
#include <Protocol/RestEx.h>
-#define IS_EMPTY_STRING(a) ((a) == NULL || (a)[0] == '\0')
#define REDFISH_HTTP_CACHE_LIST_SIZE 0x80
#define REDFISH_ERROR_MSG_MAX 128
#define REDFISH_DEBUG_STRING_LENGTH 200
diff --git a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.inf b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.inf
index c7dfdff..0757960 100644
--- a/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.inf
+++ b/RedfishPkg/RedfishHttpDxe/RedfishHttpDxe.inf
@@ -56,7 +56,7 @@
[Protocols]
gEdkIIRedfishHttpProtocolGuid ## PRODUCED
- gEdkIIRedfishCredentialProtocolGuid ## CONSUMES
+ gEdkIIRedfishCredential2ProtocolGuid ## CONSUMES
gEfiRestExProtocolGuid ## CONSUEMS
[Pcd]
diff --git a/RedfishPkg/RedfishHttpDxe/RedfishHttpOperation.c b/RedfishPkg/RedfishHttpDxe/RedfishHttpOperation.c
index 8110985..8ae1d2d 100644
--- a/RedfishPkg/RedfishHttpDxe/RedfishHttpOperation.c
+++ b/RedfishPkg/RedfishHttpDxe/RedfishHttpOperation.c
@@ -493,6 +493,7 @@ ParseResponseMessage (
EFI_STATUS Status;
EDKII_JSON_VALUE JsonData;
EFI_HTTP_HEADER *ContentEncodedHeader;
+ EFI_HTTP_HEADER *ContentTypeHeader;
VOID *DecodedBody;
UINTN DecodedLength;
@@ -545,6 +546,17 @@ ParseResponseMessage (
//
if ((ResponseMsg->BodyLength != 0) && (ResponseMsg->Body != NULL)) {
DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: body length: %d\n", __func__, ResponseMsg->BodyLength));
+
+ //
+ // We expect to see JSON body
+ //
+ ContentTypeHeader = HttpFindHeader (RedfishResponse->HeaderCount, RedfishResponse->Headers, HTTP_HEADER_CONTENT_TYPE);
+ if (ContentTypeHeader != NULL) {
+ if (AsciiStrCmp (ContentTypeHeader->FieldValue, HTTP_CONTENT_TYPE_APP_JSON) != 0) {
+ DEBUG ((DEBUG_WARN, "%a: body is not in %a format\n", __func__, HTTP_CONTENT_TYPE_APP_JSON));
+ }
+ }
+
//
// Check if data is encoded.
//
diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
index 5431852..f80c679 100644
--- a/RedfishPkg/RedfishPkg.dec
+++ b/RedfishPkg/RedfishPkg.dec
@@ -90,6 +90,9 @@
## Include/Protocol/EdkIIRedfishCredential.h
gEdkIIRedfishCredentialProtocolGuid = { 0x8804377, 0xaf7a, 0x4496, { 0x8a, 0x7b, 0x17, 0x59, 0x0, 0xe9, 0xab, 0x46 } }
+ ## Include/Protocol/EdkIIRedfishCredential.h
+ gEdkIIRedfishCredential2ProtocolGuid = { 0x936b81dc, 0x348c, 0x42e3, { 0x9e, 0x82, 0x2, 0x91, 0x4f, 0xd3, 0x48, 0x86 } }
+
## Include/Protocol/Edk2RedfishConfigHandler.h
gEdkIIRedfishConfigHandlerProtocolGuid = { 0xbc0fe6bb, 0x2cc9, 0x463e, { 0x90, 0x82, 0xfa, 0x11, 0x76, 0xfc, 0x67, 0xde } }
@@ -208,3 +211,7 @@
#
# Redfish RedfishPlatformConfigDxe feature Properties
gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigFeatureProperty|0|UINT32|0x00001014
+ ## This is used to disable a deletion of the bootstrap account.
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishCredentialDeleteAccount|TRUE|BOOLEAN|0x00001015
+ ## Default Redfish version string
+ gEfiRedfishPkgTokenSpaceGuid.PcdDefaultRedfishVersion|L"v1"|VOID*|0x00001016
diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
index b015004..97f2059 100644
--- a/RedfishPkg/RedfishPkg.dsc
+++ b/RedfishPkg/RedfishPkg.dsc
@@ -52,12 +52,11 @@
IpmiLib|MdeModulePkg/Library/BaseIpmiLibNull/BaseIpmiLibNull.inf
IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.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]
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
index 46d01fc..26bec84 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
@@ -2483,7 +2483,7 @@ HiiStringProtocolInstalled (
(VOID **)&mRedfishPlatformConfigPrivate->HiiString
);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: locate EFI_HII_STRING_PROTOCOL failure: %r\n", __func__, Status));
+ DEBUG ((DEBUG_INFO, "%a: locate EFI_HII_STRING_PROTOCOL failure: %r\n", __func__, Status));
return;
}
@@ -2518,7 +2518,7 @@ HiiDatabaseProtocolInstalled (
(VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: locate EFI_HII_DATABASE_PROTOCOL failure: %r\n", __func__, Status));
+ DEBUG ((DEBUG_INFO, "%a: locate EFI_HII_DATABASE_PROTOCOL failure: %r\n", __func__, Status));
return;
}
@@ -2581,7 +2581,7 @@ RegexProtocolInstalled (
(VOID **)&mRedfishPlatformConfigPrivate->RegularExpressionProtocol
);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: locate EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __func__, Status));
+ DEBUG ((DEBUG_INFO, "%a: locate EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __func__, Status));
return;
}
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
index e3e185a..6f491b2 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
@@ -110,11 +110,9 @@ typedef struct {
} REDFISH_STACK;
#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a) BASE_CR (a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
-#define REGULAR_EXPRESSION_INCLUDE_ALL L".*"
-#define CONFIGURE_LANGUAGE_PREFIX "x-UEFI-redfish-"
-#define REDFISH_PLATFORM_CONFIG_VERSION 0x00010000
-
-#define REDFISH_MENU_PATH_SIZE 8
+#define REGULAR_EXPRESSION_INCLUDE_ALL L".*"
+#define CONFIGURE_LANGUAGE_PREFIX "x-UEFI-redfish-"
+#define REDFISH_MENU_PATH_SIZE 8
// Definitions of Redfish platform config capability
#define REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH 0x000000001
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
index 525ca43..9ac7f26 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
@@ -13,6 +13,7 @@
#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
#include <Uefi.h>
+#include <RedfishCommon.h>
//
// Libraries
@@ -27,7 +28,6 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
-#define IS_EMPTY_STRING(a) (a == NULL || a[0] == L'\0')
#define ENGLISH_LANGUAGE_CODE "en-US"
#define X_UEFI_SCHEMA_PREFIX "x-UEFI-redfish-"
diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c b/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c
index 741a8c1..e601bb6 100644
--- a/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c
+++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c
@@ -660,7 +660,7 @@ RestExHttpCallback (
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_SUCCESS 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
@@ -762,7 +762,7 @@ RedfishRestExServiceBindingCreateChild (
goto ON_ERROR;
}
- // Initial HTTP callback funciton on this REST EX instance
+ // Initial HTTP callback function on this REST EX instance
Instance->HttpCallbakFunction.Callback = RestExHttpCallback;
Status = gBS->InstallProtocolInterface (
&Instance->HttpIo.Handle,
@@ -771,7 +771,7 @@ RedfishRestExServiceBindingCreateChild (
&Instance->HttpCallbakFunction
);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: Fail to install HttpCallbakFunction.\n", __func__));
+ DEBUG ((DEBUG_ERROR, "%a: Fail to install HttpCallbackFunction.\n", __func__));
goto ON_ERROR;
}
@@ -803,7 +803,7 @@ ON_ERROR:
@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_SUCCESS 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
diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c b/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c
index b296142..0b38c1f 100644
--- a/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c
+++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c
@@ -110,7 +110,7 @@ RedfishCheckHttpReceiveStatus (
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.
+ for the further actions.
@param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular
REST service.
diff --git a/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c b/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c
index 0da5132..fba634f 100644
--- a/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c
+++ b/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c
@@ -373,7 +373,7 @@ InterpreterInstanceDestoryJsonStruct (
Status = EFI_UNSUPPORTED;
//
- // Check if the namesapce and version is supported by this interpreter.
+ // Check if the namespace and version is supported by this interpreter.
//
ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier;
for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index++) {
diff --git a/SecurityPkg/FvReportPei/FvReportPei.c b/SecurityPkg/FvReportPei/FvReportPei.c
index 6288dde..50773db 100644
--- a/SecurityPkg/FvReportPei/FvReportPei.c
+++ b/SecurityPkg/FvReportPei/FvReportPei.c
@@ -150,6 +150,16 @@ VerifyHashedFv (
HashValue = AllocateZeroPool (AlgInfo->HashSize * (FvNumber + 1));
ASSERT (HashValue != NULL);
+ Status = PeiServicesLocatePpi (
+ &gEdkiiPeiFirmwareVolumeShadowPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&FvShadowPpi
+ );
+ if (EFI_ERROR (Status)) {
+ FvShadowPpi = NULL;
+ }
+
//
// Calculate hash value for each FV first.
//
@@ -194,14 +204,8 @@ VerifyHashedFv (
FvBuffer = AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)FvInfo[FvIndex].Length));
ASSERT (FvBuffer != NULL);
- Status = PeiServicesLocatePpi (
- &gEdkiiPeiFirmwareVolumeShadowPpiGuid,
- 0,
- NULL,
- (VOID **)&FvShadowPpi
- );
- if (!EFI_ERROR (Status)) {
+ if (FvShadowPpi != NULL) {
Status = FvShadowPpi->FirmwareVolumeShadow (
(EFI_PHYSICAL_ADDRESS)FvInfo[FvIndex].Base,
FvBuffer,
@@ -209,7 +213,7 @@ VerifyHashedFv (
);
}
- if (EFI_ERROR (Status)) {
+ if ((FvShadowPpi == NULL) || (EFI_ERROR (Status))) {
CopyMem (
FvBuffer,
(CONST VOID *)(UINTN)FvInfo[FvIndex].Base,
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c
index 335957d..3aaf012 100644
--- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Object.c
@@ -178,6 +178,7 @@ Tpm2ReadPublic (
return EFI_UNSUPPORTED;
}
+ break;
case TPM_ALG_SYMCIPHER:
OutPublic->publicArea.parameters.symDetail.algorithm = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
Buffer += sizeof (UINT16);
@@ -252,7 +253,7 @@ Tpm2ReadPublic (
OutPublic->publicArea.parameters.rsaDetail.keyBits = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
Buffer += sizeof (UINT16);
- OutPublic->publicArea.parameters.rsaDetail.exponent = SwapBytes16 (ReadUnaligned16 ((UINT16 *)Buffer));
+ OutPublic->publicArea.parameters.rsaDetail.exponent = SwapBytes32 (ReadUnaligned32 ((UINT32 *)Buffer));
Buffer += sizeof (UINT32);
break;
case TPM_ALG_ECC:
diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml
index 2a4cbd3..26fedd1 100644
--- a/SecurityPkg/SecurityPkg.ci.yaml
+++ b/SecurityPkg/SecurityPkg.ci.yaml
@@ -6,6 +6,9 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "SecurityPkg.dsc",
+ },
"LicenseCheck": {
"IgnoreFiles": [
"DeviceSecurity/SpdmLib/Include",
diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index 70981da..f6a3f49 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -89,17 +89,11 @@
PlatformLibWrapper|SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.inf
MemLibWrapper|SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf
-[LibraryClasses.ARM, LibraryClasses.AARCH64]
- #
- # It is not possible to prevent the ARM compiler for generic intrinsic functions.
- # This library provides the intrinsic functions generate by a given compiler.
- # And NULL mean link this library into all ARM images.
- #
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- # Add support for GCC stack protector
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+[LibraryClasses.ARM, LibraryClasses.AARCH64]
ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
ArmTrngLib|MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf
diff --git a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c
index 5addd2f..b3c99a9 100644
--- a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c
+++ b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.c
@@ -641,7 +641,7 @@ UpdateHID (
CopyMem (DataPtr, Hid, TPM_HID_ACPI_SIZE);
}
- DEBUG ((DEBUG_INFO, "TPM2 ACPI _HID is patched to %a\n", DataPtr));
+ DEBUG ((DEBUG_INFO, "TPM2 ACPI _HID is patched to %a\n", Hid));
return Status;
}
diff --git a/SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl b/SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl
index 95f9d7e..dcf3461 100644
--- a/SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl
+++ b/SecurityPkg/Tcg/Tcg2Acpi/Tpm.asl
@@ -241,26 +241,10 @@ DefinitionBlock (
Method (PTS, 1, Serialized)
{
//
- // Detect Sx state for MOR, only S4, S5 need to handle
+ // _PTS is deprecated for being security deficient
+ // this implementation simply returns to maintain
+ // compatibility with older OSes using it.
//
- If (LAnd (LLess (Arg0, 6), LGreater (Arg0, 3)))
- {
- //
- // Bit4 -- DisableAutoDetect. 0 -- Firmware MAY autodetect.
- //
- If (LNot (And (MORD, 0x10)))
- {
- //
- // Trigger the SMI through ACPI _PTS method.
- //
- Store (0x02, MCIP)
-
- //
- // Trigger the SMI interrupt
- //
- Store (MCIN, IOPN)
- }
- }
Return (0)
}
@@ -446,43 +430,6 @@ DefinitionBlock (
Return (1)
}
- Method (TMCI, 2, Serialized, 0, IntObj, {UnknownObj, UnknownObj}) // IntObj, PkgObj
- {
- //
- // Switch by function index
- //
- Switch (ToInteger (Arg0))
- {
- Case (0)
- {
- //
- // Standard query, supports function 1-1
- //
- Return (Buffer () {0x03})
- }
- Case (1)
- {
- //
- // Save the Operation Value of the Request to MORD (reserved memory)
- //
- Store (DerefOf (Index (Arg1, 0x00)), MORD)
-
- //
- // Trigger the SMI through ACPI _DSM method.
- //
- Store (0x01, MCIP)
-
- //
- // Trigger the SMI interrupt
- //
- Store (MCIN, IOPN)
- Return (MRET)
- }
- Default {BreakPoint}
- }
- Return (1)
- }
-
Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj})
{
@@ -503,12 +450,8 @@ DefinitionBlock (
}
//
- // TCG Memory Clear Interface
+ // _DSM Memory Clear is deprecated, so not called
//
- If(LEqual(Arg0, ToUUID ("376054ed-cc13-4675-901c-4756d7f2d45d")))
- {
- Return (TMCI (Arg2, Arg3))
- }
Return (Buffer () {0})
}
diff --git a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c
index ce78e32..92243ec 100644
--- a/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c
+++ b/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c
@@ -75,21 +75,25 @@ BuildTcg2AcpiCommunicateBufferHob (
{
TCG2_ACPI_COMMUNICATE_BUFFER *Tcg2AcpiCommunicateBufferHob;
EFI_STATUS Status;
- VOID *Buffer;
+ EFI_PHYSICAL_ADDRESS Buffer;
UINTN Pages;
- Pages = sizeof (TCG_NVS);
- Buffer = AllocateRuntimePages (Pages);
- ASSERT (Buffer != NULL);
+ Pages = EFI_SIZE_TO_PAGES (sizeof (TCG_NVS));
+ Status = PeiServicesAllocatePages (
+ EfiACPIMemoryNVS,
+ Pages,
+ &Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
- Status = MmUnblockMemoryRequest ((UINTN)Buffer, Pages);
+ Status = MmUnblockMemoryRequest (Buffer, Pages);
if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) {
return Status;
}
Tcg2AcpiCommunicateBufferHob = BuildGuidHob (&gEdkiiTcg2AcpiCommunicateBufferHobGuid, sizeof (TCG2_ACPI_COMMUNICATE_BUFFER));
ASSERT (Tcg2AcpiCommunicateBufferHob != NULL);
- Tcg2AcpiCommunicateBufferHob->Tcg2AcpiCommunicateBuffer = (UINTN)Buffer;
+ Tcg2AcpiCommunicateBufferHob->Tcg2AcpiCommunicateBuffer = Buffer;
Tcg2AcpiCommunicateBufferHob->Pages = Pages;
return EFI_SUCCESS;
@@ -190,7 +194,7 @@ Tcg2ConfigPeimEntryPoint (
//
Hob = BuildGuidDataHob (
&gEdkiiTpmInstanceHobGuid,
- PcdGetPtr (PcdTpmInstanceGuid),
+ (VOID *)PcdGetPtr (PcdTpmInstanceGuid),
sizeof (EFI_GUID)
);
ASSERT (Hob != NULL);
@@ -200,7 +204,7 @@ Tcg2ConfigPeimEntryPoint (
//
Hob = BuildGuidDataHob (
&gEdkiiTcgPhysicalPresenceInterfaceVerHobGuid,
- PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer),
+ (VOID *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer),
AsciiStrSize ((CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer))
);
ASSERT (Hob != NULL);
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
index b55b6c1..4d0c241 100644
--- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
+++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
@@ -2616,6 +2616,17 @@ OnExitBootServicesFailed (
EFI_STATUS Status;
//
+ // Measure invocation of ExitBootServices,
+ //
+ Status = TcgMeasureAction (
+ 5,
+ EFI_EXIT_BOOT_SERVICES_INVOCATION
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));
+ }
+
+ //
// Measure Failure of ExitBootServices,
//
Status = TcgMeasureAction (
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c
index c2cef76..d4a4149 100644
--- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c
+++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.c
@@ -73,16 +73,28 @@ TpmNvsCommunciate (
return EFI_ACCESS_DENIED;
}
- if (!IsBufferOutsideMmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+ CommParams = (TPM_NVS_MM_COMM_BUFFER *)CommBuffer;
+
+ //
+ // The Primary Buffer validation
+ //
+ if (!Tcg2IsPrimaryBufferValid ((UINTN)CommBuffer, TempCommBufferSize)) {
DEBUG ((DEBUG_ERROR, "[%a] - MM Communication buffer in invalid location!\n", __func__));
return EFI_ACCESS_DENIED;
}
//
+ // The NonPrimary Buffer validation
+ //
+ if (!Tcg2IsNonPrimaryBufferValid (CommParams->TargetAddress, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof (TCG_NVS))))) {
+ DEBUG ((DEBUG_ERROR, "[%a] - MM NonPrimary buffer pointed from Communication buffer in invalid location!\n", __func__));
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
// Farm out the job to individual functions based on what was requested.
//
- CommParams = (TPM_NVS_MM_COMM_BUFFER *)CommBuffer;
- Status = EFI_SUCCESS;
+ Status = EFI_SUCCESS;
switch (CommParams->Function) {
case TpmNvsMmExchangeInfo:
DEBUG ((DEBUG_VERBOSE, "[%a] - Function requested: MM_EXCHANGE_NVS_INFO\n", __func__));
@@ -159,81 +171,6 @@ PhysicalPresenceCallback (
}
/**
- Software SMI callback for MemoryClear which is called from ACPI method.
-
- Caution: This function may receive untrusted input.
- Variable and ACPINvs are external input, so this function will validate
- its data structure to be valid value.
-
- @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
- @param[in] Context Points to an optional handler context which was specified when the
- handler was registered.
- @param[in, out] CommBuffer A pointer to a collection of data in memory that will
- be conveyed from a non-SMM environment into an SMM environment.
- @param[in, out] CommBufferSize The size of the CommBuffer.
-
- @retval EFI_SUCCESS The interrupt was handled successfully.
-
-**/
-EFI_STATUS
-EFIAPI
-MemoryClearCallback (
- IN EFI_HANDLE DispatchHandle,
- IN CONST VOID *Context,
- IN OUT VOID *CommBuffer,
- IN OUT UINTN *CommBufferSize
- )
-{
- EFI_STATUS Status;
- UINTN DataSize;
- UINT8 MorControl;
-
- mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_SUCCESS;
- if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE) {
- MorControl = (UINT8)mTcgNvs->MemoryClear.Request;
- } else if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_PTS_CLEAR_MOR_BIT) {
- DataSize = sizeof (UINT8);
- Status = mSmmVariable->SmmGetVariable (
- MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
- &gEfiMemoryOverwriteControlDataGuid,
- NULL,
- &DataSize,
- &MorControl
- );
- if (EFI_ERROR (Status)) {
- mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
- DEBUG ((DEBUG_ERROR, "[TPM] Get MOR variable failure! Status = %r\n", Status));
- return EFI_SUCCESS;
- }
-
- if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) {
- return EFI_SUCCESS;
- }
-
- MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK;
- } else {
- mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
- DEBUG ((DEBUG_ERROR, "[TPM] MOR Parameter error! Parameter = %x\n", mTcgNvs->MemoryClear.Parameter));
- return EFI_SUCCESS;
- }
-
- DataSize = sizeof (UINT8);
- Status = mSmmVariable->SmmSetVariable (
- MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
- &gEfiMemoryOverwriteControlDataGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- DataSize,
- &MorControl
- );
- if (EFI_ERROR (Status)) {
- mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
- DEBUG ((DEBUG_ERROR, "[TPM] Set MOR variable failure! Status = %r\n", Status));
- }
-
- return EFI_SUCCESS;
-}
-
-/**
Notification for SMM ReadyToLock protocol.
@param[in] Protocol Points to the protocol's unique identifier.
@@ -325,16 +262,6 @@ InitializeTcgCommon (
mPpSoftwareSmi = SwContext.SwSmiInputValue;
- SwContext.SwSmiInputValue = (UINTN)-1;
- Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &McSwHandle);
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "[%a] Failed to register MC callback as SW MM handler - %r!\n", __func__, Status));
- goto Cleanup;
- }
-
- mMcSoftwareSmi = SwContext.SwSmiInputValue;
-
//
// Locate SmmVariableProtocol.
//
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h
index 3672db9..0be4984 100644
--- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h
+++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2Smm.h
@@ -55,16 +55,35 @@ Tcg2NotifyMmReady (
);
/**
- This function is an abstraction layer for implementation specific Mm buffer validation routine.
+ This function is for the Primary Buffer validation routine.
+ The Primary Buffer is the communication buffer requested from
+ Communicate protocol/PPI.
@param Buffer The buffer start address to be checked.
@param Length The buffer length to be checked.
- @retval TRUE This buffer is valid per processor architecture and not overlap with SMRAM.
- @retval FALSE This buffer is not valid per processor architecture or overlap with SMRAM.
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
**/
BOOLEAN
-IsBufferOutsideMmValid (
+Tcg2IsPrimaryBufferValid (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ );
+
+/**
+ This function is for the NonPrimary Buffer validation routine.
+ The NonPrimary Buffer is the buffer which might be pointed from the
+ communication buffer.
+
+ @param Buffer The buffer start address to be checked.
+ @param Length The buffer length to be checked.
+
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
+**/
+BOOLEAN
+Tcg2IsNonPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
);
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c
index 9320053..0f23662 100644
--- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c
+++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2StandaloneMm.c
@@ -31,16 +31,38 @@ Tcg2NotifyMmReady (
}
/**
- This function is an abstraction layer for implementation specific Mm buffer validation routine.
+ This function is for the Primary Buffer validation routine.
+ The Primary Buffer is the communication buffer requested from
+ Communicate protocol/PPI.
@param Buffer The buffer start address to be checked.
@param Length The buffer length to be checked.
- @retval TRUE This buffer is valid per processor architecture and not overlap with SMRAM.
- @retval FALSE This buffer is not valid per processor architecture or overlap with SMRAM.
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
**/
BOOLEAN
-IsBufferOutsideMmValid (
+Tcg2IsPrimaryBufferValid (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ )
+{
+ return TRUE;
+}
+
+/**
+ This function is for the Secondary Buffer validation routine.
+ The Secondary Buffer is the buffer which is pointed from the
+ communication buffer.
+
+ @param Buffer The buffer start address to be checked.
+ @param Length The buffer length to be checked.
+
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
+**/
+BOOLEAN
+Tcg2IsNonPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
)
diff --git a/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c b/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c
index f7d595e..fd8a51b 100644
--- a/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c
+++ b/SecurityPkg/Tcg/Tcg2Smm/Tcg2TraditionalMm.c
@@ -41,7 +41,9 @@ Tcg2NotifyMmReady (
}
/**
- This function is an abstraction layer for implementation specific Mm buffer validation routine.
+ This function is for the Primary Buffer validation routine.
+ The Primary Buffer is the communication buffer requested from
+ Communicate protocol/PPI.
@param Buffer The buffer start address to be checked.
@param Length The buffer length to be checked.
@@ -50,7 +52,27 @@ Tcg2NotifyMmReady (
@retval FALSE This buffer is not valid per processor architecture or overlap with SMRAM.
**/
BOOLEAN
-IsBufferOutsideMmValid (
+Tcg2IsPrimaryBufferValid (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ )
+{
+ return SmmIsBufferOutsideSmmValid (Buffer, Length);
+}
+
+/**
+ This function is for the NonPrimary Buffer validation routine.
+ The NonPrimary Buffer is the buffer which is pointed from the
+ communication buffer.
+
+ @param Buffer The buffer start address to be checked.
+ @param Length The buffer length to be checked.
+
+ @retval TRUE This buffer is valid.
+ @retval FALSE This buffer is not valid.
+**/
+BOOLEAN
+Tcg2IsNonPrimaryBufferValid (
IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length
)
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
index eac9286..728d8b5 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
@@ -1,7 +1,7 @@
/** @file
ACPI parser
- Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
+ Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
Copyright (c) 2022, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -319,12 +319,14 @@ DumpUint64 (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
Dump3Chars (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
Print (
@@ -343,12 +345,14 @@ Dump3Chars (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
Dump4Chars (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
Print (
@@ -368,12 +372,14 @@ Dump4Chars (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
Dump6Chars (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
Print (
@@ -395,12 +401,14 @@ Dump6Chars (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
Dump8Chars (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
Print (
@@ -424,12 +432,14 @@ Dump8Chars (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
Dump12Chars (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
Print (
@@ -450,6 +460,171 @@ Dump12Chars (
}
/**
+ This function traces 16 characters which can be optionally
+ formated using the format string if specified.
+
+ If no format string is specified the Format must be NULL.
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+VOID
+EFIAPI
+Dump16Chars (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ Print (
+ (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
+ Ptr[0],
+ Ptr[1],
+ Ptr[2],
+ Ptr[3],
+ Ptr[4],
+ Ptr[5],
+ Ptr[6],
+ Ptr[7],
+ Ptr[8],
+ Ptr[9],
+ Ptr[10],
+ Ptr[11],
+ Ptr[12],
+ Ptr[13],
+ Ptr[14],
+ Ptr[15]
+ );
+}
+
+/**
+ This function traces reserved fields up to 8 bytes in length.
+
+ Format string is ignored by this function as the reserved field is printed
+ byte by byte with intermittent spacing <eg: 0 0 0 0>. Use DumpxChars for any
+ other use case.
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+VOID
+EFIAPI
+DumpReserved (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ switch (Length) {
+ case 8:
+ Print (
+ L"%u %u %u %u %u %u %u %u",
+ Ptr[0],
+ Ptr[1],
+ Ptr[2],
+ Ptr[3],
+ Ptr[4],
+ Ptr[5],
+ Ptr[6],
+ Ptr[7]
+ );
+ break;
+ case 7:
+ Print (
+ L"%u %u %u %u %u %u %u",
+ Ptr[0],
+ Ptr[1],
+ Ptr[2],
+ Ptr[3],
+ Ptr[4],
+ Ptr[5],
+ Ptr[6]
+ );
+ break;
+ case 6:
+ Print (
+ L"%u %u %u %u %u %u",
+ Ptr[0],
+ Ptr[1],
+ Ptr[2],
+ Ptr[3],
+ Ptr[4],
+ Ptr[5]
+ );
+ break;
+ case 5:
+ Print (
+ L"%u %u %u %u %u",
+ Ptr[0],
+ Ptr[1],
+ Ptr[2],
+ Ptr[3],
+ Ptr[4]
+ );
+ break;
+ case 4:
+ Print (
+ L"%u %u %u %u",
+ Ptr[0],
+ Ptr[1],
+ Ptr[2],
+ Ptr[3]
+ );
+ break;
+ case 3:
+ Print (
+ L"%u %u %u",
+ Ptr[0],
+ Ptr[1],
+ Ptr[2]
+ );
+ break;
+ case 2:
+ Print (
+ L"%u %u",
+ Ptr[0],
+ Ptr[1]
+ );
+ break;
+ case 1:
+ Print (
+ L"%u",
+ Ptr[0]
+ );
+ break;
+ default:
+ return;
+ }
+}
+
+/**
+ This function traces reserved fields up to 64 bits in length.
+
+ Format string is ignored by this function as the reserved field is printed
+ byte by byte with intermittent spacing. eg: <0 0 0 0>. When the field length
+ isn't a multiple of 8, the number of bytes are "ceil"-ed by one. eg for 27
+ bits <0 0 0 0>
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field as number of bits.
+**/
+VOID
+EFIAPI
+DumpReservedBits (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ UINT32 ByteLength;
+
+ ByteLength = (Length + 7) >> 3;
+ DumpReserved (Format, Ptr, ByteLength);
+}
+
+/**
This function indents and prints the ACPI table Field Name.
@param [in] Indent Number of spaces to add to the global table indent.
@@ -587,7 +762,7 @@ ParseAcpi (
// the Format for printing
PrintFieldName (2, Parser[Index].NameStr);
if (Parser[Index].PrintFormatter != NULL) {
- Parser[Index].PrintFormatter (Parser[Index].Format, Ptr);
+ Parser[Index].PrintFormatter (Parser[Index].Format, Ptr, Parser[Index].Length);
} else if (Parser[Index].Format != NULL) {
switch (Parser[Index].Length) {
case 1:
@@ -616,7 +791,11 @@ ParseAcpi (
if (GetConsistencyChecking () &&
(Parser[Index].FieldValidator != NULL))
{
- Parser[Index].FieldValidator (Ptr, Parser[Index].Context);
+ Parser[Index].FieldValidator (
+ Ptr,
+ Parser[Index].Length,
+ Parser[Index].Context
+ );
}
Print (L"\n");
@@ -681,12 +860,14 @@ DumpGasStruct (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
DumpGas (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
DumpGasStruct (Ptr, 2, sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE));
@@ -892,7 +1073,7 @@ ParseAcpiBitFields (
// the Format for printing
PrintFieldName (2, Parser[Index].NameStr);
if (Parser[Index].PrintFormatter != NULL) {
- Parser[Index].PrintFormatter (Parser[Index].Format, (UINT8 *)&Data);
+ Parser[Index].PrintFormatter (Parser[Index].Format, (UINT8 *)&Data, Parser[Index].Length);
} else if (Parser[Index].Format != NULL) {
// convert bit length to byte length
switch ((Parser[Index].Length + 7) >> 3) {
@@ -927,7 +1108,11 @@ ParseAcpiBitFields (
if (GetConsistencyChecking () &&
(Parser[Index].FieldValidator != NULL))
{
- Parser[Index].FieldValidator ((UINT8 *)&Data, Parser[Index].Context);
+ Parser[Index].FieldValidator (
+ (UINT8 *)&Data,
+ Parser[Index].Length,
+ Parser[Index].Context
+ );
}
Print (L"\n");
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
index 6468fe5..3281624 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
@@ -2,7 +2,7 @@
Header file for ACPI parser
Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
- Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
+ Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
Copyright (c) 2022, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -130,12 +130,14 @@ DumpUint64 (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
Dump3Chars (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
);
/**
@@ -146,12 +148,14 @@ Dump3Chars (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
Dump4Chars (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
);
/**
@@ -162,12 +166,14 @@ Dump4Chars (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
Dump6Chars (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
);
/**
@@ -178,12 +184,14 @@ Dump6Chars (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
Dump8Chars (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
);
/**
@@ -194,12 +202,70 @@ Dump8Chars (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
Dump12Chars (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ );
+
+/**
+ This function traces 16 characters which can be optionally
+ formated using the format string if specified.
+
+ If no format string is specified the Format must be NULL.
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+VOID
+EFIAPI
+Dump16Chars (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ );
+
+/**
+ This function traces reserved fields up to 8 bytes in length.
+
+ Format string is ignored by this function as the reserved field is printed
+ byte by byte with intermittent spacing <eg: 0 0 0 0>. Use DumpxChars for any
+ other use case.
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+VOID
+EFIAPI
+DumpReserved (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ );
+
+/**
+ This function traces reserved fields up to 64 bits in length.
+
+ Format string is ignored by this function as the reserved field is printed
+ byte by byte with intermittent spacing. eg: <0 0 0 0>. When the field length
+ isn't a multiple of 8, the number of bytes are "ceil"-ed by one. eg for 27
+ bits <0 0 0 0>
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field as number of bits.
+**/
+VOID
+EFIAPI
+DumpReservedBits (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
);
/**
@@ -227,18 +293,24 @@ PrintFieldName (
@param [in] Format Format string for tracing the data as specified by
the 'Format' member of ACPI_PARSER.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
-typedef VOID (EFIAPI *FNPTR_PRINT_FORMATTER)(CONST CHAR16 *Format, UINT8 *Ptr);
+typedef VOID (EFIAPI *FNPTR_PRINT_FORMATTER)(CONST CHAR16 *Format, UINT8 *Ptr, UINT32 Length);
/**
This function pointer is the template for validating an ACPI table field.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information as specified by
the 'Context' member of the ACPI_PARSER.
e.g. this could be a pointer to the ACPI table header.
**/
-typedef VOID (EFIAPI *FNPTR_FIELD_VALIDATOR)(UINT8 *Ptr, VOID *Context);
+typedef VOID (EFIAPI *FNPTR_FIELD_VALIDATOR)(
+ UINT8 *Ptr,
+ UINT32 Length,
+ VOID *Context
+ );
/**
The ACPI_PARSER structure describes the fields of an ACPI table and
@@ -468,12 +540,14 @@ DumpGasStruct (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
DumpGas (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
);
/**
@@ -617,6 +691,27 @@ ParseAcpiDsdt (
);
/**
+ This function parses the EINJ table.
+ When trace is enabled this function parses the EINJ table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiEinj (
+ IN BOOLEAN Trace,
+ IN UINT8 *Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/**
This function parses the ACPI ERST table.
When trace is enabled this function parses the ERST table and
traces the ACPI table fields.
@@ -705,6 +800,27 @@ ParseAcpiGtdt (
);
/**
+ This function parses the ACPI HEST table.
+ When trace is enabled this function parses the HEST table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiHest (
+ IN BOOLEAN Trace,
+ IN UINT8 *Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/**
This function parses the ACPI HMAT table.
When trace is enabled this function parses the HMAT table and
traces the ACPI table fields.
@@ -827,6 +943,27 @@ ParseAcpiMcfg (
);
/**
+ This function parses the ACPI MPAM table.
+ When trace is enabled this function parses the MPAM table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiMpam (
+ IN BOOLEAN Trace,
+ IN UINT8 *Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/**
This function parses the ACPI PCCT table including its sub-structures
of type 0 through 4.
When trace is enabled this function parses the PCCT table and
@@ -870,6 +1007,29 @@ ParseAcpiPptt (
);
/**
+ This function parses the ACPI RAS2 table.
+ When trace is enabled this function parses the RAS2 table and
+ traces the ACPI table fields.
+
+ This function parses the RAS2 ACPI table along with PCC Entries
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiRas2 (
+ IN BOOLEAN Trace,
+ IN UINT8 *Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/**
This function parses the ACPI RSDP table.
This function invokes the parser for the XSDT table.
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c
index 48f7148..af70c41 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c
@@ -1,7 +1,7 @@
/** @file
AEST table parser
- Copyright (c) 2020, Arm Limited.
+ Copyright (c) 2020 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -33,6 +33,7 @@ STATIC UINT8 *ProcessorResourceType;
Validate Processor Flags.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -40,8 +41,9 @@ STATIC
VOID
EFIAPI
ValidateProcessorFlags (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
// If the global or shared node flag is set then the ACPI Processor ID
@@ -59,6 +61,7 @@ ValidateProcessorFlags (
Validate GIC Interface Type.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -66,8 +69,9 @@ STATIC
VOID
EFIAPI
ValidateGicInterfaceType (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT32 GicInterfaceType;
@@ -83,6 +87,7 @@ ValidateGicInterfaceType (
Validate Interface Type.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -90,8 +95,9 @@ STATIC
VOID
EFIAPI
ValidateInterfaceType (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*Ptr > 1) {
@@ -104,6 +110,7 @@ ValidateInterfaceType (
Validate Interrupt Type.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -111,8 +118,9 @@ STATIC
VOID
EFIAPI
ValidateInterruptType (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*Ptr > 1) {
@@ -125,6 +133,7 @@ ValidateInterruptType (
Validate interrupt flags.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -132,8 +141,9 @@ STATIC
VOID
EFIAPI
ValidateInterruptFlags (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if ((*Ptr & 0xfe) != 0) {
@@ -147,12 +157,14 @@ ValidateInterruptFlags (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
DumpVendorSpecificData (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
Print (
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c
index d25d4d8..3d43d5c 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c
@@ -1,7 +1,7 @@
/** @file
DBG2 table parser
- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -30,6 +30,7 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
This function validates the NameSpace string length.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -37,8 +38,9 @@ STATIC
VOID
EFIAPI
ValidateNameSpaceStrLen (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT16 NameSpaceStrLen;
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c
new file mode 100644
index 0000000..d01b15f
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Einj/EinjParser.c
@@ -0,0 +1,370 @@
+/** @file
+ EINJ table parser
+
+ Copyright (c) 2024, Arm Limited.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Specification Reference:
+ - ACPI 6.5, Table 18.3.2 ACPI Error Source
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+#include "AcpiView.h"
+
+STATIC ACPI_DESCRIPTION_HEADER_INFO mAcpiHdrInfo;
+STATIC UINT32 *mEinjInjectionHdrSize;
+STATIC UINT32 *mEinjInjectionEntryCnt;
+
+STATIC CONST CHAR16 *InstNameTable[] = {
+ L"READ_REGISTER",
+ L"READ_REGISTER_VALUE",
+ L"WRITE_REGISTER",
+ L"WRITE_REGISTER_VALUE",
+ L"NOOP",
+};
+
+/**
+ This function validates the flags field in the EINJ injection header.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateInjectionFlags (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 Flags;
+
+ Flags = *(UINT8 *)Ptr;
+
+ if (Flags != 0) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Injection Flags must be zero...");
+ }
+}
+
+/**
+ An ACPI_PARSER array describing the ACPI EINJ Table.
+**/
+STATIC CONST ACPI_PARSER EinjParser[] = {
+ PARSE_ACPI_HEADER (&mAcpiHdrInfo),
+ { L"Injection Header Size", 4, 36, L"%d", NULL, (VOID **)&mEinjInjectionHdrSize,
+ NULL, NULL },
+ { L"Injection Flags", 1, 40, L"0x%x", NULL, NULL, ValidateInjectionFlags,NULL },
+ { L"Reserved", 3, 41, NULL, NULL, NULL, NULL, NULL },
+ { L"Injection Entry Count", 4, 44, L"%d", NULL, (VOID **)&mEinjInjectionEntryCnt,
+ NULL, NULL },
+ /// Injection Action Table.
+ /// ...
+};
+
+/**
+ This function validates the injection action field in
+ the EINJ injection instruction entry.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateInjectionAction (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 InjectionAction;
+ UINT8 MaxInjectionAction;
+
+ InjectionAction = *(UINT8 *)Ptr;
+
+ /**
+ * EFI_ACPI_6_5_EINJ_TRIGGER_ERROR is only used Trigger Action Table
+ * not used in Injection Action Table in EINJ.
+ * Cf ACPI 6.5 Table 18.24 - Error Injection Table
+ * Cf ACPI 6.5 Table 18.36 - Trigger Error Action
+ */
+ if (*mAcpiHdrInfo.Revision < EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REVISION) {
+ MaxInjectionAction = EFI_ACPI_6_5_EINJ_GET_EXECUTE_OPERATION_TIMINGS;
+ } else {
+ MaxInjectionAction = EFI_ACPI_6_5_EINJ_EINJV2_GET_ERROR_TYPE;
+ }
+
+ if ((InjectionAction < EFI_ACPI_6_5_EINJ_BEGIN_INJECTION_OPERATION) ||
+ (InjectionAction > MaxInjectionAction))
+ {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Invalid Injection Action(0x%x)...", InjectionAction);
+ }
+}
+
+/**
+ This function validates the instruction field in
+ the EINJ injection instruction entry.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateInstruction (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 Inst;
+
+ Inst = *Ptr;
+
+ if (*mAcpiHdrInfo.Revision <= EFI_ACPI_6_5_ERROR_INJECTION_TABLE_REVISION) {
+ if (Inst > EFI_ACPI_6_5_EINJ_NOOP) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Invalid Instruction(0x%x)...", Inst);
+ }
+ }
+}
+
+/**
+ This function validates the register region field in
+ the EINJ injection instruction entry.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateRegisterRegion (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE *RegisterRegion;
+
+ RegisterRegion = (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE *)Ptr;
+
+ if ((RegisterRegion->AddressSpaceId != EFI_ACPI_6_5_SYSTEM_MEMORY) &&
+ (RegisterRegion->AddressSpaceId != EFI_ACPI_6_5_SYSTEM_IO))
+ {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Register Region Must be SYSTEM_MEMORY or SYSTEM_IO...");
+ }
+}
+
+/**
+ Dumps the injection action fields in injection instruction entry.
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+STATIC
+VOID
+EFIAPI
+DumpInjectionInstAction (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ UINT8 InjectionAction;
+ CONST CHAR16 *ActionName;
+
+ InjectionAction = *Ptr;
+
+ switch (InjectionAction) {
+ case EFI_ACPI_6_5_EINJ_BEGIN_INJECTION_OPERATION:
+ ActionName = L"BEGIN_INJECTION_OPERATION";
+ break;
+ case EFI_ACPI_6_5_EINJ_GET_TRIGGER_ERROR_ACTION_TABLE:
+ ActionName = L"GET_TRIGGER_ERROR_ACTION_TABLE";
+ break;
+ case EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE:
+ ActionName = L"SET_ERROR_TYPE";
+ break;
+ case EFI_ACPI_6_5_EINJ_GET_ERROR_TYPE:
+ ActionName = L"GET_ERROR_TYPE";
+ break;
+ case EFI_ACPI_6_5_EINJ_END_OPERATION:
+ ActionName = L"END_OPERATION";
+ break;
+ case EFI_ACPI_6_5_EINJ_EXECUTE_OPERATION:
+ ActionName = L"EXECUTE_OPERATION";
+ break;
+ case EFI_ACPI_6_5_EINJ_CHECK_BUSY_STATUS:
+ ActionName = L"CHECK_BUSY_STATUS";
+ break;
+ case EFI_ACPI_6_5_EINJ_GET_COMMAND_STATUS:
+ ActionName = L"GET_COMMAND_STATUS";
+ break;
+ case EFI_ACPI_6_5_EINJ_SET_ERROR_TYPE_WITH_ADDRESS:
+ ActionName = L"SET_ERROR_TYPE_WITH_ADDRESS";
+ break;
+ case EFI_ACPI_6_5_EINJ_GET_EXECUTE_OPERATION_TIMINGS:
+ ActionName = L"GET_EXECUTE_OPERATION_TIMINGS";
+ break;
+ case EFI_ACPI_6_5_EINJ_EINJV2_SET_ERROR_TYPE:
+ ActionName = L"EINJV2_SET_ERROR_TYPE";
+ break;
+ case EFI_ACPI_6_5_EINJ_EINJV2_GET_ERROR_TYPE:
+ ActionName = L"EINJV2_GET_ERROR_TYPE";
+ break;
+ case EFI_ACPI_6_5_EINJ_TRIGGER_ERROR:
+ ActionName = L"TRIGGER_ERROR";
+ break;
+ default:
+ IncrementErrorCount ();
+ ActionName = L"UNKNOWN";
+ }
+
+ Print (L"%s(0x%x)", ActionName, InjectionAction);
+}
+
+/**
+ Dumps the instruction fields in injection instruction entry.
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+STATIC
+VOID
+EFIAPI
+DumpInstruction (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ UINT8 Inst;
+ CONST CHAR16 *InstName;
+
+ Inst = *Ptr;
+
+ if (Inst < ARRAY_SIZE (InstNameTable)) {
+ InstName = InstNameTable[Inst];
+ } else {
+ IncrementErrorCount ();
+ InstName = L"UNKNOWN";
+ }
+
+ Print (L"%s(0x%x)", InstName, Inst);
+}
+
+/**
+ An ACPI_PARSER array describing the EINJ Injection instruction entry.
+**/
+STATIC CONST ACPI_PARSER EinjInjectionInstEntryParser[] = {
+ { L"Injection Action", 1, 0, NULL, DumpInjectionInstAction, NULL,
+ ValidateInjectionAction, NULL },
+ { L"Instruction", 1, 1, NULL, DumpInstruction, NULL,
+ ValidateInstruction, NULL },
+ { L"Flags", 1, 2, L"0x%x", NULL, NULL,NULL, NULL },
+ { L"Reserved", 1, 3, NULL, NULL, NULL,NULL, NULL },
+ { L"Register Region", 12, 4, NULL, DumpGas, NULL,
+ ValidateRegisterRegion, NULL },
+ { L"Value", 8, 16, L"0x%x", NULL, NULL,NULL, NULL },
+ { L"Mask", 8, 24, L"0x%x", NULL, NULL,NULL, NULL },
+};
+
+/**
+ This function parses the EINJ table.
+ When trace is enabled this function parses the EINJ table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiEinj (
+ IN BOOLEAN Trace,
+ IN UINT8 *Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+ UINT8 *InjInstEntryPtr;
+ UINT32 InjInstEntrySize;
+
+ if (!Trace) {
+ return;
+ }
+
+ Offset = ParseAcpi (
+ TRUE,
+ 0,
+ "EINJ",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (EinjParser)
+ );
+
+ // Validate Error Source Descriptors Count.
+ if ((mEinjInjectionHdrSize == NULL) || (*mEinjInjectionHdrSize != Offset)) {
+ IncrementErrorCount ();
+ Print (L"ERROR: Invalid Injection Header...\n");
+ return;
+ }
+
+ if ((mEinjInjectionEntryCnt == NULL) || (*mEinjInjectionEntryCnt == 0)) {
+ IncrementErrorCount ();
+ Print (L"ERROR: Injection Instruction Entry should be presented...\n");
+ return;
+ }
+
+ InjInstEntrySize = sizeof (EFI_ACPI_6_5_EINJ_INJECTION_INSTRUCTION_ENTRY);
+
+ if ((*mEinjInjectionEntryCnt * InjInstEntrySize) != (AcpiTableLength - Offset)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Incorrect count for Injection Instruction Entry.\n" \
+ L" Injection Entry Count= %d.\n" \
+ L" Present Count= %d.\n",
+ *mEinjInjectionEntryCnt,
+ (AcpiTableLength - Offset) / InjInstEntrySize
+ );
+ }
+
+ while (Offset < AcpiTableLength) {
+ InjInstEntryPtr = Ptr + Offset;
+
+ // Get Injection Instruction Entry.
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Injection Instruction Entry",
+ InjInstEntryPtr,
+ AcpiTableLength - Offset,
+ PARSER_PARAMS (EinjInjectionInstEntryParser)
+ );
+
+ Offset += InjInstEntrySize;
+ } // while
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c
index f3ae093..e237e0e 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c
@@ -2,7 +2,7 @@
ERST table parser
Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
- Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -70,6 +70,7 @@ STATIC CONST CHAR16 *ErstInstructionTable[] = {
Validate Erst action.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -77,8 +78,9 @@ STATIC
VOID
EFIAPI
ValidateErstAction (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*Ptr > EFI_ACPI_6_4_ERST_GET_EXECUTE_OPERATION_TIMINGS) {
@@ -91,6 +93,7 @@ ValidateErstAction (
Validate Erst instruction.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -98,8 +101,9 @@ STATIC
VOID
EFIAPI
ValidateErstInstruction (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*Ptr > EFI_ACPI_6_4_ERST_MOVE_DATA) {
@@ -112,6 +116,7 @@ ValidateErstInstruction (
Validate Erst flags.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -119,8 +124,9 @@ STATIC
VOID
EFIAPI
ValidateErstFlags (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if ((*Ptr & 0xfe) != 0) {
@@ -165,13 +171,15 @@ FormatByte (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the Action byte.
+ @param [in] Length Length of the field.
**/
STATIC
VOID
EFIAPI
DumpErstAction (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
FormatByte (ErstActionTable, *Ptr, ARRAY_SIZE (ErstActionTable));
@@ -182,13 +190,15 @@ DumpErstAction (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the Instruction byte.
+ @param [in] Length Length of the field.
**/
STATIC
VOID
EFIAPI
DumpErstInstruction (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
FormatByte (ErstInstructionTable, *Ptr, ARRAY_SIZE (ErstInstructionTable));
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c
index abc58d6..d89fcb1 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c
@@ -1,7 +1,7 @@
/** @file
FADT table parser
- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
Copyright (c) 2022, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -57,6 +57,7 @@ GetAcpiXsdtHeaderInfo (
This function validates the Firmware Control Field.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -64,8 +65,9 @@ STATIC
VOID
EFIAPI
ValidateFirmwareCtrl (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
@@ -83,6 +85,7 @@ ValidateFirmwareCtrl (
This function validates the X_Firmware Control Field.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -90,8 +93,9 @@ STATIC
VOID
EFIAPI
ValidateXFirmwareCtrl (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
@@ -109,6 +113,7 @@ ValidateXFirmwareCtrl (
This function validates the flags.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -116,8 +121,9 @@ STATIC
VOID
EFIAPI
ValidateFlags (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
@@ -163,12 +169,14 @@ STATIC CONST ACPI_PARSER FadtFlagParser[] = {
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
DumpFadtFlags (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
if (Format != NULL) {
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c
index e629270..c8681e8 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c
@@ -1,7 +1,7 @@
/** @file
GTDT table parser
- Copyright (c) 2016 - 2021, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -30,6 +30,7 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
This function validates the GT Block timer count.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -37,8 +38,9 @@ STATIC
VOID
EFIAPI
ValidateGtBlockTimerCount (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT32 BlockTimerCount;
@@ -59,6 +61,7 @@ ValidateGtBlockTimerCount (
This function validates the GT Frame Number.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -66,8 +69,9 @@ STATIC
VOID
EFIAPI
ValidateGtFrameNumber (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT8 FrameNumber;
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c
new file mode 100644
index 0000000..75fc40b
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c
@@ -0,0 +1,982 @@
+/** @file
+ HEST table parser
+
+ Copyright (c) 2024, Arm Limited.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Specification Reference:
+ - ACPI 6.5, Table 18.3.2 ACPI Error Source
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+#include "AcpiView.h"
+
+STATIC ACPI_DESCRIPTION_HEADER_INFO mAcpiHdrInfo;
+STATIC UINT32 *mHestErrorSourceCount;
+STATIC UINT16 *mHestErrorSourceType;
+STATIC UINT8 *mHestIA32HardwareBankCount;
+
+/**
+ An String array for Error Notification Structure's type.
+ Cf ACPI 6.5 Table 18.14: Hardware Error Notification Structure
+**/
+STATIC CONST CHAR16 *HestErrorNotificationStructureTypeStr[] = {
+ L"Polled",
+ L"External Interrupt",
+ L"Local Interrupt",
+ L"SCI",
+ L"NMI",
+ L"CMCI",
+ L"MCE",
+ L"GPIO-Signal",
+ L"ARMv8 SEA",
+ L"ARMv8 SEI",
+ L"External Interrupt - GSIV",
+ L"Software Delegated Exception",
+};
+
+/**
+ An ACPI_PARSER array describing the ACPI HEST Table.
+**/
+STATIC CONST ACPI_PARSER HestParser[] = {
+ PARSE_ACPI_HEADER (&mAcpiHdrInfo),
+ { L"Error Source Count", 4, 36, L"%d", NULL,
+ (VOID **)&mHestErrorSourceCount,NULL, NULL },
+ // Error Source Descriptor 1
+ // Error Source Descriptor Type
+ // Error Source Descriptor Data
+ // ...
+ // Error Source Descriptor 2
+ // Error Source Descriptor Type
+ // Error Source Descriptor Data
+ // ...
+ // ....
+ // Error Source Descriptor n
+ // Error Source Descriptor Type
+ // Error Source Descriptor Data
+ // ...
+};
+
+/**
+ An ACPI_PARSER array describing the HEST error source descriptor type.
+**/
+STATIC CONST ACPI_PARSER HestErrorSourceTypeParser[] = {
+ { L"Type", 2, 0, L"%d", NULL, (VOID **)&mHestErrorSourceType, NULL, NULL },
+};
+
+/**
+ An ACPI_PARSER array describing the HEST error source flags information.
+**/
+STATIC CONST ACPI_PARSER HestErrorSourceFlags[] = {
+ { L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL },
+ { L"Global", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"GHES Assist", 1, 2, L"%d", NULL, NULL, NULL, NULL },
+ { L"Reserved", 5, 3, NULL, NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing IA-32 Architecture Machine Check Bank Structure
+ Cf ACPI 6.5 Table 18.4: IA-32 Architecture Machine Check Error Bank Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorIA32ArchMachineCheckBankStructureParser[] = {
+ { L"Bank Number", 1, 0, L"%d", NULL, NULL, NULL, NULL },
+ { L"Clear Status On Initialization", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"Status Data Format", 1, 2, L"%d", NULL, NULL, NULL, NULL },
+ { L"Reserved", 1, 3, NULL, NULL, NULL, NULL, NULL },
+ { L"Control Register MSR Address", 4, 4, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Control Init Data", 8, 8, L"0x%llx", NULL, NULL, NULL, NULL },
+ { L"Status Register MSR Address", 4, 16, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Address Register MSR Address", 4, 20, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Misc Register MSR Address", 4, 24, L"0x%lx", NULL, NULL, NULL, NULL },
+};
+
+/**
+ An ACPI_PARSER array describing the Hardware Error Notification Structure's
+ Configuration Write Enable Field (CWE)
+ Cf ACPI 6.5 Table 18.14: Hardware Error Notification Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorNotificationCweParser[] = {
+ { L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL },
+ { L"Poll Interval", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"Switch To Polling Threshold Value", 1, 2, L"%d", NULL, NULL, NULL, NULL },
+ { L"Switch To Polling Threshold Window", 1, 3, L"%d", NULL, NULL, NULL, NULL },
+ { L"Error Threshold Value", 1, 4, L"%d", NULL, NULL, NULL, NULL },
+ { L"Error Threshold Window", 1, 5, L"%d", NULL, NULL, NULL, NULL },
+ { L"Reserved", 10, 6, L"0x%x", NULL, NULL, NULL, NULL },
+};
+
+/**
+ This function validates the Type field of Hardware Error Notification Structure
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateErrorNotificationType (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 Type;
+
+ Type = *(UINT8 *)Ptr;
+
+ if (Type >
+ EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_SOFTWARE_DELEGATED_EXCEPTION)
+ {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Notification Structure Type must be <= 0x%x.",
+ EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_SOFTWARE_DELEGATED_EXCEPTION
+ );
+ }
+}
+
+/**
+ Dumps flags fields of error source descriptor.
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+STATIC
+VOID
+EFIAPI
+DumpSourceFlags (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ if (Format != NULL) {
+ Print (Format, *(UINT32 *)Ptr);
+ return;
+ }
+
+ Print (L"0x%x\n", *Ptr);
+ ParseAcpiBitFields (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 1,
+ PARSER_PARAMS (HestErrorSourceFlags)
+ );
+}
+
+/**
+ Dumps type fields of Error Notification Structure
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+STATIC
+VOID
+EFIAPI
+DumpErrorNotificationType (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ if (Format != NULL) {
+ Print (Format, *Ptr);
+ return;
+ }
+
+ if (*Ptr <= EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_SOFTWARE_DELEGATED_EXCEPTION) {
+ Print (L"%s(0x%x)", HestErrorNotificationStructureTypeStr[*Ptr]);
+ } else {
+ Print (L"UNKNOWN(0x%x)", HestErrorNotificationStructureTypeStr[*Ptr]);
+ }
+}
+
+/**
+ Dumps Configuration Write Enable fields of Hardware Error Notification Structure.
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+STATIC
+VOID
+EFIAPI
+DumpErrorNotificationCwe (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ if (Format != NULL) {
+ Print (Format, *(UINT32 *)Ptr);
+ return;
+ }
+
+ Print (L"0x%x\n", *Ptr);
+ ParseAcpiBitFields (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 1,
+ PARSER_PARAMS (HestErrorNotificationCweParser)
+ );
+}
+
+/**
+ An ACPI_PARSER array describing the Hardware Error Notification Structure
+ Cf ACPI 6.5 Table 18.14: Hardware Error Notification Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorNotificationParser[] = {
+ { L"Type", 1, 0, NULL, DumpErrorNotificationType, NULL, ValidateErrorNotificationType, NULL },
+ { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"Configuration Write Enable", 2, 2, NULL, DumpErrorNotificationCwe, NULL, NULL, NULL },
+ { L"Pull Interval", 4, 4, L"%d ms", NULL, NULL, NULL, NULL },
+ { L"Vector", 4, 8, L"%d", NULL, NULL, NULL, NULL },
+ { L"Switch To Polling Threshold Value", 4, 12, L"%d", NULL, NULL, NULL, NULL },
+ { L"Switch To Polling Threshold Window", 4, 16, L"%d ms", NULL, NULL, NULL, NULL },
+ { L"Error Threshold Value", 4, 20, L"%d", NULL, NULL, NULL, NULL },
+ { L"Error Threshold Window", 4, 24, L"%d ms", NULL, NULL, NULL, NULL },
+};
+
+/**
+ This function validates reserved bits of
+ pci related Error source structure's bus field.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidatePciBusReservedBits (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ if (*Ptr != 0x00) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: bits[31:24] should must be zero...");
+ }
+}
+
+/**
+ An ACPI_PARSER array describing the PCI related Error Source Bus field.
+**/
+STATIC CONST ACPI_PARSER HestErrorSourcePciCommonBusParser[] = {
+ { L"Bus", 8, 0, L"%d", NULL, NULL, NULL, NULL },
+ { L"Segment Number", 16, 8, L"%d", NULL, NULL, NULL, NULL },
+ { L"Reserved", 8, 24, L"0x%x", NULL, NULL, ValidatePciBusReservedBits, NULL },
+};
+
+/**
+ This function validates the flags field of IA32 related
+ error source descriptor structure.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateIA32ErrorSourceFlags (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 SourceFlags;
+
+ SourceFlags = *(UINT8 *)Ptr;
+
+ if ((SourceFlags &
+ ~(EFI_ACPI_6_5_ERROR_SOURCE_FLAG_FIRMWARE_FIRST |
+ EFI_ACPI_6_5_ERROR_SOURCE_FLAG_GHES_ASSIST)) != 0)
+ {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Invalid IA32 source flags field value...");
+ }
+
+ if (((SourceFlags & EFI_ACPI_6_5_ERROR_SOURCE_FLAG_FIRMWARE_FIRST) != 0) &&
+ ((SourceFlags & EFI_ACPI_6_5_ERROR_SOURCE_FLAG_GHES_ASSIST) != 0))
+ {
+ IncrementErrorCount ();
+ Print (L"\nERROR: GHES_ASSIST should be reserved if FIRMWARE_FIRST is set...");
+ }
+}
+
+/**
+ This function validates the flags field of PCI related
+ error source descriptor structure.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidatePciErrorSourceFlags (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 SourceFlags;
+
+ SourceFlags = *(UINT8 *)Ptr;
+
+ if ((SourceFlags &
+ ~(EFI_ACPI_6_5_ERROR_SOURCE_FLAG_FIRMWARE_FIRST |
+ EFI_ACPI_6_5_ERROR_SOURCE_FLAG_GLOBAL)) != 0)
+ {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Invalid PCI source flags field value...");
+ }
+}
+
+/**
+ This function validates the flags field of Ghes related
+ error source descriptor structure.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateGhesSourceFlags (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 SourceFlags;
+
+ SourceFlags = *(UINT8 *)Ptr;
+
+ if (SourceFlags != 0) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Ghes'source flags should be reserved...");
+ }
+}
+
+/**
+ This function validates the enabled field of error source descriptor
+ structure.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateEnabledField (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ if (*(UINT8 *)Ptr > 1) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Invalid Enabled field value must be either 0 or 1.");
+ }
+}
+
+/**
+ This function validates the number of records to preallocated and
+ max sections per record fields of error source descriptor
+ structure.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateRecordCount (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 RecordCount;
+ BOOLEAN CheckRecordCount;
+
+ RecordCount = *Ptr;
+ CheckRecordCount = ((BOOLEAN)(UINTN)Context);
+
+ if ((CheckRecordCount) && (RecordCount == 0)) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Record count must be >= 1...");
+ }
+}
+
+/**
+ Dumps the notification structure fields.
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+STATIC
+VOID
+EFIAPI
+DumpNotificationStructure (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ UINT32 Offset;
+ UINT32 Size;
+
+ Size = sizeof (EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_STRUCTURE);
+ Print (L"\n");
+ Offset = ParseAcpi (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ Size,
+ PARSER_PARAMS (HestErrorNotificationParser)
+ );
+ if (Offset != Size) {
+ IncrementErrorCount ();
+ Print (L"ERROR: Failed to parse Hardware Error Notification Structure!\n");
+ }
+}
+
+/**
+ Dumps bus field in the PCI related Error Source Structure.
+ from HestTable.
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+STATIC
+VOID
+EFIAPI
+DumpPciBus (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ if (Format != NULL) {
+ Print (Format, *(UINT32 *)Ptr);
+ return;
+ }
+
+ Print (L"0x%x\n", *Ptr);
+ ParseAcpiBitFields (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 1,
+ PARSER_PARAMS (HestErrorSourcePciCommonBusParser)
+ );
+}
+
+/**
+ Dumps the IA32 Arch Machine Check Error Bank structure fields.
+
+ @param [in] HestTable Start pointer to Hest table.
+ @param [in] AcpiTableLength Length of HestTable.
+ @param [in,out] Offset Offset to machine check bank structure
+ from HestTable.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER Invalid Hest Table
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+DumpIA32ArchMachineCheckErrorBankStructure (
+ IN UINT8 *HestTable,
+ UINT32 AcpiTableLength,
+ UINT32 *Offset
+ )
+{
+ UINT8 Idx;
+ UINT8 *IA32BankStructPtr;
+ UINT32 TotalBankStructSize;
+
+ TotalBankStructSize = *mHestIA32HardwareBankCount *
+ sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE);
+
+ if ((*Offset + TotalBankStructSize) > AcpiTableLength) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Not enough data for "
+ "IA-32 Architecture Machine Check Exception Error source.\n"
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Idx = 0; Idx < *mHestIA32HardwareBankCount; Idx++) {
+ IA32BankStructPtr = HestTable + *Offset;
+ ParseAcpi (
+ TRUE,
+ 4,
+ "IA-32 Architecture Machine Check Bank Structure",
+ IA32BankStructPtr,
+ sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE),
+ PARSER_PARAMS (HestErrorIA32ArchMachineCheckBankStructureParser)
+ );
+ *Offset +=
+ sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_ERROR_BANK_STRUCTURE);
+ }
+
+ *mHestIA32HardwareBankCount = 0;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Helper macro to populate the header fields of error source descriptor in the
+ ACPI_PARSER array.
+**/
+#define PARSE_HEST_ERROR_SOURCE_COMMON_HEADER(FlagsValidateFunc, CheckRecordCount) \
+ { L"Type", 2, 0, L"%d", NULL, NULL, NULL, NULL }, \
+ { L"Source Id", 2, 2, L"%d", NULL, NULL, NULL, NULL }, \
+ { L"Reserved", 2, 4, NULL, NULL, NULL, NULL, NULL }, \
+ { L"Flags", 1, 6, NULL, DumpSourceFlags, NULL, \
+ FlagsValidateFunc, NULL }, \
+ { L"Enabled", 1, 7, L"%d", NULL, NULL, ValidateEnabledField, NULL }, \
+ { L"Number of Records to Pre-allocate", 4, 8, L"%d", NULL, NULL, \
+ ValidateRecordCount, (VOID *) ((UINTN) CheckRecordCount) }, \
+ { L"Max Sections Per Record", 4, 12, L"%d", NULL, NULL, \
+ ValidateRecordCount, (VOID *) ((UINTN) CheckRecordCount) }
+
+/**
+ Helper macro to populate the header fields of PCI related
+ error source descriptor in the ACPI_PARSER array.
+**/
+#define PARSE_HEST_PCI_ERROR_SOURCE_COMMON_HEADER() \
+ PARSE_HEST_ERROR_SOURCE_COMMON_HEADER(ValidatePciErrorSourceFlags, TRUE), \
+ { L"Bus", 4, 16, NULL, DumpPciBus, NULL, NULL, NULL }, \
+ { L"Device", 2, 20, L"%d", NULL, NULL, NULL, NULL }, \
+ { L"Function", 2, 22, L"%d", NULL, NULL, NULL, NULL }, \
+ { L"Device Control", 2, 24, L"%d", NULL, NULL, NULL, NULL }, \
+ { L"Reserved", 2, 26, NULL, NULL, NULL, NULL, NULL }, \
+ { L"Uncorrectable Error Mask", 4, 28, L"0x%lx", NULL, NULL, NULL, NULL }, \
+ { L"Uncorrectable Error Severity", 4, 32, L"%d", NULL, NULL, NULL, NULL }, \
+ { L"Correctable Error Mask", 4, 36, L"0x%lx", NULL, NULL, NULL, NULL }, \
+ { L"Advanced Error Capabilities and Control", 4, 40, L"%d", NULL, NULL, \
+ NULL, NULL }
+
+/**
+ Helper macro to populate the header fields of GHES related
+ error source descriptor in the ACPI_PARSER array.
+**/
+#define PARSE_HEST_GHES_ERROR_SOURCE() \
+ { L"Type", 2, 0, L"%d", NULL, NULL, NULL, NULL }, \
+ { L"Source Id", 2, 2, L"%d", NULL, NULL, NULL, NULL }, \
+ { L"Related Source Id", 2, 4, L"0x%x", NULL, NULL, NULL, NULL }, \
+ { L"Flags", 1, 6, L"0x%x", NULL, NULL, ValidateGhesSourceFlags, NULL }, \
+ { L"Enabled", 1, 7, L"%d", NULL, NULL, ValidateEnabledField, NULL }, \
+ { L"Number of Records to Pre-allocate", 4, 8, L"%d", NULL, NULL, \
+ ValidateRecordCount, (VOID *) ((UINTN) TRUE) }, \
+ { L"Max Sections Per Record", 4, 12, L"%d", NULL, NULL, \
+ ValidateRecordCount, (VOID *) ((UINTN) TRUE) }, \
+ { L"Max Raw Data Length", 4, 16, L"%d", NULL, NULL, NULL, NULL }, \
+ { L"Error Status Address", 12, 20, NULL, DumpGas, NULL, NULL, NULL }, \
+ { L"Notification Structure", 28, 32, NULL, DumpNotificationStructure, \
+ NULL, NULL, NULL }, \
+ { L"Error Status Block Length", 4, 60, L"%d", NULL, NULL, NULL, NULL }
+
+/**
+ An ACPI_PARSER array describing the IA-32 Architecture Machine Check Exception
+ error source descriptor.
+ Cf ACPI 6.5 Table 18.3: IA-32 Architecture Machine Check Exception Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorSourceIA32ArchMachineCheckExceptionParser[] = {
+ PARSE_HEST_ERROR_SOURCE_COMMON_HEADER (ValidateIA32ErrorSourceFlags, FALSE),
+ { L"Global Capability Init Data",
+ 8, 16, L"0x%llx", NULL, NULL, NULL, NULL },
+ { L"Global Control Init Data",
+ 8, 24, L"0x%llx", NULL, NULL, NULL, NULL },
+ { L"Number of Hardware Banks",
+ 1, 32, L"%d", NULL, (VOID **)&mHestIA32HardwareBankCount, NULL, NULL },
+ { L"Reserved",
+ 7, 33, NULL, NULL, NULL, NULL, NULL },
+ /// HestErrorIA32ArchMachineCheckBankStructureParser
+ /// ...
+};
+
+/**
+ An ACPI_PARSER array describing the IA-32 Architecture Machine Check Exception
+ error source descriptor.
+ Cf ACPI 6.5 Table 18.5: IA-32 Architecture Machine Check Exception Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorSourceIA32ArchCorrectedMachineCheckParser[] = {
+ PARSE_HEST_ERROR_SOURCE_COMMON_HEADER (ValidateIA32ErrorSourceFlags, TRUE),
+ { L"Notification Structure",
+ 28, 16, NULL, DumpNotificationStructure, NULL, NULL, NULL },
+ { L"Number of Hardware Banks",
+ 1, 44, L"%d", NULL, (VOID **)&mHestIA32HardwareBankCount, NULL, NULL },
+ { L"Reserved",
+ 3, 45, NULL, NULL, NULL, NULL, NULL },
+ /// HestErrorIA32ArchMachineCheckBankStructureParser
+ /// ...
+};
+
+/**
+ An ACPI_PARSER array describing the IA-32 Non-Maskable Interrupt
+ error source descriptor.
+ Cf ACPI 6.5 Table 18.6: IA-32 Architecture NMI Error Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorSourceIA32ArchNonMaskableInterruptParser[] = {
+ { L"Type", 2, 0, L"%d", NULL, NULL, NULL, NULL },
+ { L"Source Id", 2, 2, L"%d", NULL, NULL, NULL, NULL },
+ { L"Reserved", 4, 4, NULL, NULL, NULL, NULL, NULL },
+ { L"Number of Records to Pre-allocate", 4, 8, L"%d", NULL, NULL,
+ ValidateRecordCount, (VOID *)((UINTN)TRUE) },
+ { L"Max Sections Per Record", 4, 12, L"%d", NULL, NULL,
+ ValidateRecordCount, (VOID *)((UINTN)TRUE) },
+ { L"Max Raw Data Length", 4, 16, L"%d", NULL, NULL, NULL, NULL },
+};
+
+/**
+ An ACPI_PARSER array describing the HEST PCIe Root Port AER
+ error source descriptor.
+ Cf ACPI 6.5 Table 18.7: PCI Express Root Port AER Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorSourcePciExpressRootPortAerParser[] = {
+ PARSE_HEST_PCI_ERROR_SOURCE_COMMON_HEADER (),
+ { L"Root Error Command",
+ 4, 44,L"%d", NULL, NULL, NULL, NULL },
+};
+
+/**
+ An ACPI_PARSER array describing the HEST PCIe Device AER
+ error source descriptor.
+ Cf ACPI 6.5 Table 18.8: PCI Express Device AER Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorSourcePciExpressDeviceAerParser[] = {
+ PARSE_HEST_PCI_ERROR_SOURCE_COMMON_HEADER (),
+};
+
+/**
+ An ACPI_PARSER array describing the HEST PCIe/PCI-X Bridge AER
+ error source descriptor.
+ Cf ACPI 6.5 Table 18.9: PCI Express/PCI-X Bridge AER Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorSourcePciExpressBridgeAerParser[] = {
+ PARSE_HEST_PCI_ERROR_SOURCE_COMMON_HEADER (),
+ { L"Secondary Uncorrectable Error Mask",
+ 4, 44, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Secondary Uncorrectable Error Severity",
+ 4, 48, L"%d", NULL, NULL, NULL, NULL },
+ { L"Secondary Advanced Error Capabilities and Control",
+ 4, 52, L"%d", NULL, NULL, NULL, NULL },
+};
+
+/**
+ An ACPI_PARSER array describing the HEST GHES error source descriptor.
+ Cf ACPI 6.5 Table 18.10: Generic Hardware Error Source Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorSourceGhesParser[] = {
+ PARSE_HEST_GHES_ERROR_SOURCE (),
+};
+
+/**
+ An ACPI_PARSER array describing the HEST GHESv2 error source descriptor.
+ Cf ACPI 6.5 Table 18.11: Generic Hardware Error Source version 2 Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorSourceGhesv2Parser[] = {
+ PARSE_HEST_GHES_ERROR_SOURCE (),
+ { L"Read Ack Register", 12, 64, NULL, DumpGas, NULL, NULL, NULL },
+ { L"Read Ack Preserve", 8, 76, L"%llx", NULL, NULL, NULL, NULL },
+ { L"Read Ack Write", 8, 84, L"%llx", NULL, NULL, NULL, NULL },
+};
+
+/**
+ An ACPI_PARSER array describing the IA-32 Architecture Deferred Machine Check
+ error source descriptor.
+ Cf ACPI 6.5 Table 18.15: IA-32 Architecture Deferred Machine Check Structure
+**/
+STATIC CONST ACPI_PARSER HestErrorSourceIA32ArchDeferredMachineCheckParser[] = {
+ PARSE_HEST_ERROR_SOURCE_COMMON_HEADER (ValidateIA32ErrorSourceFlags, TRUE),
+ { L"Notification Structure", 28, 16, NULL, DumpNotificationStructure,
+ NULL, NULL, NULL },
+ { L"Number of Hardware Banks", 1, 44, L"%d", NULL,
+ (VOID **)&mHestIA32HardwareBankCount, NULL, NULL },
+ { L"Reserved", 3, 45, NULL, NULL, NULL,NULL, NULL },
+ /// HestErrorIA32ArchMachineCheckBankStructureParser
+ /// ...
+};
+
+/**
+ This function parses the ACPI HEST table.
+ When trace is enabled this function parses the HEST table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiHest (
+ IN BOOLEAN Trace,
+ IN UINT8 *Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Offset;
+ UINT8 *ErrorSourcePtr;
+ UINT32 ParsedErrorSourceCount;
+ UINT32 CurErrorSourceType;
+
+ if (Trace != TRUE) {
+ return;
+ }
+
+ Offset = ParseAcpi (
+ TRUE,
+ 0,
+ "HEST",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (HestParser)
+ );
+
+ // Validate Error Source Descriptors Count.
+ if (mHestErrorSourceCount == NULL) {
+ IncrementErrorCount ();
+ Print (L"ERROR: Invalid Hardware Error Source Table Header...\n");
+ return;
+ }
+
+ ParsedErrorSourceCount = 0;
+ CurErrorSourceType = EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION;
+
+ while ((Offset < AcpiTableLength) && (ParsedErrorSourceCount < *mHestErrorSourceCount)) {
+ ErrorSourcePtr = Ptr + Offset;
+
+ // Get Type of Error Source Descriptor.
+ ParseAcpi (
+ FALSE,
+ 0,
+ NULL,
+ ErrorSourcePtr,
+ AcpiTableLength - Offset,
+ PARSER_PARAMS (HestErrorSourceTypeParser)
+ );
+
+ // Validate Error Source Descriptors Type.
+ if (mHestErrorSourceType == NULL) {
+ IncrementErrorCount ();
+ Print (L"ERROR: Invalid Error Source Structure...\n");
+ return;
+ }
+
+ if (CurErrorSourceType > *mHestErrorSourceType) {
+ IncrementErrorCount ();
+ Print (L"ERROR: Error Source Structure must be sorted in Type with ascending order...\n");
+ return;
+ }
+
+ switch (*mHestErrorSourceType) {
+ case EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "IA-32 Architecture Machine Check Exception",
+ ErrorSourcePtr,
+ sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE),
+ PARSER_PARAMS (HestErrorSourceIA32ArchMachineCheckExceptionParser)
+ );
+
+ Offset +=
+ sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_MACHINE_CHECK_EXCEPTION_STRUCTURE);
+
+ Status = DumpIA32ArchMachineCheckErrorBankStructure (
+ Ptr,
+ AcpiTableLength,
+ &Offset
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ break;
+ case EFI_ACPI_6_5_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "IA-32 Architecture Corrected Machine Check",
+ ErrorSourcePtr,
+ sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE),
+ PARSER_PARAMS (HestErrorSourceIA32ArchCorrectedMachineCheckParser)
+ );
+
+ Offset +=
+ sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_CORRECTED_MACHINE_CHECK_STRUCTURE);
+
+ Status = DumpIA32ArchMachineCheckErrorBankStructure (
+ Ptr,
+ AcpiTableLength,
+ &Offset
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ break;
+ case EFI_ACPI_6_5_IA32_ARCHITECTURE_NMI_ERROR:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "IA-32 Architecture Non-Maskable Interrupt",
+ ErrorSourcePtr,
+ sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE),
+ PARSER_PARAMS (HestErrorSourceIA32ArchNonMaskableInterruptParser)
+ );
+
+ Offset +=
+ sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_NMI_ERROR_STRUCTURE);
+ break;
+ case EFI_ACPI_6_5_PCI_EXPRESS_ROOT_PORT_AER:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "PCI Express RootPort AER Structure",
+ ErrorSourcePtr,
+ sizeof (EFI_ACPI_6_5_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE),
+ PARSER_PARAMS (HestErrorSourcePciExpressRootPortAerParser)
+ );
+
+ Offset += sizeof (EFI_ACPI_6_5_PCI_EXPRESS_ROOT_PORT_AER_STRUCTURE);
+ break;
+ case EFI_ACPI_6_5_PCI_EXPRESS_DEVICE_AER:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "PCI Express Device AER Structure",
+ ErrorSourcePtr,
+ sizeof (EFI_ACPI_6_5_PCI_EXPRESS_DEVICE_AER_STRUCTURE),
+ PARSER_PARAMS (HestErrorSourcePciExpressDeviceAerParser)
+ );
+
+ Offset += sizeof (EFI_ACPI_6_5_PCI_EXPRESS_DEVICE_AER_STRUCTURE);
+ break;
+ case EFI_ACPI_6_5_PCI_EXPRESS_BRIDGE_AER:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "PCI Express Bridge AER Structure",
+ ErrorSourcePtr,
+ sizeof (EFI_ACPI_6_5_PCI_EXPRESS_BRIDGE_AER_STRUCTURE),
+ PARSER_PARAMS (HestErrorSourcePciExpressBridgeAerParser)
+ );
+
+ Offset += sizeof (EFI_ACPI_6_5_PCI_EXPRESS_BRIDGE_AER_STRUCTURE);
+ break;
+ case EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Generic Hardware Error Source Structure",
+ ErrorSourcePtr,
+ sizeof (EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE),
+ PARSER_PARAMS (HestErrorSourceGhesParser)
+ );
+
+ Offset += sizeof (EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE);
+ break;
+ case EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_VERSION_2:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Generic Hardware Error Source V2 Structure",
+ ErrorSourcePtr,
+ sizeof (
+ EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE
+ ),
+ PARSER_PARAMS (HestErrorSourceGhesv2Parser)
+ );
+
+ Offset +=
+ sizeof (
+ EFI_ACPI_6_5_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE
+ );
+ break;
+ case EFI_ACPI_6_5_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK:
+ ParseAcpi (
+ TRUE,
+ 2,
+ "IA-32 Architecture Deferred Machine Check",
+ ErrorSourcePtr,
+ sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK_STRUCTURE),
+ PARSER_PARAMS (HestErrorSourceIA32ArchDeferredMachineCheckParser)
+ );
+
+ Offset +=
+ sizeof (EFI_ACPI_6_5_IA32_ARCHITECTURE_DEFERRED_MACHINE_CHECK_STRUCTURE),
+
+ Status = DumpIA32ArchMachineCheckErrorBankStructure (
+ Ptr,
+ AcpiTableLength,
+ &Offset
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ break;
+ default:
+ IncrementErrorCount ();
+ Print (L"ERROR: Invalid Error Source Descriptor Type(%d).\n", *mHestErrorSourceType);
+ return;
+ } // switch
+
+ ParsedErrorSourceCount++;
+ } // while
+
+ if (ParsedErrorSourceCount < *mHestErrorSourceCount) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Invalid Error Source Count... Real:%d, ErrorSourceCount:%d\n",
+ ParsedErrorSourceCount,
+ *mHestErrorSourceCount
+ );
+ return;
+ }
+
+ if (Offset < AcpiTableLength) {
+ IncrementErrorCount ();
+ Print (L"ERROR: Invalid Error Source Count, There's more data...\n");
+ return;
+ }
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c
index 2a1357c..8f48927 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c
@@ -1,7 +1,7 @@
/** @file
HMAT table parser
- Copyright (c) 2020, Arm Limited.
+ Copyright (c) 2020 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -54,6 +54,7 @@ STATIC CONST CHAR16 *SllbiNames[] = {
This function validates the Cache Attributes field.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -61,8 +62,9 @@ STATIC
VOID
EFIAPI
ValidateCacheAttributes (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *
@@ -109,13 +111,15 @@ ValidateCacheAttributes (
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
STATIC
VOID
EFIAPI
DumpCacheAttributes (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c
index 1b4c38f..c8ccdd4 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c
@@ -1,6 +1,7 @@
/** @file
HPET table parser
+ Copyright (c) 2024, Arm Limited. All rights reserved.
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -24,7 +25,8 @@ VOID
EFIAPI
DumpHpetPageProtectionFlag (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
if (Format != NULL) {
@@ -71,7 +73,8 @@ VOID
EFIAPI
DumpHpetFlag (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
if (Format != NULL) {
@@ -101,7 +104,8 @@ VOID
EFIAPI
DumpCounterSize (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
if (Format != NULL) {
@@ -121,6 +125,7 @@ DumpCounterSize (
This function validates the flags.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -128,8 +133,9 @@ STATIC
VOID
EFIAPI
ValidateHpetRevId (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if ((*(UINT8 *)Ptr) == 0) {
@@ -163,7 +169,8 @@ VOID
EFIAPI
DumpHpetEventTimerBlockId (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
if (Format != NULL) {
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
index 599cf0e..299ea4f 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
@@ -1,7 +1,7 @@
/** @file
IORT table parser
- Copyright (c) 2016 - 2022, Arm Limited. All rights reserved.
+ Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -46,6 +46,7 @@ STATIC CONST UINT32 *RmrMemDescOffset;
This function validates the ID Mapping array count for the ITS node.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -53,8 +54,9 @@ STATIC
VOID
EFIAPI
ValidateItsIdMappingCount (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*(UINT32 *)Ptr != 0) {
@@ -68,6 +70,7 @@ ValidateItsIdMappingCount (
Monitoring Counter Group (PMCG) node.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -75,8 +78,9 @@ STATIC
VOID
EFIAPI
ValidatePmcgIdMappingCount (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*(UINT32 *)Ptr > 1) {
@@ -89,6 +93,7 @@ ValidatePmcgIdMappingCount (
This function validates the ID Mapping array offset for the ITS node.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -96,8 +101,9 @@ STATIC
VOID
EFIAPI
ValidateItsIdArrayReference (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*(UINT32 *)Ptr != 0) {
@@ -111,6 +117,7 @@ ValidateItsIdArrayReference (
and is 64K aligned.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -118,8 +125,9 @@ STATIC
VOID
EFIAPI
ValidatePhysicalRange (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT64 Value;
@@ -135,6 +143,7 @@ ValidatePhysicalRange (
This function validates that the RMR memory range descriptor count.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -142,8 +151,9 @@ STATIC
VOID
EFIAPI
ValidateRmrMemDescCount (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*(UINT32 *)Ptr == 0) {
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c
index 3a4f246..8f0a454 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c
@@ -1,8 +1,9 @@
/** @file
MADT table parser
- Copyright (c) 2016 - 2023, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
Copyright (c) 2022, AMD Incorporated. All rights reserved.
+ Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -28,6 +29,7 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
This function validates the System Vector Base in the GICD.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -35,8 +37,9 @@ STATIC
VOID
EFIAPI
ValidateGICDSystemVectorBase (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*(UINT32 *)Ptr != 0) {
@@ -51,6 +54,7 @@ ValidateGICDSystemVectorBase (
This function validates the SPE Overflow Interrupt in the GICC.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -58,8 +62,9 @@ STATIC
VOID
EFIAPI
ValidateSpeOverflowInterrupt (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT16 SpeOverflowInterrupt;
@@ -101,6 +106,7 @@ ValidateSpeOverflowInterrupt (
This function validates the TRBE Interrupt in the GICC.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -108,8 +114,9 @@ STATIC
VOID
EFIAPI
ValidateTrbeInterrupt (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT16 TrbeInterrupt;
@@ -140,32 +147,97 @@ ValidateTrbeInterrupt (
}
/**
+ This function dumps the GICC Flags fields.
+ Format string is 2 fields separated by a \0 mapping to 0 or > 0 of
+ the buffer field bit.
+
+ @param [in] Format Format string that is the list of strings to
+ map values to.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+STATIC
+VOID
+EFIAPI
+DumpValue (
+ IN CONST CHAR16 *Format,
+ IN UINT8 *Ptr,
+ IN UINT32 Length OPTIONAL
+ )
+{
+ UINT32 Value;
+ UINTN Len;
+ CONST CHAR16 *Format_Alt;
+
+ Len = StrLen (Format);
+ Format_Alt = Format + Len + 1;
+ Value = *(UINT32 *)Ptr;
+
+ Print (L"%s", Value ? Format : Format_Alt);
+}
+
+STATIC CONST ACPI_PARSER GICCFlagParser[] = {
+ { L"Enabled", 1, 0, L"%d", NULL, NULL, NULL, NULL },
+ { L"Performance Inter. Mode", 1, 1, L"Level Triggered\0Edge Triggered", DumpValue, NULL, NULL, NULL },
+ { L"VGIC Maintenance Inter. Mode", 1, 2, L"Level Triggered\0Edge Triggered", DumpValue, NULL, NULL, NULL },
+ { L"Online Capable", 1, 3, L"%d", NULL, NULL, NULL, NULL },
+ { L"Reserved", 28, 4, L"%d", NULL, NULL, NULL, NULL }
+};
+
+/**
+ This function dumps the GICC Flags fields.
+ Format string is unused.
+
+ @param [in] Format Unused
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+STATIC
+VOID
+EFIAPI
+DumpGicCFlags (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length OPTIONAL
+ )
+{
+ Print (L"0x%X\n", *(UINT32 *)Ptr);
+ ParseAcpiBitFields (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 4,
+ PARSER_PARAMS (GICCFlagParser)
+ );
+}
+
+/**
An ACPI_PARSER array describing the GICC Interrupt Controller Structure.
**/
STATIC CONST ACPI_PARSER GicCParser[] = {
- { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
- { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
-
- { L"CPU Interface Number", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"ACPI Processor UID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Flags", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Parking Protocol Version", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },
-
- { L"Performance Interrupt GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Parked Address", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Physical Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"GICV", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"GICH", 8, 48, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"VGIC Maintenance interrupt", 4, 56, L"0x%x", NULL, NULL, NULL, NULL },
- { L"GICR Base Address", 8, 60, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"MPIDR", 8, 68, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Processor Power Efficiency Class", 1, 76, L"0x%x", NULL, NULL, NULL,
- NULL },
- { L"Reserved", 1, 77, L"0x%x", NULL, NULL, NULL, NULL },
- { L"SPE overflow Interrupt", 2, 78, L"0x%x", NULL, NULL,
+ { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
+
+ { L"CPU Interface Number", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"ACPI Processor UID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Flags", 4, 12, NULL, DumpGicCFlags, NULL, NULL, NULL },
+ { L"Parking Protocol Version", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },
+
+ { L"Performance Interrupt GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Parked Address", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Physical Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"GICV", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"GICH", 8, 48, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"VGIC Maintenance interrupt", 4, 56, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"GICR Base Address", 8, 60, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"MPIDR", 8, 68, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Processor Power Efficiency Class", 1, 76, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Reserved", 1, 77, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"SPE overflow Interrupt", 2, 78, L"0x%x", NULL, NULL,
ValidateSpeOverflowInterrupt, NULL },
- { L"TRBE Interrupt", 2, 80, L"0x%x", NULL, NULL,
+ { L"TRBE Interrupt", 2, 80, L"0x%x", NULL, NULL,
ValidateTrbeInterrupt, NULL }
};
@@ -263,12 +335,14 @@ STATIC CONST ACPI_PARSER LocalApicFlags[] = {
@param [in] Format Optional format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
VOID
EFIAPI
DumpLocalApicBitFlags (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
if (Format != NULL) {
@@ -326,6 +400,92 @@ STATIC CONST ACPI_PARSER LocalX2ApicNmi[] = {
};
/**
+ An ACPI_PARSER array describing the Core Pragrammable Interrupt Controller (CORE PIC) Structure.
+**/
+STATIC CONST ACPI_PARSER CorePic[] = {
+ { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"ACPI Processor ID", 4, 3, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Physical Processor ID", 4, 7, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Flags", 4, 11, L"0x%x", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the Leagcy I/O Programmable Interrupt Controller (LIO PIC) Structure.
+**/
+STATIC CONST ACPI_PARSER LegacyIoPic[] = {
+ { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Base Address", 8, 3, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Size", 2, 11, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Cascade Vector", 2, 13, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Cascade vector mapping", 8, 15, L"0x%lx", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the HyperTransport Programmable Interrupt Controller (HT PIC) Structure.
+**/
+STATIC CONST ACPI_PARSER HyperTransportPic[] = {
+ { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Base Address", 8, 3, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Size", 2, 11, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Cascade Vector", 8, 13, L"0x%lx", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the Extend I/0 Programmable Interrupt Controller (EIO PIC) Structure.
+**/
+STATIC CONST ACPI_PARSER ExtendIoPic[] = {
+ { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Cascade Vector", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Node", 1, 4, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Node Map", 8, 5, L"0x%lx", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the MSI Programmable Interrupt Controller (MSI PIC) Structure.
+**/
+STATIC CONST ACPI_PARSER MsiPic[] = {
+ { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Message Address", 8, 3, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Start", 4, 11, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Count", 4, 15, L"0x%x", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the Bridge I/O Programmable Interrupt Controller (BIO PIC) Structure.
+**/
+STATIC CONST ACPI_PARSER BridgeIoPic[] = {
+ { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Base Address", 8, 3, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Size", 2, 11, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Hardware ID", 2, 13, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"GSI base", 2, 15, L"0x%x", NULL, NULL, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the LPC Programmable Interrupt Controller (LPC PIC) Structure.
+**/
+STATIC CONST ACPI_PARSER LpcPic[] = {
+ { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
+ { L"Version", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Base Address", 8, 3, L"0x%lx", NULL, NULL, NULL, NULL },
+ { L"Size", 2, 11, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Cascade vector", 2, 13, L"0x%x", NULL, NULL, NULL, NULL }
+};
+
+/**
An ACPI_PARSER array describing the ACPI MADT Table.
**/
STATIC CONST ACPI_PARSER MadtParser[] = {
@@ -572,6 +732,97 @@ ParseAcpiMadt (
break;
}
+ case EFI_ACPI_6_5_CORE_PIC:
+ {
+ ParseAcpi (
+ TRUE,
+ 2,
+ "CORE PIC",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (CorePic)
+ );
+ break;
+ }
+
+ case EFI_ACPI_6_5_LIO_PIC:
+ {
+ ParseAcpi (
+ TRUE,
+ 2,
+ "LIO PIC",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (LegacyIoPic)
+ );
+ break;
+ }
+
+ case EFI_ACPI_6_5_HT_PIC:
+ {
+ ParseAcpi (
+ TRUE,
+ 2,
+ "HT PIC",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (HyperTransportPic)
+ );
+ break;
+ }
+
+ case EFI_ACPI_6_5_EIO_PIC:
+ {
+ ParseAcpi (
+ TRUE,
+ 2,
+ "EIO PIC",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (ExtendIoPic)
+ );
+ break;
+ }
+
+ case EFI_ACPI_6_5_MSI_PIC:
+ {
+ ParseAcpi (
+ TRUE,
+ 2,
+ "MSI PIC",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (MsiPic)
+ );
+ break;
+ }
+
+ case EFI_ACPI_6_5_BIO_PIC:
+ {
+ ParseAcpi (
+ TRUE,
+ 2,
+ "BIO PIC",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (BridgeIoPic)
+ );
+ break;
+ }
+
+ case EFI_ACPI_6_5_LPC_PIC:
+ {
+ ParseAcpi (
+ TRUE,
+ 2,
+ "LPC PIC",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (LpcPic)
+ );
+ break;
+ }
+
default:
{
IncrementErrorCount ();
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/MpamParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/MpamParser.c
new file mode 100644
index 0000000..acbb859
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mpam/MpamParser.c
@@ -0,0 +1,1241 @@
+/** @file
+ MPAM table parser
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Specification Reference:
+ - [1] ACPI for Memory System Resource Partitioning and Monitoring 2.0
+ (https://developer.arm.com/documentation/den0065/latest)
+
+ @par Glossary:
+ - MPAM - Memory System Resource Partitioning And Monitoring
+ - MSC - Memory System Component
+ - PCC - Platform Communication Channel
+ - RIS - Resource Instance Selection
+ - SMMU - Arm System Memory Management Unit
+ **/
+
+#include <IndustryStandard/Mpam.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiView.h"
+#include "AcpiViewConfig.h"
+
+// Local variables
+STATIC CONST UINT8 *MscInterfaceType;
+STATIC CONST UINT8 *ResourceLocatorType;
+STATIC UINT32 MpamMscNodeStart;
+STATIC CONST UINT16 *MpamMscNodeLength;
+STATIC CONST UINT32 *NumberOfMscResources;
+STATIC CONST UINT32 *NumberOfFunctionalDependencies;
+STATIC CONST UINT32 *NumberOfInterconnectDescriptors;
+STATIC CONST UINT64 *InterconnectTableOffset;
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+// Array of locator type names. New types should be added keeping the order
+// preserved as locator type is used to index into the array while parsing.
+STATIC CONST CHAR16 *MpamMscLocatorTitles[] = {
+ L"Processor cache",
+ L"Memory",
+ L"SMMU",
+ L"Memory cache",
+ L"ACPI device",
+ L"Interconnect"
+};
+
+/**
+ When the length of the table is insufficient to be parsed, this function could
+ be used to display an appropriate error message.
+
+ @param [in] ErrorMsg Error message string that has to be appended to the
+ main error log. This string could explain the reason
+ why a insufficient length error was encountered in
+ the first place.
+**/
+STATIC
+VOID
+EFIAPI
+MpamLengthError (
+ IN CONST CHAR16 *ErrorMsg
+ )
+{
+ IncrementErrorCount ();
+ Print (L"\nERROR : ");
+ Print (ErrorMsg);
+ Print (
+ L"\nError : Insufficient MPAM MSC Node length. Table length : %u.\n",
+ *(AcpiHdrInfo.Length)
+ );
+}
+
+/**
+ This function validates reserved fields. Any reserved field within the MPAM
+ specification must be 0.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information. For this
+ particular function, context holds the size of the
+ reserved field that needs to be validated.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateReserved (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ while (Length > 0) {
+ if (Ptr[Length-1] != 0) {
+ IncrementErrorCount ();
+ Print (L"\nERROR : Reserved field must be 0\n");
+ break;
+ }
+
+ Length--;
+ }
+}
+
+/**
+ This function validates bit-length reserved fields. Any reserved field within
+ the MPAM specification must be 0.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information. For this
+ particular function, context holds the size of the
+ reserved field that needs to be validated.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateReservedBits (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT32 ByteLength;
+
+ ByteLength = (Length + 7) >> 3;
+ ValidateReserved (Ptr, ByteLength, Context);
+}
+
+/**
+ This function validates the MMIO size within the MSC node body for MPAM ACPI
+ table. MPAM ACPI specification states that the MMIO size for an MSC having PCC
+ type interface should be zero.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information. For this
+ function, context holds the parent/double pointer to a
+ variable holding the interface type. Make sure to call
+ the function accordingly.
+**/
+STATIC
+VOID
+EFIAPI
+ValidateMmioSize (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 InterfaceType;
+ UINT32 MmioSize;
+
+ InterfaceType = *MscInterfaceType;
+
+ if (InterfaceType == EFI_ACPI_MPAM_INTERFACE_PCC) {
+ MmioSize = *((UINT32 *)Ptr);
+
+ if (MmioSize != 0) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: MMIO size must be 0 for PCC interface type. Size - %u\n",
+ MmioSize
+ );
+ }
+ }
+}
+
+/**
+ This function decodes and validates the link type for MPAM's interconnect
+ descriptor. Valid links are of NUMA and PROC type.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information. For this
+ function, context is ignored.
+**/
+STATIC
+VOID
+EFIAPI
+DecodeLinkType (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 LinkType;
+
+ LinkType = *Ptr;
+
+ if (LinkType == EFI_ACPI_MPAM_LINK_TYPE_NUMA) {
+ Print (
+ L" (NUMA)"
+ );
+ } else if (LinkType == EFI_ACPI_MPAM_LINK_TYPE_PROC) {
+ Print (
+ L" (PROC)"
+ );
+ } else {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Invalid link type - %u\n",
+ (UINT32)LinkType
+ );
+ }
+}
+
+/**
+ This function decodes the hardware ID field present within MPAM ACPI table.
+ The specification states that the hardware ID has to be set to zero if not
+ being used.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information. For this
+ function, context is ignored.
+**/
+STATIC
+VOID
+EFIAPI
+DecodeHardwareId (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT64 HardwareId;
+
+ HardwareId = *((UINT64 *)Ptr);
+
+ if (HardwareId != 0) {
+ Print (L" (");
+ Dump8Chars (NULL, Ptr, Length);
+ Print (L")");
+ }
+}
+
+/**
+ This function decodes and validates the interface type for MPAM. Valid
+ interfaces are of MMIO and PCC type.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information. For this
+ function, context is ignored.
+**/
+STATIC
+VOID
+EFIAPI
+DecodeInterfaceType (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 InterfaceType;
+
+ InterfaceType = *Ptr;
+
+ if (InterfaceType == EFI_ACPI_MPAM_INTERFACE_MMIO) {
+ Print (L" (MMIO)");
+ } else if (InterfaceType == EFI_ACPI_MPAM_INTERFACE_PCC) {
+ Print (L" (PCC)");
+ } else {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Invalid interface type - %u\n",
+ (UINT32)InterfaceType
+ );
+ }
+}
+
+/**
+ This function decodes the interrupt mode flag for MPAM. Interrupt mode could
+ either be "edge triggered" or "level triggered".
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information. For this
+ function, context holds the parent/double pointer to a
+ variable holding the interrupt gsiv. Make sure to call
+ the function accordingly.
+**/
+STATIC
+VOID
+EFIAPI
+DecodeInterruptMode (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 InterruptMode;
+
+ InterruptMode = *Ptr;
+
+ if (InterruptMode == EFI_ACPI_MPAM_INTERRUPT_LEVEL_TRIGGERED) {
+ Print (L" (Level triggered)");
+ } else {
+ Print (L" (Edge triggered)");
+ }
+}
+
+/**
+ This function decodes the interrupt type flag for MPAM. Interrupt type could
+ be "wired interrupt". Other values are reserved at this point.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information. For this
+ function, context holds the parent/double pointer to a
+ variable holding the interrupt gsiv. Make sure to call
+ the function accordingly.
+**/
+STATIC
+VOID
+EFIAPI
+DecodeInterruptType (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 InterruptType;
+
+ InterruptType = *Ptr;
+
+ if (InterruptType == EFI_ACPI_MPAM_INTERRUPT_WIRED) {
+ Print (L" (Wired interrupt)");
+ } else {
+ IncrementWarningCount ();
+ Print (L" (Reserved value!)");
+ }
+}
+
+/**
+ This function decodes the interrupt affinity valid flag for MPAM. Interrupt
+ affinity could be either be valid or not.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information. For this
+ function, context holds the parent/double pointer to a
+ variable holding the interrupt gsiv. Make sure to call
+ the function accordingly.
+**/
+STATIC
+VOID
+EFIAPI
+DecodeInterruptAffinityValid (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 InterruptAffinityValid;
+
+ InterruptAffinityValid = *Ptr;
+
+ if (InterruptAffinityValid != EFI_ACPI_MPAM_INTERRUPT_AFFINITY_VALID) {
+ Print (L" (Affinity not valid)");
+ } else {
+ Print (L" (Affinity valid)");
+ }
+}
+
+/**
+ This function decodes the interrupt affinity type flag for MPAM. Interrupt
+ affinity type could either be "Processor affinity" or "Processor container
+ affinity"
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information. For this
+ function, context holds the parent/double pointer to a
+ variable holding the interrupt gsiv. Make sure to call
+ the function accordingly.
+**/
+STATIC
+VOID
+EFIAPI
+DecodeInterruptAffinityType (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 InterruptAffinityType;
+
+ InterruptAffinityType = *Ptr;
+
+ if (InterruptAffinityType == EFI_ACPI_MPAM_INTERRUPT_PROCESSOR_AFFINITY) {
+ Print (L" (Processor affinity)");
+ } else {
+ Print (L" (Processor container affinity)");
+ }
+}
+
+/**
+ This function decodes the locator type for a particular MPAM MSC resource.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
+ @param [in] Context Pointer to context specific information. For this
+ function, context holds the parent/double pointer to a
+ variable holding the interrupt gsiv. Make sure to call
+ the function accordingly.
+**/
+STATIC
+VOID
+EFIAPI
+DecodeLocatorType (
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
+ )
+{
+ UINT8 LocatorType;
+
+ LocatorType = *Ptr;
+
+ if (LocatorType <= EFI_ACPI_MPAM_LOCATION_INTERCONNECT) {
+ Print (L" (%s)", MpamMscLocatorTitles[LocatorType]);
+ } else if (LocatorType == EFI_ACPI_MPAM_LOCATION_UNKNOWN) {
+ Print (L" (Unknown)");
+ } else {
+ Print (L" (Reserved)");
+ }
+}
+
+/**
+ ACPI_PARSER array describing MPAM MSC interrupt flags.
+**/
+STATIC CONST ACPI_PARSER MpamMscInterruptFlagParser[] = {
+ { L"Interrupt Mode", 1, 0, L"%u", NULL, NULL,
+ DecodeInterruptMode, NULL },
+ { L"Interrupt Type", 2, 1, L"%u", NULL, NULL,
+ DecodeInterruptType, NULL },
+ { L"Affinity Type", 1, 3, L"%u", NULL, NULL,
+ DecodeInterruptAffinityType, NULL },
+ { L"Affinity Valid", 1, 4, L"%u", NULL, NULL,
+ DecodeInterruptAffinityValid, NULL },
+ { L"Reserved", 27, 5, NULL, DumpReservedBits, NULL,
+ ValidateReservedBits, NULL }
+};
+
+/**
+ This function traces MPAM MSC Interrupt Flags.
+ If no format string is specified the Format must be NULL.
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+STATIC
+VOID
+EFIAPI
+DumpMpamMscInterruptFlags (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ Print (L"%u\n", *(UINT32 *)Ptr);
+
+ ParseAcpiBitFields (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 4,
+ PARSER_PARAMS (MpamMscInterruptFlagParser)
+ );
+}
+
+/**
+ ACPI_PARSER array describing the MPAM MSC processor cache locator field.
+**/
+STATIC CONST ACPI_PARSER MpamMscProcessorCacheLocatorParser[] = {
+ { L"Cache reference", 8, 0, L"%lu", NULL, NULL, NULL, NULL },
+ { L"Reserved", 4, 8, NULL, DumpReserved, NULL,
+ ValidateReserved, NULL }
+};
+
+/**
+ ACPI_PARSER array describing the MPAM MSC memory locator field.
+**/
+STATIC CONST ACPI_PARSER MpamMscMemoryLocatorParser[] = {
+ { L"Proximity domain", 8, 0, L"%lu", NULL, NULL, NULL, NULL },
+ { L"Reserved", 4, 8, NULL, DumpReserved, NULL,
+ ValidateReserved, NULL }
+};
+
+/**
+ ACPI_PARSER array describing the MPAM MSC SMMU locator field.
+**/
+STATIC CONST ACPI_PARSER MpamMscSMMULocatorParser[] = {
+ { L"SMMU interface", 8, 0, L"%lu", NULL, NULL, NULL, NULL },
+ { L"Reserved", 4, 8, NULL, DumpReserved, NULL,
+ ValidateReserved, NULL }
+};
+
+/**
+ ACPI_PARSER array describing the MPAM MSC memory cache locator field.
+**/
+STATIC CONST ACPI_PARSER MpamMscMemoryCacheLocatorParser[] = {
+ { L"Reserved", 7, 0, NULL, DumpReserved, NULL,
+ ValidateReserved, NULL },
+ { L"Level", 1, 7, L"%u", NULL, NULL,NULL, NULL },
+ { L"Reference", 4, 8, L"%u", NULL, NULL,NULL, NULL }
+};
+
+/**
+ ACPI_PARSER array describing the MPAM MSC ACPI device locator field.
+**/
+STATIC CONST ACPI_PARSER MpamMscAcpiDeviceLocatorParser[] = {
+ { L"ACPI hardware ID", 8, 0, L"0x%lx", NULL, NULL,
+ DecodeHardwareId, NULL },
+ { L"ACPI unique ID", 4, 8, L"%u", NULL, NULL,NULL,NULL }
+};
+
+/**
+ ACPI_PARSER array describing the MPAM MSC interconnect locator field.
+**/
+STATIC CONST ACPI_PARSER MpamMscInterconnectLocatorParser[] = {
+ { L"Interconnect desc tbl offset", 8, 0, L"%lu", NULL,
+ (VOID **)&InterconnectTableOffset, NULL, NULL },
+ { L"Reserved", 4, 8, NULL, DumpReserved,
+ NULL, ValidateReserved, NULL }
+};
+
+/**
+ ACPI_PARSER array describing the MPAM MSC generic resource locator field.
+**/
+STATIC CONST ACPI_PARSER MpamMscGenericLocatorParser[] = {
+ { L"Descriptor1", 8, 0, L"%lu", NULL, NULL, NULL, NULL },
+ { L"Descriptor2", 4, 8, L"%u", NULL, NULL, NULL, NULL }
+};
+
+/**
+ This function parses the locator field within the resource node for ACPI MPAM
+ table. The parsing is based on the locator type field.
+
+ @param [in] Format Optional format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
+**/
+STATIC
+VOID
+EFIAPI
+ParseLocator (
+ IN CONST CHAR16 *Format OPTIONAL,
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ Print (L"\n");
+ switch (*ResourceLocatorType) {
+ case EFI_ACPI_MPAM_LOCATION_PROCESSOR_CACHE:
+ ParseAcpi (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 12,
+ PARSER_PARAMS (MpamMscProcessorCacheLocatorParser)
+ );
+ break;
+ case EFI_ACPI_MPAM_LOCATION_MEMORY:
+ ParseAcpi (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 12,
+ PARSER_PARAMS (MpamMscMemoryLocatorParser)
+ );
+ break;
+ case EFI_ACPI_MPAM_LOCATION_SMMU:
+ ParseAcpi (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 12,
+ PARSER_PARAMS (MpamMscSMMULocatorParser)
+ );
+ break;
+ case EFI_ACPI_MPAM_LOCATION_MEMORY_CACHE:
+ ParseAcpi (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 12,
+ PARSER_PARAMS (MpamMscMemoryCacheLocatorParser)
+ );
+ break;
+ case EFI_ACPI_MPAM_LOCATION_ACPI_DEVICE:
+ ParseAcpi (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 12,
+ PARSER_PARAMS (MpamMscAcpiDeviceLocatorParser)
+ );
+ break;
+ case EFI_ACPI_MPAM_LOCATION_INTERCONNECT:
+ ParseAcpi (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 12,
+ PARSER_PARAMS (MpamMscInterconnectLocatorParser)
+ );
+ break;
+ // For both UNKNOWN and RESERVED locator types, the locator is parsed using
+ // the generic locator parser as the spec does not define any format.
+ case EFI_ACPI_MPAM_LOCATION_UNKNOWN:
+ ParseAcpi (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 12,
+ PARSER_PARAMS (MpamMscGenericLocatorParser)
+ );
+ break;
+ default:
+ Print (L"\nWARNING : Reserved locator type\n");
+ ParseAcpi (
+ TRUE,
+ 2,
+ NULL,
+ Ptr,
+ 12,
+ PARSER_PARAMS (MpamMscGenericLocatorParser)
+ );
+ IncrementWarningCount ();
+ break;
+ } // switch
+}
+
+/**
+ ACPI_PARSER array describing the Generic ACPI MPAM table header.
+**/
+STATIC CONST ACPI_PARSER MpamParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo)
+};
+
+/**
+ ACPI_PARSER array describing the MPAM MSC node object.
+**/
+STATIC CONST ACPI_PARSER MpamMscNodeParser[] = {
+ { L"Length", 2, 0, L"%u", NULL,
+ (VOID **)&MpamMscNodeLength, NULL, NULL },
+ // Once Interface type is decoded, the address of interface type field is
+ // captured into InterfaceType pointer so that it could be used to check if
+ // MMIO Size field is set as per the specification.
+ { L"Interface type", 1, 2, L"0x%x", NULL,
+ (VOID **)&MscInterfaceType, DecodeInterfaceType, NULL },
+ { L"Reserved", 1, 3, NULL, DumpReserved,
+ NULL, ValidateReserved, NULL },
+ { L"Identifier", 4, 4, L"%u", NULL,
+ NULL, NULL, NULL },
+ { L"Base address", 8, 8, L"0x%lx", NULL,
+ NULL, NULL, NULL },
+ { L"MMIO Size", 4, 16, L"0x%x", NULL,
+ NULL, ValidateMmioSize, (VOID **)&MscInterfaceType },
+ { L"Overflow interrupt", 4, 20, L"%u", NULL,
+ NULL, NULL, NULL },
+ { L"Overflow interrupt flags", 4, 24, NULL, DumpMpamMscInterruptFlags,
+ NULL, NULL, NULL },
+ { L"Reserved1", 4, 28, NULL, DumpReserved,
+ NULL, ValidateReserved, NULL },
+ { L"Overflow interrupt affinity", 4, 32, L"0x%x", NULL,
+ NULL, NULL, NULL },
+ { L"Error interrupt", 4, 36, L"%u", NULL,
+ NULL, NULL, NULL },
+ { L"Error interrupt flags", 4, 40, NULL, DumpMpamMscInterruptFlags,
+ NULL, NULL, NULL },
+ { L"Reserved2", 4, 44, NULL, DumpReserved,
+ NULL, ValidateReserved, NULL },
+ { L"Error interrupt affinity", 4, 48, L"0x%x", NULL,
+ NULL, NULL, NULL },
+ { L"MAX_NRDY_USEC", 4, 52, L"0x%x", NULL,
+ NULL, NULL, NULL },
+ { L"Hardware ID of linked device", 8, 56, L"0x%lx", NULL,
+ NULL, DecodeHardwareId, NULL },
+ { L"Instance ID of linked device", 4, 64, L"0x%x", NULL,
+ NULL, NULL, NULL },
+ { L"Number of resource nodes", 4, 68, L"%u", NULL,
+ (VOID **)&NumberOfMscResources, NULL, NULL }
+};
+
+/**
+ ACPI_PARSER array describing the MPAM MSC resource.
+**/
+STATIC CONST ACPI_PARSER MpamMscResourceParser[] = {
+ { L"Identifier", 4, 0, L"%u", NULL,
+ NULL, NULL, NULL },
+ { L"RIS index", 1, 4, L"%u", NULL,
+ NULL, NULL, NULL },
+ { L"Reserved1", 2, 5, NULL, DumpReserved,
+ NULL, ValidateReserved, NULL },
+ { L"Locator type", 1, 7, L"0x%x", NULL,
+ (VOID **)&ResourceLocatorType,
+ DecodeLocatorType, NULL },
+ { L"Locator", 12, 8, NULL, ParseLocator,
+ NULL, NULL, NULL },
+ { L"Number of func dependencies", 4, 20, L"%u", NULL,
+ (VOID **)&NumberOfFunctionalDependencies, NULL, NULL }
+};
+
+/**
+ ACPI_PARSER array describing the MPAM MSC resource's functional dependencies.
+**/
+STATIC CONST ACPI_PARSER MpamMscFunctionalDependencyParser[] = {
+ { L"Producer", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Reserved", 4, 4, NULL, DumpReserved,
+ NULL, ValidateReserved, NULL },
+};
+
+/**
+ ACPI_PARSER array describing the interconnect descriptor table associated with
+ the interconnect locator type.
+**/
+STATIC CONST ACPI_PARSER MpamInterconnectDescriptorTableParser[] = {
+ { L"Signature", 16, 0,
+ L"%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x", Dump16Chars, NULL, NULL, NULL },
+ { L"Number of Interconnect desc", 4, 16,L"0x%x", NULL,
+ (VOID **)&NumberOfInterconnectDescriptors, NULL, NULL }
+};
+
+/**
+ ACPI_PARSER array describing the interconnect descriptor associated with the
+ interconnect locator type.
+**/
+STATIC CONST ACPI_PARSER MpamInterconnectDescriptorParser[] = {
+ { L"Source ID", 4, 0, L"%u", NULL, NULL, NULL, NULL },
+ { L"Destination ID", 4, 4, L"%u", NULL, NULL, NULL, NULL },
+ { L"Link type", 1, 8, L"0x%x", NULL,
+ NULL, DecodeLinkType, NULL },
+ { L"Reserved", 3, 9, NULL, DumpReserved, NULL,
+ ValidateReserved, NULL }
+};
+
+/**
+ PrintBlockTitle could be used to print the title of blocks that
+ appear more than once in the MPAM ACPI table.
+
+ @param [in] Indent Number of spaces to add to the global table
+ indent. The global table indent is 0 by
+ default; however this value is updated on
+ entry to the ParseAcpi() by adding the indent
+ value provided to ParseAcpi() and restored
+ back on exit. Therefore the total indent in
+ the output is dependent on from where this
+ function is called.
+ @param [in] Title Title string to be used for the block.
+ @param [in] Index Index of the block.
+**/
+STATIC
+VOID
+EFIAPI
+PrintBlockTitle (
+ IN UINT32 Indent,
+ IN CONST CHAR16 *Title,
+ IN CONST UINT32 Index
+ )
+{
+ Print (L"\n");
+ PrintFieldName (Indent, Title);
+ Print (L"%u\n\n", Index);
+}
+
+/**
+ This function parses the interconnect descriptor(s) associated with
+ an interconnect type locator object.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in, out] Offset Pointer to current offset within Ptr.
+
+Returns:
+
+ Status
+
+ EFI_SUCCESS MPAM MSC nodes were parsed properly.
+ EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is not
+ long enough to be parsed correctly.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ParseInterconnectDescriptors (
+ IN UINT8 *CONST Ptr,
+ IN CONST UINT32 AcpiTableLength,
+ IN OUT UINT32 *CONST Offset
+ )
+{
+ UINT32 InterconnectDescriptorIndex;
+
+ InterconnectDescriptorIndex = 0;
+
+ if (NumberOfInterconnectDescriptors == NULL) {
+ MpamLengthError (L"Number of interconnect descriptors not set!");
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ while (InterconnectDescriptorIndex < *NumberOfInterconnectDescriptors) {
+ PrintBlockTitle (
+ 6,
+ L"* Interconnect descriptor *",
+ InterconnectDescriptorIndex
+ );
+
+ // Parse interconnect descriptor
+ *Offset += ParseAcpi (
+ TRUE,
+ 4,
+ NULL,
+ Ptr + *Offset,
+ AcpiTableLength - *Offset,
+ PARSER_PARAMS (MpamInterconnectDescriptorParser)
+ );
+
+ InterconnectDescriptorIndex++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function parses the interconnect descriptor table associated with an
+ interconnect type locator object. It also performs necessary validation to
+ make sure the interconnect descriptor is at a valid location.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] Offset Pointer to current offset within Ptr.
+ @param [in] InterconnectOffset Offset to the interconnect descriptor table.
+
+Returns:
+
+ Status
+
+ EFI_SUCCESS MPAM MSC nodes were parsed properly.
+ EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is not
+ long enough to be parsed correctly.
+ EFI_INVALID_PARAMETER The Offset parameter encoded within the Ptr
+ buffer is not valid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ParseInterconnectDescriptorTable (
+ IN UINT8 *CONST Ptr,
+ IN CONST UINT32 AcpiTableLength,
+ IN UINT32 Offset,
+ IN CONST UINT64 InterconnectOffset
+ )
+{
+ EFI_STATUS Status;
+
+ // Lower bound check
+ if (Offset > (MpamMscNodeStart + InterconnectOffset)) {
+ IncrementErrorCount ();
+ Print (L"\nERROR : Parsing Interconnect descriptor table failed!\n");
+ Print (
+ L"ERROR : Offset overlaps with other objects within the MSC. Offset %u.\n",
+ InterconnectOffset
+ );
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Upper bound check
+ if (InterconnectOffset > (*MpamMscNodeLength)) {
+ IncrementErrorCount ();
+ Print (L"\nERROR : Parsing Interconnect descriptor table failed!\n");
+ Print (
+ L"ERROR : Offset falls outside MSC's space. Offset %u.\n",
+ InterconnectOffset
+ );
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // It is safe to cast InterconnectOffset to UINT32 as IntercconnectOffset can
+ // never exceed the MPAM table length which is at max 2 bytes.
+ Offset = MpamMscNodeStart + (UINT32)InterconnectOffset;
+
+ Print (L"\n");
+ PrintFieldName (6, L"* Interconnect desc table *");
+ Print (L"\n\n");
+
+ // Parse interconnect descriptor table
+ Offset += ParseAcpi (
+ TRUE,
+ 4,
+ NULL,
+ Ptr + Offset,
+ AcpiTableLength - Offset,
+ PARSER_PARAMS (MpamInterconnectDescriptorTableParser)
+ );
+
+ Status = ParseInterconnectDescriptors (
+ Ptr,
+ AcpiTableLength,
+ &Offset
+ );
+
+ return Status;
+}
+
+/**
+ This function parses all the MPAM functional dependency nodes within a
+ single resource node.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in, out] Offset Pointer to current offset within Ptr.
+
+Returns:
+
+ Status
+
+ EFI_SUCCESS MPAM MSC nodes were parsed properly.
+ EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is not
+ long enough to be parsed correctly.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ParseMpamMscFunctionalDependencies (
+ IN UINT8 *CONST Ptr,
+ IN CONST UINT32 AcpiTableLength,
+ IN OUT UINT32 *CONST Offset
+ )
+{
+ UINT32 FunctionalDependencyIndex;
+
+ FunctionalDependencyIndex = 0;
+
+ if (NumberOfFunctionalDependencies == NULL) {
+ MpamLengthError (L"Number of functional dependencies not set!");
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ while (FunctionalDependencyIndex < *NumberOfFunctionalDependencies) {
+ PrintBlockTitle (
+ 6,
+ L"* Functional dependency *",
+ FunctionalDependencyIndex
+ );
+
+ // Parse functional dependency
+ *Offset += ParseAcpi (
+ TRUE,
+ 4,
+ NULL,
+ Ptr + *Offset,
+ AcpiTableLength - *Offset,
+ PARSER_PARAMS (MpamMscFunctionalDependencyParser)
+ );
+
+ FunctionalDependencyIndex++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function parses all the MPAM resource nodes within a single MSC
+ node within the MPAM ACPI table. It also invokes helper functions to
+ validate and parse locators and functional dependency descriptors.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] Offset Pointer to current offset within Ptr.
+
+Returns:
+
+ Status
+
+ EFI_SUCCESS MPAM MSC nodes were parsed properly.
+ EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is not
+ long enough to be parsed correctly.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ParseMpamMscResources (
+ IN UINT8 *CONST Ptr,
+ IN CONST UINT32 AcpiTableLength,
+ IN UINT32 Offset
+ )
+{
+ EFI_STATUS Status;
+ UINT32 ResourceIndex;
+
+ ResourceIndex = 0;
+
+ if (NumberOfMscResources == NULL) {
+ MpamLengthError (L"Number of MSC resource not set!");
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ while (ResourceIndex < *NumberOfMscResources) {
+ PrintBlockTitle (
+ 4,
+ L"* Resource *",
+ ResourceIndex
+ );
+
+ // Parse MPAM MSC resources within the MSC body.
+ Offset += ParseAcpi (
+ TRUE,
+ 2,
+ NULL,
+ Ptr + Offset,
+ AcpiTableLength - Offset,
+ PARSER_PARAMS (MpamMscResourceParser)
+ );
+
+ Status = ParseMpamMscFunctionalDependencies (Ptr, AcpiTableLength, &Offset);
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ // If the InterconnectTableOffset field has been set, proceed to parse the
+ // interconnect descriptor table. Please note that the interconnect
+ // descriptors are placed within the MSC node body in the resource specific
+ // region. However since its easier to map an interconnect descriptor to
+ // its corresponding resource, proceed to parse it along with its parent
+ // resource. This design choice is made to keep the trace view as intuitive
+ // as possible.
+ //
+ // +---------------------+
+ // | MPAM ACPI Header |
+ // +---------------------+-------
+ // | MSC Node 0 Hdr | ^
+ // | +-----------------+ | |
+ // | | Res Node 0 | | |
+ // | | +-------------+ | | |
+ // | | | Res Node Hdr| | | |
+ // | | +-------------+ | | |
+ // | | | Res Data | | | |
+ // | | | | | | |
+ // | | | +---------+ | | | | +---------------------------+
+ // | | | | Locator | | | | ..|..| Interconnect locator desc |
+ // | | | | | | | | | | Descriptor Table Offset |--points-to->+
+ // | | | | | | | | | | Reserved [4] | |
+ // | | | +---------+ | | | | +---------------------------+ |
+ // | | | |FnDep Cnt| | | | | |
+ // | | | +---------+ | | | | |
+ // | | | |FnDep 1 | | | | | |
+ // | | | +---------+ | | | Interconnect |
+ // | | | |FnDep 2 | | | | descriptor |
+ // | | | +---------+ | | | table |
+ // | | | |FnDep n | | | | offset |
+ // | | | +---------+ | | | value |
+ // | | +-------------+ | | | |
+ // | +-----------------+ | | |
+ // | ... | | |
+ // | +-----------------+ | | |
+ // | | Res Node N | | | |
+ // | | +-------------+ | | | |
+ // | | | Res Node Hdr| | | | |
+ // | | +-------------+ | | | |
+ // | | | Res Data | | | | |
+ // | | | | | | | |
+ // | | | +---------+ | | | | |
+ // | | | | Locator | | | | | |
+ // | | | | | | | | | |
+ // | | | | | | | | | |
+ // | | | +---------+ | | | | |
+ // | | | |FnDep Cnt| | | | | |
+ // | | | +---------+ | | | | |
+ // | | | |FnDep 1 | | | | | |
+ // | | | +---------+ | | | | |
+ // | | | |FnDep 2 | | | | | |
+ // | | | +---------+ | | | | |
+ // | | | |FnDep n | | | | | |
+ // | | | +---------+ | | | | |
+ // | | +-------------+ | | | |
+ // | +-----------------+ | | |
+ // \ Resource-specific / v |
+ // / data region. \<-----------------------------------------------+
+ // \ /
+ // +---------------------+
+ // | MSC Node 1 Hdr |
+ // | ... |
+ // +---------------------+
+ if ( (*ResourceLocatorType == EFI_ACPI_MPAM_LOCATION_INTERCONNECT)
+ && (InterconnectTableOffset != NULL))
+ {
+ Status = ParseInterconnectDescriptorTable (
+ Ptr,
+ AcpiTableLength,
+ Offset,
+ *InterconnectTableOffset
+ );
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+ }
+
+ ResourceIndex++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function parses all the MPAM MSC nodes within the MPAM ACPI table. It
+ also invokes a helper function to detect and parse resource nodes that maybe
+ present.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in, out] Offset Pointer to the current offset within Ptr.
+
+Returns:
+
+ Status
+
+ EFI_SUCCESS MPAM MSC nodes were parsed properly.
+ EFI_BAD_BUFFER_SIZE The buffer pointer provided as input is not
+ long enough to be parsed correctly.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ParseMpamMscNodes (
+ IN UINT8 *CONST Ptr,
+ IN CONST UINT32 AcpiTableLength,
+ IN OUT UINT32 *CONST Offset
+ )
+{
+ EFI_STATUS Status;
+ UINT32 MscIndex;
+
+ MscIndex = 0;
+
+ while (*Offset < AcpiTableLength) {
+ MpamMscNodeStart = *Offset;
+
+ PrintBlockTitle (2, L"* MSC *", MscIndex);
+ // Parse MPAM MSC node
+ *Offset += ParseAcpi (
+ TRUE,
+ 0,
+ NULL,
+ Ptr + *Offset,
+ AcpiTableLength - *Offset,
+ PARSER_PARAMS (MpamMscNodeParser)
+ );
+
+ if (MpamMscNodeLength == NULL) {
+ MpamLengthError (L"MPAM MSC node length not set!");
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ if (*MpamMscNodeLength < sizeof (EFI_ACPI_MPAM_MSC_NODE)) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: MSC length should be at least the size of node body! ");
+ Print (L"MSC Length %u\n", *MpamMscNodeLength);
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ // Parse MPAM MSC resources within the MSC body
+ Status = ParseMpamMscResources (Ptr, AcpiTableLength, *Offset);
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ *Offset = MpamMscNodeStart + *MpamMscNodeLength;
+ MscIndex++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function parses the MPAM ACPI table's generic header. It also invokes a
+ sub routine that would help with parsing rest of the table.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiMpam (
+ IN BOOLEAN Trace,
+ IN UINT8 *Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Offset;
+
+ if (!Trace) {
+ return;
+ }
+
+ // Parse generic table header
+ Offset = ParseAcpi (
+ TRUE,
+ 0,
+ "MPAM",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (MpamParser)
+ );
+
+ Status = ParseMpamMscNodes (
+ Ptr,
+ AcpiTableLength,
+ &Offset
+ );
+
+ if (Status == EFI_SUCCESS) {
+ // Check if the length of all MPAM MSCs with the header, matches with the
+ // ACPI table's length field.
+ if (*(AcpiHdrInfo.Length) != Offset) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Length mismatch! : ");
+ Print (L"MSC Length total != MPAM table length.");
+ Print (
+ L"Table length : %u MSC total : %u\n",
+ *(AcpiHdrInfo.Length),
+ Offset
+ );
+ }
+ }
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
index 8ad3909..43c6a9f 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c
@@ -1,7 +1,7 @@
/** @file
PCCT table parser
- Copyright (c) 2021, Arm Limited.
+ Copyright (c) 2021 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -28,6 +28,7 @@ STATIC UINT8 *ExtendedPccSubspaceInterruptFlags;
This function validates the length coded on 4 bytes of a shared memory range
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -35,8 +36,9 @@ STATIC
VOID
EFIAPI
ValidateRangeLength4 (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*(UINT32 *)Ptr < MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN) {
@@ -54,6 +56,7 @@ ValidateRangeLength4 (
This function validates the length coded on 8 bytes of a shared memory range
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -61,8 +64,9 @@ STATIC
VOID
EFIAPI
ValidateRangeLength8 (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*(UINT64 *)Ptr <= MIN_MEMORY_RANGE_LENGTH) {
@@ -80,6 +84,7 @@ ValidateRangeLength8 (
This function validates address space for Memory/IO GAS.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -87,8 +92,9 @@ STATIC
VOID
EFIAPI
ValidatePccMemoryIoGas (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
switch (*(UINT8 *)Ptr) {
@@ -107,6 +113,7 @@ ValidatePccMemoryIoGas (
This function validates address space for structures of types other than 0.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -114,8 +121,9 @@ STATIC
VOID
EFIAPI
ValidatePccGas (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
switch (*(UINT8 *)Ptr) {
@@ -135,6 +143,7 @@ ValidatePccGas (
This function validates doorbell address space for type 4 structure.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -142,8 +151,9 @@ STATIC
VOID
EFIAPI
ValidatePccDoorbellGas (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
// For responder subspaces this field is optional, if not present the field
@@ -158,7 +168,7 @@ ValidatePccDoorbellGas (
}
}
- ValidatePccGas (Ptr, Context);
+ ValidatePccGas (Ptr, Length, Context);
}
/**
@@ -166,6 +176,7 @@ ValidatePccDoorbellGas (
type 4 structure.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -173,8 +184,9 @@ STATIC
VOID
EFIAPI
ValidatePccIntAckGas (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
// If the subspace does not support interrupts or the interrupt is
@@ -196,13 +208,14 @@ ValidatePccIntAckGas (
}
}
- ValidatePccGas (Ptr, Context);
+ ValidatePccGas (Ptr, Length, Context);
}
/**
This function validates error status address space for type 4 structure.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -210,8 +223,9 @@ STATIC
VOID
EFIAPI
ValidatePccErrStatusGas (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
// This field is ignored by the OSPM on responder channels.
@@ -219,13 +233,14 @@ ValidatePccErrStatusGas (
return;
}
- ValidatePccGas (Ptr, Context);
+ ValidatePccGas (Ptr, Length, Context);
}
/**
This function validates platform interrupt flags for type 4 structure.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -233,8 +248,9 @@ STATIC
VOID
EFIAPI
ValidatePlatInterrupt (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
// If a responder subspace is present in the PCCT, then the global Platform
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
index 5377764..fabe057 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c
@@ -1,7 +1,7 @@
/** @file
PPTT table parser
- Copyright (c) 2019 - 2021, ARM Limited. All rights reserved.
+ Copyright (c) 2019 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -52,6 +52,7 @@ LogCacheFlagError (
This function validates the Cache Type Structure (Type 1) Cache Flags field.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -59,8 +60,9 @@ STATIC
VOID
EFIAPI
ValidateCacheFlags (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
@@ -115,6 +117,7 @@ ValidateCacheFlags (
field.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -122,8 +125,9 @@ STATIC
VOID
EFIAPI
ValidateCacheNumberOfSets (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT32 NumberOfSets;
@@ -166,6 +170,7 @@ ValidateCacheNumberOfSets (
field.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -173,8 +178,9 @@ STATIC
VOID
EFIAPI
ValidateCacheAssociativity (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT8 Associativity;
@@ -192,6 +198,7 @@ ValidateCacheAssociativity (
This function validates the Cache Type Structure (Type 1) Line size field.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -199,8 +206,9 @@ STATIC
VOID
EFIAPI
ValidateCacheLineSize (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
@@ -237,6 +245,7 @@ ValidateCacheLineSize (
This function validates the Cache Type Structure (Type 1) Cache ID field.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -244,8 +253,9 @@ STATIC
VOID
EFIAPI
ValidateCacheId (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT32 CacheId;
@@ -276,6 +286,7 @@ ValidateCacheId (
This function validates the Cache Type Structure (Type 1) Attributes field.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -283,8 +294,9 @@ STATIC
VOID
EFIAPI
ValidateCacheAttributes (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
// Reference: Advanced Configuration and Power Interface (ACPI) Specification
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ras2/Ras2Parser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ras2/Ras2Parser.c
new file mode 100644
index 0000000..9c61b96
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ras2/Ras2Parser.c
@@ -0,0 +1,118 @@
+/** @file
+ RAS2 table parser
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.5 Specification - August 2022
+**/
+
+#include <Library/PrintLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiView.h"
+
+// Maximum Memory Domain matrix print size.
+#define MAX_MEMORY_DOMAIN_TARGET_PRINT_MATRIX 10
+
+// Local variables
+STATIC CONST UINT16 *Ras2PccDescriptors;
+
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/**
+ An ACPI_PARSER array describing the ACPI RAS2 Table.
+*/
+STATIC CONST ACPI_PARSER Ras2Parser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ { L"Reserved", 2, 36, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"PCC Descriptors", 2, 38, L"%d", NULL, (VOID **)&Ras2PccDescriptors, NULL, NULL }
+};
+
+/**
+ An ACPI_PARSER array describing the RAS2 PCC ID Entry
+*/
+STATIC CONST ACPI_PARSER Ras2StructurePccDescriptor[] = {
+ { L"PCC ID", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Reserved", 1, 1, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Reserved", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Feature Type", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
+ { L"Instance", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }
+};
+
+STATIC
+VOID
+DumpPccEntry (
+ IN UINT8 *Ptr,
+ IN UINT32 Length
+ )
+{
+ ParseAcpi (
+ TRUE,
+ 2,
+ "PCC Descriptor Entry",
+ Ptr,
+ Length,
+ PARSER_PARAMS (Ras2StructurePccDescriptor)
+ );
+}
+
+/**
+ This function parses the ACPI RAS2 table.
+ When trace is enabled this function parses the RAS2 table and
+ traces the ACPI table fields.
+
+ This function parses the following RAS2 structures:
+ - Pcc Instries
+ - Entry Pcc ID
+ - Entry Feature Type
+ - Entry Pcc Instance
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+**/
+VOID
+EFIAPI
+ParseAcpiRas2 (
+ IN BOOLEAN Trace,
+ IN UINT8 *Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+
+ if (!Trace) {
+ return;
+ }
+
+ // Parse ACPI Header + RAS2 "fixed" fields
+ Offset = ParseAcpi (
+ Trace,
+ 0,
+ "RAS2",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (Ras2Parser)
+ );
+
+ // Table is too small to contain data
+ if (Offset >= AcpiTableLength) {
+ return;
+ }
+
+ // Loop over rest of table for PCC Entries and dump them
+ while (Offset <= (AcpiTableLength - sizeof (EFI_ACPI_RAS2_PCC_DESCRIPTOR))) {
+ DumpPccEntry (
+ Ptr + Offset,
+ sizeof (EFI_ACPI_RAS2_PCC_DESCRIPTOR)
+ );
+ Offset += sizeof (EFI_ACPI_RAS2_PCC_DESCRIPTOR);
+ } // while
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c
index bddf276..895258b 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c
@@ -1,7 +1,7 @@
/** @file
RSDP table parser
- Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -19,6 +19,7 @@ STATIC CONST UINT64 *XsdtAddress;
This function validates the RSDT Address.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -26,8 +27,9 @@ STATIC
VOID
EFIAPI
ValidateRsdtAddress (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
@@ -55,6 +57,7 @@ ValidateRsdtAddress (
This function validates the XSDT Address.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -62,8 +65,9 @@ STATIC
VOID
EFIAPI
ValidateXsdtAddress (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c
index e5267b1..d172a55 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c
@@ -1,7 +1,7 @@
/** @file
SPCR table parser
- Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -22,6 +22,7 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
This function validates the Interrupt Type.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -29,8 +30,9 @@ STATIC
VOID
EFIAPI
ValidateInterruptType (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
@@ -55,6 +57,7 @@ ValidateInterruptType (
This function validates the Irq.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -62,8 +65,9 @@ STATIC
VOID
EFIAPI
ValidateIrq (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c
index 2980704..7bae94c 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c
@@ -1,7 +1,7 @@
/** @file
SRAT table parser
- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
+ Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
@@ -25,6 +25,7 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
This function validates the Reserved field in the SRAT table header.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -32,8 +33,9 @@ STATIC
VOID
EFIAPI
ValidateSratReserved (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
if (*(UINT32 *)Ptr != 1) {
@@ -47,6 +49,7 @@ ValidateSratReserved (
Affinity Structure.
@param [in] Ptr Pointer to the start of the field data.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -54,8 +57,9 @@ STATIC
VOID
EFIAPI
ValidateSratDeviceHandleType (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT8 DeviceHandleType;
@@ -77,13 +81,15 @@ ValidateSratDeviceHandleType (
@param [in] Format Format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
STATIC
VOID
EFIAPI
DumpSratPciBdfNumber (
IN CONST CHAR16 *Format,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];
@@ -165,13 +171,15 @@ STATIC CONST ACPI_PARSER SratDeviceHandlePciParser[] = {
@param [in] Format Format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
STATIC
VOID
EFIAPI
DumpSratDeviceHandle (
IN CONST CHAR16 *Format,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
if (SratDeviceHandleType == NULL) {
@@ -208,13 +216,15 @@ DumpSratDeviceHandle (
@param [in] Format Format string for tracing the data.
@param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
**/
STATIC
VOID
EFIAPI
DumpSratApicProximity (
IN CONST CHAR16 *Format,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
UINT32 ProximityDomain;
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c
index 3c7252b..4433c04 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c
@@ -1,6 +1,7 @@
/** @file
WSMT table parser
+ Copyright (c) 2024, Arm Limited. All rights reserved.
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -17,7 +18,8 @@ STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
/**
This function validates the WSMT Protection flag.
- @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
@@ -26,8 +28,9 @@ STATIC
VOID
EFIAPI
ValidateWsmtProtectionFlag (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT32 ProtectionFlag;
@@ -49,7 +52,8 @@ ValidateWsmtProtectionFlag (
/**
This function validates the reserved bits in the WSMT Protection flag.
- @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the field.
@param [in] Context Pointer to context specific information e.g. this
could be a pointer to the ACPI table header.
**/
@@ -57,8 +61,9 @@ STATIC
VOID
EFIAPI
ValidateReserved (
- IN UINT8 *Ptr,
- IN VOID *Context
+ IN UINT8 *Ptr,
+ IN UINT32 Length,
+ IN VOID *Context
)
{
UINT32 ProtectionFlag;
@@ -92,7 +97,8 @@ VOID
EFIAPI
DumpWsmtProtectionFlag (
IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
+ IN UINT8 *Ptr,
+ IN UINT32 Length
)
{
if (Format != NULL) {
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
index 0bdf068..5e73a39 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
@@ -2,7 +2,7 @@
Main file for 'acpiview' Shell command function.
Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
- Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
+ Copyright (c) 2016 - 2023, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -54,20 +54,24 @@ ACPI_TABLE_PARSER ParserList[] = {
{ EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, ParseAcpiDbg2 },
{ EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
ParseAcpiDsdt },
+ { EFI_ACPI_6_5_ERROR_INJECTION_TABLE_SIGNATURE, ParseAcpiEinj },
{ EFI_ACPI_6_4_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE, ParseAcpiErst },
{ EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, ParseAcpiFacs },
{ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiFadt },
{ EFI_ACPI_6_4_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiGtdt },
+ { EFI_ACPI_6_5_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE, ParseAcpiHest },
{ EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE, ParseAcpiHmat },
{ EFI_ACPI_6_5_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE, ParseAcpiHpet },
{ EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE, ParseAcpiIort },
{ EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiMadt },
{ EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
ParseAcpiMcfg },
+ { EFI_ACPI_MEMORY_SYSTEM_RESOURCE_PARTITIONING_AND_MONITORING_TABLE_SIGNATURE, ParseAcpiMpam },
{ EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
ParseAcpiPcct },
{ EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
ParseAcpiPptt },
+ { EFI_ACPI_6_5_ACPI_RAS2_FEATURE_TABLE_SIGNATURE, ParseAcpiRas2 },
{ RSDP_TABLE_INFO, ParseAcpiRsdp },
{ EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE, ParseAcpiSlit },
{ EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, ParseAcpiSpcr },
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
index e623661..7ef8b0a 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
@@ -2,7 +2,7 @@
# Provides Shell 'acpiview' command functions
#
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
-# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
+# Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -33,20 +33,24 @@
Parsers/Bgrt/BgrtParser.c
Parsers/Dbg2/Dbg2Parser.c
Parsers/Dsdt/DsdtParser.c
+ Parsers/Einj/EinjParser.c
Parsers/Erst/ErstParser.c
Parsers/Facs/FacsParser.c
Parsers/Fadt/FadtParser.c
Parsers/Gtdt/GtdtParser.c
+ Parsers/Hest/HestParser.c
Parsers/Hmat/HmatParser.c
Parsers/Hpet/HpetParser.c
Parsers/Iort/IortParser.c
Parsers/Madt/MadtParser.c
Parsers/Madt/MadtParser.h
Parsers/Mcfg/McfgParser.c
+ Parsers/Mpam/MpamParser.c
Parsers/Pcct/PcctParser.c
Parsers/Pcct/PcctParser.h
Parsers/Pptt/PpttParser.c
Parsers/Pptt/PpttParser.h
+ Parsers/Ras2/Ras2Parser.c
Parsers/Rsdp/RsdpParser.c
Parsers/Slit/SlitParser.c
Parsers/Spcr/SpcrParser.c
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
index e4a9dd5..4079a8e 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
@@ -1,6 +1,6 @@
// /**
//
-// Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
+// Copyright (c) 2016 - 2023, Arm Limited. All rights reserved.<BR>
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
// Module Name:
@@ -89,6 +89,7 @@
" HMAT - Heterogeneous Memory Attributes Table\r\n"
" IORT - IO Remapping Table\r\n"
" MCFG - Memory Mapped Config Space Base Address Description Table\r\n"
+" MPAM - Memory System Resource Partitioning and Monitoring Table\r\n"
" PPTT - Processor Properties Topology Table\r\n"
" RSDP - Root System Description Pointer\r\n"
" SLIT - System Locality Information Table\r\n"
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c
index a609971..046cfd5 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Dmem.c
@@ -19,6 +19,7 @@
#include <Guid/SystemResourceTable.h>
#include <Guid/DebugImageInfoTable.h>
#include <Guid/ImageAuthentication.h>
+#include <Guid/ConformanceProfiles.h>
/**
Make a printable character.
@@ -84,9 +85,267 @@ DisplayMmioMemory (
return (ShellStatus);
}
+/**
+ Display the RtPropertiesTable entries
+
+ @param[in] Address The pointer to the RtPropertiesTable.
+**/
+SHELL_STATUS
+DisplayRtProperties (
+ IN UINT64 Address
+ )
+{
+ EFI_RT_PROPERTIES_TABLE *RtPropertiesTable;
+ UINT32 RtServices;
+ SHELL_STATUS ShellStatus;
+ EFI_STATUS Status;
+
+ ShellStatus = SHELL_SUCCESS;
+
+ if (Address != 0) {
+ EfiGetSystemConfigurationTable (&gEfiRtPropertiesTableGuid, (VOID **)&RtPropertiesTable);
+
+ RtServices = (UINT32)RtPropertiesTable->RuntimeServicesSupported;
+ Status = ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_DMEM_RT_PROPERTIES),
+ gShellDebug1HiiHandle,
+ EFI_RT_PROPERTIES_TABLE_VERSION,
+ (RtServices & EFI_RT_SUPPORTED_GET_TIME) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_SET_TIME) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_GET_WAKEUP_TIME) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_SET_WAKEUP_TIME) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_GET_VARIABLE) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_SET_VARIABLE) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_SET_VIRTUAL_ADDRESS_MAP) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_CONVERT_POINTER) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_GET_NEXT_HIGH_MONOTONIC_COUNT) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_RESET_SYSTEM) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_UPDATE_CAPSULE) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_QUERY_CAPSULE_CAPABILITIES) ? 1 : 0,
+ (RtServices & EFI_RT_SUPPORTED_QUERY_VARIABLE_INFO) ? 1 : 0
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_ABORTED;
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_ERR_GET_FAIL), gShellDebug1HiiHandle, L"RtPropertiesTable");
+ }
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_ERR_NOT_FOUND), gShellDebug1HiiHandle, L"RtPropertiesTable");
+ }
+
+ return (ShellStatus);
+}
+
+/**
+ Retrieve the ImageExecutionTable Entry ImageName from ImagePath
+
+ @param[in] FileName The full path of the image.
+ @param[out] BaseName The name of the image.
+**/
+EFI_STATUS
+GetBaseName (
+ IN CHAR16 *FileName,
+ OUT CHAR16 **BaseName
+ )
+{
+ UINTN StrLen;
+ CHAR16 *StrTail;
+
+ StrLen = StrSize (FileName);
+
+ for (StrTail = FileName + StrLen - 1; StrTail != FileName && *StrTail != L'\\'; StrTail--) {
+ }
+
+ if (StrTail == FileName) {
+ return EFI_NOT_FOUND;
+ }
+
+ *BaseName = StrTail+1;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Retrieve the ImageExecutionTable entries.
+**/
+EFI_STATUS
+GetImageExecutionInfo (
+ )
+{
+ EFI_STATUS Status;
+ EFI_IMAGE_EXECUTION_INFO_TABLE *ExecInfoTablePtr;
+ EFI_IMAGE_EXECUTION_INFO *InfoPtr;
+ CHAR8 *ptr;
+ CHAR16 *ImagePath;
+ CHAR16 *ImageName;
+ UINTN Image;
+ UINTN *NumberOfImages;
+ CHAR16 *ActionType;
+
+ EfiGetSystemConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID **)&ExecInfoTablePtr);
+
+ NumberOfImages = &ExecInfoTablePtr->NumberOfImages;
+
+ ptr = (CHAR8 *)ExecInfoTablePtr + 1;
+
+ for (Image = 0; Image < *NumberOfImages; Image++, ptr += InfoPtr->InfoSize) {
+ InfoPtr = (EFI_IMAGE_EXECUTION_INFO *)ptr;
+ ImagePath = (CHAR16 *)(InfoPtr + 1);
+
+ GetBaseName (ImagePath, &ImageName);
+
+ switch (InfoPtr->Action) {
+ case EFI_IMAGE_EXECUTION_AUTHENTICATION:
+ ActionType = L"AUTHENTICATION";
+ break;
+ case EFI_IMAGE_EXECUTION_AUTH_UNTESTED:
+ ActionType = L"AUTH_UNTESTED";
+ break;
+ case EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED:
+ ActionType = L"AUTH_SIG_FAILED";
+ break;
+ case EFI_IMAGE_EXECUTION_AUTH_SIG_PASSED:
+ ActionType = L"AUTH_SIG_PASSED";
+ break;
+ case EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND:
+ ActionType = L"AUTH_SIG_NOT_FOUND";
+ break;
+ case EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND:
+ ActionType = L"AUTH_SIG_FOUND";
+ break;
+ case EFI_IMAGE_EXECUTION_POLICY_FAILED:
+ ActionType = L"POLICY_FAILED";
+ break;
+ case EFI_IMAGE_EXECUTION_INITIALIZED:
+ ActionType = L"INITIALIZED";
+ break;
+ default:
+ ActionType = L"invalid action";
+ }
+
+ Status = ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_DMEM_IMG_EXE_ENTRY),
+ gShellDebug1HiiHandle,
+ ImageName,
+ ActionType
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Display the ImageExecutionTable entries
+
+ @param[in] Address The pointer to the ImageExecutionTable.
+**/
+SHELL_STATUS
+DisplayImageExecutionEntries (
+ IN UINT64 Address
+ )
+{
+ SHELL_STATUS ShellStatus;
+ EFI_STATUS Status;
+
+ ShellStatus = SHELL_SUCCESS;
+
+ if (Address != 0) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_IMG_EXE_TABLE), gShellDebug1HiiHandle);
+ Status = GetImageExecutionInfo ();
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_ABORTED;
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_ERR_GET_FAIL), gShellDebug1HiiHandle, L"ImageExecutionTable");
+ }
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_ERR_NOT_FOUND), gShellDebug1HiiHandle, L"ImageExecutionTable");
+ }
+
+ return (ShellStatus);
+}
+
+/**
+ Display the ConformanceProfileTable entries
+
+ @param[in] Address The pointer to the ConformanceProfileTable.
+**/
+SHELL_STATUS
+DisplayConformanceProfiles (
+ IN UINT64 Address
+ )
+{
+ SHELL_STATUS ShellStatus;
+ EFI_STATUS Status;
+ EFI_GUID *EntryGuid;
+ CHAR16 *GuidName;
+ UINTN Profile;
+ EFI_CONFORMANCE_PROFILES_TABLE *ConfProfTable;
+
+ ShellStatus = SHELL_SUCCESS;
+
+ if (Address != 0) {
+ EfiGetSystemConfigurationTable (&gEfiConfProfilesTableGuid, (VOID **)&ConfProfTable);
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_CONF_PRO_TABLE), gShellDebug1HiiHandle);
+
+ EntryGuid = (EFI_GUID *)(ConfProfTable + 1);
+
+ for (Profile = 0; Profile < ConfProfTable->NumberOfProfiles; Profile++, EntryGuid++) {
+ GuidName = L"Unknown_Profile";
+
+ if (CompareGuid (EntryGuid, &gEfiConfProfilesUefiSpecGuid)) {
+ GuidName = L"EFI_CONFORMANCE_PROFILE_UEFI_SPEC_GUID";
+ }
+
+ if (CompareGuid (EntryGuid, &gEfiConfProfilesEbbrSpec21Guid)) {
+ GuidName = L"EBBR_2.1";
+ }
+
+ if (CompareGuid (EntryGuid, &gEfiConfProfilesEbbrSpec22Guid)) {
+ GuidName = L"EBBR_2.2";
+ }
+
+ Status = ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_DMEM_CONF_PRO_ROW),
+ gShellDebug1HiiHandle,
+ GuidName,
+ EntryGuid
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_ABORTED;
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_ERR_GET_FAIL), gShellDebug1HiiHandle, L"ComformanceProfilesTable");
+ }
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DMEM_CONF_PRO_TABLE), gShellDebug1HiiHandle);
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_DMEM_CONF_PRO_ROW),
+ gShellDebug1HiiHandle,
+ L"EFI_CONFORMANCE_PROFILES_UEFI_SPEC_GUID",
+ &gEfiConfProfilesUefiSpecGuid
+ );
+ }
+
+ return (ShellStatus);
+}
+
STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-mmio", TypeFlag },
- { NULL, TypeMax }
+ { L"-mmio", TypeFlag },
+ { L"-verbose", TypeFlag },
+ { NULL, TypeMax }
};
/**
@@ -273,6 +532,11 @@ ShellCommandRunDmem (
HiiDatabaseExportBufferAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable;
continue;
}
+
+ if (CompareGuid (&gST->ConfigurationTable[TableWalker].VendorGuid, &gEfiConfProfilesTableGuid)) {
+ ConformanceProfileTableAddress = (UINT64)(UINTN)gST->ConfigurationTable[TableWalker].VendorTable;
+ continue;
+ }
}
ShellPrintHiiEx (
@@ -308,6 +572,20 @@ ShellCommandRunDmem (
ConformanceProfileTableAddress
);
}
+
+ if (ShellCommandLineGetFlag (Package, L"-verbose")) {
+ if (ShellStatus == SHELL_SUCCESS) {
+ ShellStatus = DisplayRtProperties (RtPropertiesTableAddress);
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ ShellStatus = DisplayImageExecutionEntries (ImageExecutionTableAddress);
+ }
+
+ if (ShellStatus == SHELL_SUCCESS) {
+ ShellStatus = DisplayConformanceProfiles (ConformanceProfileTableAddress);
+ }
+ }
} else {
ShellStatus = DisplayMmioMemory (Address, (UINTN)Size);
}
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c
index 35369f0..2ee2bb4 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/PrintInfo.c
@@ -524,6 +524,10 @@ SmbiosPrintStructure (
ShellPrintEx (-1, -1, L"Thread Enabled: %u\n", Struct->Type4->ThreadEnabled);
}
+ if (AE_SMBIOS_VERSION (0x3, 0x8) && (Struct->Hdr->Length > 0x30)) {
+ ShellPrintEx (-1, -1, L"Socket Type: %a\n", LibGetSmbiosString (Struct, Struct->Type4->SocketType));
+ }
+
break;
//
@@ -903,6 +907,13 @@ SmbiosPrintStructure (
ShellPrintEx (-1, -1, L"Extended Configured Memory Speed: 0x%x\n", Struct->Type17->ExtendedConfiguredMemorySpeed);
}
+ if (AE_SMBIOS_VERSION (0x3, 0x7) && (Struct->Hdr->Length > 0x5C)) {
+ ShellPrintEx (-1, -1, L"PMIC0 Manufacturer ID: 0x%x\n", Struct->Type17->Pmic0ManufacturerID);
+ ShellPrintEx (-1, -1, L"PMIC0 Revision Number: 0x%x\n", Struct->Type17->Pmic0RevisionNumber);
+ ShellPrintEx (-1, -1, L"RCD Manufacturer ID: 0x%x\n", Struct->Type17->RcdManufacturerID);
+ ShellPrintEx (-1, -1, L"RCD Revision Number: 0x%x\n", Struct->Type17->RcdRevisionNumber);
+ }
+
break;
//
@@ -1482,7 +1493,7 @@ DisplayBiosCharacteristics (
}
if (BIT (Chara, 5) != 0) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MSA_SUPPORTED), gShellDebug1HiiHandle);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_MCA_SUPPORTED), gShellDebug1HiiHandle);
}
if (BIT (Chara, 6) != 0) {
@@ -1593,7 +1604,7 @@ DisplayBiosCharacteristics (
// Just print the Reserved
//
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_32_47), gShellDebug1HiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_48_64), gShellDebug1HiiHandle);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_BITS_48_63), gShellDebug1HiiHandle);
}
/**
@@ -3166,7 +3177,7 @@ DisplaySystemSlotId (
//
case 0x04:
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_LOGICAL_MICRO_CHAN), gShellDebug1HiiHandle);
- if ((SlotId > 0) && (SlotId < 15)) {
+ if ((SlotId > 0) && (SlotId <= 15)) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ONE_VAR_D), gShellDebug1HiiHandle, SlotId);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ERROR_NOT_1_15), gShellDebug1HiiHandle);
@@ -3175,11 +3186,11 @@ DisplaySystemSlotId (
break;
//
- // EISA
+ // Slot Type: EISA
//
case 0x05:
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_LOGICAL_EISA_NUM), gShellDebug1HiiHandle);
- if ((SlotId > 0) && (SlotId < 15)) {
+ if ((SlotId > 0) && (SlotId <= 15)) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ONE_VAR_D), gShellDebug1HiiHandle, SlotId);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_ERROR_NOT_1_15), gShellDebug1HiiHandle);
@@ -3195,21 +3206,20 @@ DisplaySystemSlotId (
break;
//
- // PCMCIA
+ // Slot Type: PCMCIA
//
case 0x07:
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_IDENTIFIES_ADAPTER_NUM), gShellDebug1HiiHandle, SlotId);
break;
//
- // Slot Type: PCI-E
+ // Slot Type: PCI 66MHz Capable, AGP, PCI-E, etc
//
- case 0xA5:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VALUE_PRESENT), gShellDebug1HiiHandle, SlotId);
- break;
-
default:
- if (((SlotType >= 0x0E) && (SlotType <= 0x12)) || ((SlotType >= 0xA6) && (SlotType <= 0xC4))) {
+ if (((SlotType >= 0x0E) && (SlotType <= 0x13)) ||
+ ((SlotType >= 0x1F) && (SlotType <= 0x25)) ||
+ ((SlotType >= 0xA5) && (SlotType <= 0xC6)))
+ {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_VALUE_PRESENT), gShellDebug1HiiHandle, SlotId);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SMBIOSVIEW_PRINTINFO_UNDEFINED_SLOT_ID), gShellDebug1HiiHandle);
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c
index 36f8739..0db28b6 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/QueryTable.c
@@ -1924,7 +1924,7 @@ TABLE_ITEM SystemSlotHeightTable[] = {
},
{
0x02,
- L" Unkown"
+ L" Unknown"
},
{
0x03,
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni
index 971e0d0..d55af31 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SmbiosView/SmbiosViewStrings.uni
@@ -119,52 +119,52 @@
#string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR #language en-US "BIOS Characteristics: \r\n"
#string STR_SMBIOSVIEW_PRINTINFO_RESERVED_BIT #language en-US "Reserved bit\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_UNKNOWN_BIT #language en-US "Unknown bit\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_NOT_SUPPORTED #language en-US "BIOS Characteristics Not Supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_NOT_SUPPORTED #language en-US "BIOS Characteristics are not supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_ISA_SUPPORTED #language en-US "ISA is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_MSA_SUPPORTED #language en-US "MSA is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MCA_SUPPORTED #language en-US "MCA is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_EISA_SUPPORTED #language en-US "EISA is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_PCI_SUPPORTED #language en-US "PCI is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_PC_CARD_SUPPORTED #language en-US "PC Card(PCMCIA) is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PC_CARD_SUPPORTED #language en-US "PC card (PCMCIA) is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_PLUG_PLAY_SUPPORTED #language en-US "Plug and play is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_APM_SUPPORTED #language en-US "APM is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_BIOS_UPGRADEABLE #language en-US "BIOS is Upgradeable(FLASH)\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_UPGRADEABLE #language en-US "BIOS is upgradeable (Flash)\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_BIOS_SHADOWING #language en-US "BIOS shadowing is allowed\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_VESA_SUPPORTED #language en-US "VL-VESA is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_ECSD_SUPPORT #language en-US "ESCD support is available\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_BOOT_FROM_CD_SUPPORTED #language en-US "Boot from CD is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_SELECTED_BOOT_SUPPORTED #language en-US "Selectable Boot is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_BIOS_ROM_SOCKETED #language en-US "BIOS ROM is socketed\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_BOOT_FROM_PC_CARD #language en-US "Boot From PC Card(PCMCIA)is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_EDD_ENHANCED_DRIVER #language en-US "EDD (Enhanced Disk Driver) Specification is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_NEC #language en-US "Int 13h - Japanese Floppy for NEC 9800 1.2mb (3.5\",1k Bytes/Sector, 360 RPM) is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_TOSHIBA #language en-US "Int 13h - Japanese Floppy for Toshiba 1.2mn (3.5\", 360 RPM) is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_FLOPPY_SERVICES_SUPPORTED #language en-US "Int 13h - 5.25\"/360KB Floppy Services are supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_ONE_POINT_TWO_MB #language en-US "Int 13h - 5.25\"/1.2MB Floppy services are supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_720_KB #language en-US "Int 13h - 3.5\"/720KB Floppy services are supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_TWO_POINT_EIGHT_EIGHT_MB #language en-US "Int 13h - 3.5\"/2.88MB Floppy services are supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_PRINT_SCREEN_SUPPORT #language en-US "Int 5h, Print screen Services is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_KEYBOARD_SERV_SUPPORT #language en-US "Int 9h, 8042 Keyboard services are supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_SERIAL_SERVICES_SUPPORT #language en-US "Int 14h, Serial Services are supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_PRINTER_SERVICES_SUPPORT #language en-US "Int 17h, Printer services are supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_MONO_VIDEO_SUPPORT #language en-US "Int 10h, CGA/Mono Video services are supported2\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_ROM_SOCKETED #language en-US "BIOS ROM is socketed (e.g., PLCC or SOP socket)\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BOOT_FROM_PC_CARD #language en-US "Boot from PC card (PCMCIA) is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_EDD_ENHANCED_DRIVER #language en-US "EDD specification is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_NEC #language en-US "Int 13h - Japanese floppy for NEC 9800 1.2MB (3.5\", 1K bytes/sector, 360 RPM) is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_JAPANESE_FLOPPY_TOSHIBA #language en-US "Int 13h - Japanese floppy for Toshiba 1.2MB (3.5\", 360 RPM) is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_FLOPPY_SERVICES_SUPPORTED #language en-US "Int 13h - 5.25\"/360KB floppy services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ONE_POINT_TWO_MB #language en-US "Int 13h - 5.25\"/1.2MB floppy services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_720_KB #language en-US "Int 13h - 3.5\"/720KB floppy services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_TWO_POINT_EIGHT_EIGHT_MB #language en-US "Int 13h - 3.5\"/2.88MB floppy services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PRINT_SCREEN_SUPPORT #language en-US "Int 5h, print screen Services is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_KEYBOARD_SERV_SUPPORT #language en-US "Int 9h, 8042 keyboard services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SERIAL_SERVICES_SUPPORT #language en-US "Int 14h, serial services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_PRINTER_SERVICES_SUPPORT #language en-US "Int 17h, printer services are supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_MONO_VIDEO_SUPPORT #language en-US "Int 10h, CGA/Mono Video Services are supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_NEC_PC_98 #language en-US "NEC PC-98\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_BITS_32_47 #language en-US " Bits 32:47 are reserved for BIOS Vendor\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_BITS_48_64 #language en-US " Bits 48:64 are reserved for System Vendor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BITS_32_47 #language en-US " Bits 32:47 are reserved for BIOS vendor\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BITS_48_63 #language en-US " Bits 48:63 are reserved for system vendor\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_EXTENSION #language en-US "BIOS Characteristics Extension Byte1:\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_ACPI_SUPPORTED #language en-US "ACPI supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ACPI_SUPPORTED #language en-US "ACPI is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_USB_LEGACY_SUPPORTED #language en-US "USB Legacy is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_AGP_SUPPORTED #language en-US "AGP is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_I2O_BOOT_SUPPORTED #language en-US "I2O boot is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_LS_120_BOOT_SUPPORTED #language en-US "LS-120 boot is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_ATAPI_ZIP_DRIVE #language en-US "ATAPI ZIP Drive boot is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_LS_120_BOOT_SUPPORTED #language en-US "LS-120 SuperDisk boot is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ATAPI_ZIP_DRIVE #language en-US "ATAPI ZIP drive boot is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_1394_BOOT_SUPPORTED #language en-US "1394 boot is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_SMART_BATTERY_SUPPORTED #language en-US "Smart battery supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_SMART_BATTERY_SUPPORTED #language en-US "Smart battery is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_BIOS_CHAR_EXTENSION_2 #language en-US "BIOS Characteristics Extension Byte2:\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_BIOS_BOOT_SPEC_SUPP #language en-US "BIOS Boot Specification supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_FUNCTION_KEY_INIT #language en-US "Function key-initiated Network Service boot supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_ENABLE_TAR_CONT_DIST #language en-US "Enable Targeted Content Distribution\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_BIOS_BOOT_SPEC_SUPP #language en-US "BIOS Boot Specification is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_FUNCTION_KEY_INIT #language en-US "Function key-initiated network service boot is supported\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_ENABLE_TAR_CONT_DIST #language en-US "Enable targeted content distribution\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_UEFI_SPEC_SUPPORT #language en-US "UEFI Specification is supported\r\n"
-#string STR_SMBIOSVIEW_PRINTINFO_VIRTUAL_MACHINE #language en-US "The SMBIOS table describes a virtual machine\r\n"
+#string STR_SMBIOSVIEW_PRINTINFO_VIRTUAL_MACHINE #language en-US "SMBIOS table describes a virtual machine\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_MCFG_SUPPORTED #language en-US "Manufacturing mode is supported\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_MCFG_ENABLED #language en-US "Manufacturing mode is enabled\r\n"
#string STR_SMBIOSVIEW_PRINTINFO_BITS_RSVD_FOR_FUTURE #language en-US " Bits %d:7 are reserved for future assignment\r\n"
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
index 3741dac..140e9dc 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
@@ -139,3 +139,7 @@
gEfiJsonConfigDataTableGuid ## SOMETIMES_CONSUMES ## SystemTable
gEfiJsonCapsuleDataTableGuid ## SOMETIMES_CONSUMES ## SystemTable
gEfiJsonCapsuleResultTableGuid ## SOMETIMES_CONSUMES ## SystemTable
+ gEfiConfProfilesTableGuid ## SOMETIMES_CONSUMES ## SystemTable
+ gEfiConfProfilesUefiSpecGuid ## SOMETIMES_CONSUMES ## GUID
+ gEfiConfProfilesEbbrSpec21Guid ## SOMETIMES_CONSUMES ## GUID
+ gEfiConfProfilesEbbrSpec22Guid ## SOMETIMES_CONSUMES ## GUID
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni
index 4041f0c..6ef923e 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.uni
@@ -126,8 +126,34 @@
"Memory Range Capsule %016LX\r\n"
"Hii Database Export Buffer %016LX\r\n"
"Conformance Profile Table %016LX\r\n"
-
-
+#string STR_DMEM_RT_PROPERTIES #language en-US "\r\nRT Properties Table\r\n"
+ "----------------------------------------\r\n"
+ "Version 0x%01LX\r\n"
+ "Runtime Services Supported:\r\n"
+ " GET_TIME %d\r\n"
+ " GET_WAKEUP_TIME %d\r\n"
+ " SET_TIME %d\r\n"
+ " SET_WAKEUP_TIME %d\r\n"
+ " GET_VARIABLE %d\r\n"
+ " GET_NEXT_VARIABLE_NAME %d\r\n"
+ " SET_VARIABLE %d\r\n"
+ " SET_VIRTUAL_ADDRESS_MAP %d\r\n"
+ " CONVERT_POINTERS %d\r\n"
+ " GET_NEXT_HIGH_MONOTONIC_COUNT %d\r\n"
+ " RESET_SYSTEM %d\r\n"
+ " UPDATE_CAPSULE %d\r\n"
+ " QUERY_CAPSULE_CAPABILITIES %d\r\n"
+ " QUERY_VARIABLE_INFO %d\r\n"
+#string STR_DMEM_IMG_EXE_TABLE #language en-US "\r\nImage Execution Table\r\n"
+ "----------------------------------------\r\n"
+#string STR_DMEM_IMG_EXE_ENTRY #language en-US "%20s: %s\r\n"
+#string STR_DMEM_CONF_PRO_TABLE #language en-US "\r\nConformance Profile Table\r\n"
+ "----------------------------------------\r\n"
+ "Version 0x1\r\n"
+ "Profile GUIDs:\r\n"
+#string STR_DMEM_CONF_PRO_ROW #language en-US " %s %g\r\n"
+#string STR_DMEM_ERR_NOT_FOUND #language en-US "\r\n%H%s%N: Table address not found.\r\n"
+#string STR_DMEM_ERR_GET_FAIL #language en-US "\r\n%H%s%N: Unable to get table information.\r\n"
#string STR_LOAD_PCI_ROM_RES #language en-US "Image '%B%s%N' load result: %r\r\n"
#string STR_LOADPCIROM_CORRUPT #language en-US "%H%s%N: File '%B%s%N' Image %d is corrupt.\r\n"
@@ -589,6 +615,7 @@
" \r\n"
" -b - Displays one screen at a time.\r\n"
" -MMIO - Forces address cycles to the PCI bus.\r\n"
+" -verbose - Displays contents of certain EFI System Tables.\r\n"
" address - Specifies a starting address in hexadecimal format.\r\n"
" size - Specifies the number of bytes to display in hexadecimal format.\r\n"
".SH DESCRIPTION\r\n"
diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Reset.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Reset.c
index 361c47e..cab9a1d 100644
--- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Reset.c
+++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Reset.c
@@ -138,7 +138,7 @@ ShellCommandRunReset (
} else {
String = ShellCommandLineGetValue (Package, L"-s");
DEBUG_CODE (
- ShellPrintEx (-1, -1, L"Reset with %s (%d bytes)", String, String != NULL ? StrSize (String) : 0);
+ ShellPrintEx (-1, -1, L"Reset with %s (%d bytes)\n", String, String != NULL ? StrSize (String) : 0);
);
if (String != NULL) {
gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, StrSize (String), (VOID *)String);
diff --git a/ShellPkg/ShellPkg.ci.yaml b/ShellPkg/ShellPkg.ci.yaml
index e741402..74059d1 100644
--- a/ShellPkg/ShellPkg.ci.yaml
+++ b/ShellPkg/ShellPkg.ci.yaml
@@ -6,6 +6,9 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "ShellPkg.dsc",
+ },
"LicenseCheck": {
"IgnoreFiles": []
},
diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc
index 557b0ec..029a22f 100644
--- a/ShellPkg/ShellPkg.dsc
+++ b/ShellPkg/ShellPkg.dsc
@@ -65,16 +65,9 @@
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
-[LibraryClasses.ARM,LibraryClasses.AARCH64]
- #
- # It is not possible to prevent the ARM compiler for generic intrinsic functions.
- # This library provides the instrinsic functions generate by a given compiler.
- # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
- #
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- # Add support for GCC stack protector
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
[PcdsFixedAtBuild]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
@@ -139,6 +132,11 @@
NULL|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
}
+ ShellPkg/Application/AcpiViewApp/AcpiViewApp.inf
+ ShellPkg/Application/ShellCTestApp/ShellCTestApp.inf
+ ShellPkg/Application/ShellExecTestApp/SA.inf
+ ShellPkg/Application/ShellSortTestApp/ShellSortTestApp.inf
+
ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
@@ -159,7 +157,6 @@
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyApp.inf
- ShellPkg/Application/AcpiViewApp/AcpiViewApp.inf
[BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/SignedCapsulePkg/SignedCapsulePkg.ci.yaml b/SignedCapsulePkg/SignedCapsulePkg.ci.yaml
index 5f48613..e25218f 100644
--- a/SignedCapsulePkg/SignedCapsulePkg.ci.yaml
+++ b/SignedCapsulePkg/SignedCapsulePkg.ci.yaml
@@ -6,6 +6,9 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "SignedCapsulePkg.dsc",
+ },
## options defined .pytool/Plugin/LicenseCheck
"LicenseCheck": {
"IgnoreFiles": []
diff --git a/SignedCapsulePkg/SignedCapsulePkg.dsc b/SignedCapsulePkg/SignedCapsulePkg.dsc
index 4c65666..1217d24 100644
--- a/SignedCapsulePkg/SignedCapsulePkg.dsc
+++ b/SignedCapsulePkg/SignedCapsulePkg.dsc
@@ -95,20 +95,13 @@
PlatformFlashAccessLib|SignedCapsulePkg/Library/PlatformFlashAccessLibNull/PlatformFlashAccessLibNull.inf
RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.ARM]
ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
-[LibraryClasses.AARCH64, LibraryClasses.ARM]
- #
- # It is not possible to prevent the ARM compiler for generic intrinsic functions.
- # This library provides the instrinsic functions generate by a given compiler.
- # And NULL mean link this library into all ARM images.
- #
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- # Add support for GCC stack protector
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
[LibraryClasses.ARM]
RngLib|MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
diff --git a/SourceLevelDebugPkg/SourceLevelDebugPkg.ci.yaml b/SourceLevelDebugPkg/SourceLevelDebugPkg.ci.yaml
index 8887a6d..0ddf60c 100644
--- a/SourceLevelDebugPkg/SourceLevelDebugPkg.ci.yaml
+++ b/SourceLevelDebugPkg/SourceLevelDebugPkg.ci.yaml
@@ -6,6 +6,9 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "SourceLevelDebugPkg.dsc",
+ },
## options defined .pytool/Plugin/LicenseCheck
"LicenseCheck": {
"IgnoreFiles": []
diff --git a/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc b/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc
index 986dd5a..1b9a99b 100644
--- a/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc
+++ b/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc
@@ -52,6 +52,10 @@
!endif
!endif
+# StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+[LibraryClasses.common.SEC]
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.PEIM]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
diff --git a/StandaloneMmPkg/Core/Dependency.c b/StandaloneMmPkg/Core/Dependency.c
index 2bcb07d..0a77ceb 100644
--- a/StandaloneMmPkg/Core/Dependency.c
+++ b/StandaloneMmPkg/Core/Dependency.c
@@ -231,13 +231,6 @@ MmIsSchedulable (
CopyMem (&DriverGuid, Iterator + 1, sizeof (EFI_GUID));
Status = MmLocateProtocol (&DriverGuid, NULL, &Interface);
- if (EFI_ERROR (Status) && (mEfiSystemTable != NULL)) {
- //
- // For MM Driver, it may depend on uefi protocols
- //
- Status = mEfiSystemTable->BootServices->LocateProtocol (&DriverGuid, NULL, &Interface);
- }
-
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = FALSE\n", &DriverGuid));
Status = PushBool (FALSE);
diff --git a/StandaloneMmPkg/Core/Dispatcher.c b/StandaloneMmPkg/Core/Dispatcher.c
index 01a2b3a..b9fe323 100644
--- a/StandaloneMmPkg/Core/Dispatcher.c
+++ b/StandaloneMmPkg/Core/Dispatcher.c
@@ -185,44 +185,30 @@ MmLoadImage (
DriverEntry->ImageBuffer = DstBuffer;
DriverEntry->NumberOfPage = PageCount;
- if (mEfiSystemTable != NULL) {
- Status = mEfiSystemTable->BootServices->AllocatePool (
- EfiBootServicesData,
- sizeof (EFI_LOADED_IMAGE_PROTOCOL),
- (VOID **)&DriverEntry->LoadedImage
- );
- if (EFI_ERROR (Status)) {
- MmFreePages (DstBuffer, PageCount);
- return Status;
- }
-
- ZeroMem (DriverEntry->LoadedImage, sizeof (EFI_LOADED_IMAGE_PROTOCOL));
- //
- // Fill in the remaining fields of the Loaded Image Protocol instance.
- // Note: ImageBase is an SMRAM address that can not be accessed outside of SMRAM if SMRAM window is closed.
- //
- DriverEntry->LoadedImage->Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
- DriverEntry->LoadedImage->ParentHandle = NULL;
- DriverEntry->LoadedImage->SystemTable = mEfiSystemTable;
- DriverEntry->LoadedImage->DeviceHandle = NULL;
- DriverEntry->LoadedImage->FilePath = NULL;
+ //
+ // Fill in the remaining fields of the Loaded Image Protocol instance.
+ // Note: ImageBase is an SMRAM address that can not be accessed outside of SMRAM if SMRAM window is closed.
+ //
+ DriverEntry->LoadedImage.Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
+ DriverEntry->LoadedImage.ParentHandle = NULL;
+ DriverEntry->LoadedImage.SystemTable = NULL;
+ DriverEntry->LoadedImage.DeviceHandle = NULL;
+ DriverEntry->LoadedImage.FilePath = NULL;
- DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)DriverEntry->ImageBuffer;
- DriverEntry->LoadedImage->ImageSize = ImageContext.ImageSize;
- DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;
- DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;
+ DriverEntry->LoadedImage.ImageBase = (VOID *)(UINTN)DriverEntry->ImageBuffer;
+ DriverEntry->LoadedImage.ImageSize = ImageContext.ImageSize;
+ DriverEntry->LoadedImage.ImageCodeType = EfiRuntimeServicesCode;
+ DriverEntry->LoadedImage.ImageDataType = EfiRuntimeServicesData;
- //
- // Create a new image handle in the UEFI handle database for the MM Driver
- //
- DriverEntry->ImageHandle = NULL;
- Status = mEfiSystemTable->BootServices->InstallMultipleProtocolInterfaces (
- &DriverEntry->ImageHandle,
- &gEfiLoadedImageProtocolGuid,
- DriverEntry->LoadedImage,
- NULL
- );
- }
+ //
+ // Install Loaded Image protocol into MM handle database for the MM Driver
+ //
+ MmInstallProtocolInterface (
+ &DriverEntry->ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &DriverEntry->LoadedImage
+ );
//
// Print the load address and the PDB file name if it is available
@@ -398,6 +384,7 @@ MmDispatcher (
LIST_ENTRY *Link;
EFI_MM_DRIVER_ENTRY *DriverEntry;
BOOLEAN ReadyToRun;
+ BOOLEAN PreviousMmEntryPointRegistered;
DEBUG ((DEBUG_INFO, "MmDispatcher\n"));
@@ -462,22 +449,41 @@ MmDispatcher (
RemoveEntryList (&DriverEntry->ScheduledLink);
//
- // For each MM driver, pass NULL as ImageHandle
+ // Cache state of MmEntryPointRegistered before calling entry point
//
- if (mEfiSystemTable == NULL) {
- DEBUG ((DEBUG_INFO, "StartImage - 0x%x (Standalone Mode)\n", DriverEntry->ImageEntryPoint));
- Status = ((MM_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, &gMmCoreMmst);
- } else {
- DEBUG ((DEBUG_INFO, "StartImage - 0x%x (Tradition Mode)\n", DriverEntry->ImageEntryPoint));
- Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(
- DriverEntry->ImageHandle,
- mEfiSystemTable
- );
- }
+ PreviousMmEntryPointRegistered = mMmEntryPointRegistered;
+ //
+ // For each MM driver, pass NULL as ImageHandle
+ //
+ DEBUG ((DEBUG_INFO, "StartImage - 0x%x (Standalone Mode)\n", DriverEntry->ImageEntryPoint));
+ Status = ((MM_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, &gMmCoreMmst);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "StartImage Status - %r\n", Status));
MmFreePages (DriverEntry->ImageBuffer, DriverEntry->NumberOfPage);
+ if (DriverEntry->ImageHandle != NULL) {
+ MmUninstallProtocolInterface (
+ DriverEntry->ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ &DriverEntry->LoadedImage
+ );
+ }
+ }
+
+ if (!PreviousMmEntryPointRegistered && mMmEntryPointRegistered) {
+ if (FeaturePcdGet (PcdRestartMmDispatcherOnceMmEntryRegistered)) {
+ //
+ // Return immediately if the MM Entry Point was registered by the MM
+ // Driver that was just dispatched. The MM IPL will reinvoke the MM
+ // Core Dispatcher. This is required so MM Mode may be enabled as soon
+ // as all the dependent MM Drivers for MM Mode have been dispatched.
+ // Once the MM Entry Point has been registered, then MM Mode will be
+ // used.
+ //
+ gRequestDispatch = TRUE;
+ gDispatcherRunning = FALSE;
+ return EFI_NOT_READY;
+ }
}
}
@@ -710,6 +716,57 @@ MmAddToDriverList (
}
/**
+ Event notification that is fired MM IPL to dispatch the previously discovered MM drivers.
+
+ @param[in] DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().
+ @param[in] Context Points to an optional handler context which was specified when the
+ handler was registered.
+ @param[in, out] CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-MM environment into an MM environment.
+ @param[in, out] CommBufferSize The size of the CommBuffer.
+
+ @return EFI_SUCCESS Dispatcher is executed.
+
+**/
+EFI_STATUS
+EFIAPI
+MmDriverDispatchHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "MmDriverDispatchHandler\n"));
+
+ //
+ // Execute the MM Dispatcher on MM drivers that have been discovered
+ // previously but not dispatched.
+ //
+ Status = MmDispatcher ();
+
+ //
+ // Check to see if CommBuffer and CommBufferSize are valid
+ //
+ if ((CommBuffer != NULL) && (CommBufferSize != NULL)) {
+ if (*CommBufferSize > sizeof (EFI_STATUS)) {
+ //
+ // Set the status of MmDispatcher to CommBuffer
+ //
+ *(EFI_STATUS *)CommBuffer = Status;
+ }
+ }
+
+ MmCoreInitializeMemoryAttributesTable ();
+
+ MmiHandlerUnRegister (DispatchHandle);
+
+ return EFI_SUCCESS;
+}
+
+/**
Traverse the discovered list for any drivers that were discovered but not loaded
because the dependency expressions evaluated to false.
diff --git a/StandaloneMmPkg/Core/FwVol.c b/StandaloneMmPkg/Core/FwVol.c
index 07500ce..9c5ee9c 100644
--- a/StandaloneMmPkg/Core/FwVol.c
+++ b/StandaloneMmPkg/Core/FwVol.c
@@ -11,18 +11,6 @@
#include <Library/FvLib.h>
#include <Library/ExtractGuidedSectionLib.h>
-//
-// List of file types supported by dispatcher
-//
-EFI_FV_FILETYPE mMmFileTypes[] = {
- EFI_FV_FILETYPE_MM,
- 0xE, // EFI_FV_FILETYPE_MM_STANDALONE,
- //
- // Note: DXE core will process the FV image file, so skip it in MM core
- // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
- //
-};
-
EFI_STATUS
MmAddToDriverList (
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
@@ -72,12 +60,10 @@ MmCoreFfsFindMmDriver (
EFI_STATUS Status;
EFI_STATUS DepexStatus;
EFI_FFS_FILE_HEADER *FileHeader;
- EFI_FV_FILETYPE FileType;
VOID *Pe32Data;
UINTN Pe32DataSize;
VOID *Depex;
UINTN DepexSize;
- UINTN Index;
EFI_COMMON_SECTION_HEADER *Section;
VOID *SectionData;
UINTN SectionDataSize;
@@ -224,22 +210,19 @@ MmCoreFfsFindMmDriver (
}
} while (TRUE);
- for (Index = 0; Index < sizeof (mMmFileTypes) / sizeof (mMmFileTypes[0]); Index++) {
- DEBUG ((DEBUG_INFO, "Check MmFileTypes - 0x%x\n", mMmFileTypes[Index]));
- FileType = mMmFileTypes[Index];
- FileHeader = NULL;
- do {
- Status = FfsFindNextFile (FileType, FwVolHeader, &FileHeader);
- if (!EFI_ERROR (Status)) {
- Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, &Pe32Data, &Pe32DataSize);
- DEBUG ((DEBUG_INFO, "Find PE data - 0x%x\n", Pe32Data));
- DepexStatus = FfsFindSectionData (EFI_SECTION_MM_DEPEX, FileHeader, &Depex, &DepexSize);
- if (!EFI_ERROR (DepexStatus)) {
- MmAddToDriverList (FwVolHeader, Pe32Data, Pe32DataSize, Depex, DepexSize, &FileHeader->Name);
- }
+ DEBUG ((DEBUG_INFO, "Check MmFileTypes - 0x%x\n", EFI_FV_FILETYPE_MM_STANDALONE));
+ FileHeader = NULL;
+ do {
+ Status = FfsFindNextFile (EFI_FV_FILETYPE_MM_STANDALONE, FwVolHeader, &FileHeader);
+ if (!EFI_ERROR (Status)) {
+ Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, &Pe32Data, &Pe32DataSize);
+ DEBUG ((DEBUG_INFO, "Find PE data - 0x%x\n", Pe32Data));
+ DepexStatus = FfsFindSectionData (EFI_SECTION_MM_DEPEX, FileHeader, &Depex, &DepexSize);
+ if (!EFI_ERROR (DepexStatus)) {
+ MmAddToDriverList (FwVolHeader, Pe32Data, Pe32DataSize, Depex, DepexSize, &FileHeader->Name);
}
- } while (!EFI_ERROR (Status));
- }
+ }
+ } while (!EFI_ERROR (Status));
return EFI_SUCCESS;
diff --git a/StandaloneMmPkg/Core/MemoryAttributesTable.c b/StandaloneMmPkg/Core/MemoryAttributesTable.c
new file mode 100644
index 0000000..bf00189
--- /dev/null
+++ b/StandaloneMmPkg/Core/MemoryAttributesTable.c
@@ -0,0 +1,493 @@
+/** @file
+ PI SMM MemoryAttributes support
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "StandaloneMmCore.h"
+
+#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
+ ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
+
+#define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D')
+
+typedef struct {
+ UINT32 Signature;
+ UINTN ImageRecordCount;
+ UINTN CodeSegmentCountMax;
+ LIST_ENTRY ImageRecordList;
+} IMAGE_PROPERTIES_PRIVATE_DATA;
+
+IMAGE_PROPERTIES_PRIVATE_DATA mImagePropertiesPrivateData = {
+ IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE,
+ 0,
+ 0,
+ INITIALIZE_LIST_HEAD_VARIABLE (mImagePropertiesPrivateData.ImageRecordList)
+};
+
+#define EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA BIT0
+
+UINT64 mMemoryProtectionAttribute = EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA;
+
+//
+// Below functions are for MemoryMap
+//
+
+/**
+ Merge continuous memory map entries whose have same attributes.
+
+ @param[in, out] MemoryMap A pointer to the buffer in which firmware places
+ the current memory map.
+ @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the
+ MemoryMap buffer. On input, this is the size of
+ the current memory map. On output,
+ it is the size of new memory map after merge.
+ @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+**/
+STATIC
+VOID
+MergeMemoryMap (
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ IN OUT UINTN *MemoryMapSize,
+ IN UINTN DescriptorSize
+ )
+{
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
+ UINT64 MemoryBlockLength;
+ EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry;
+ EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry;
+
+ MemoryMapEntry = MemoryMap;
+ NewMemoryMapEntry = MemoryMap;
+ MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize);
+ while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
+ CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+
+ do {
+ MemoryBlockLength = LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT);
+ if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&
+ (MemoryMapEntry->Type == NextMemoryMapEntry->Type) &&
+ (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&
+ ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart))
+ {
+ MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
+ if (NewMemoryMapEntry != MemoryMapEntry) {
+ NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
+ }
+
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
+ continue;
+ } else {
+ MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
+ break;
+ }
+ } while (TRUE);
+
+ MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+ NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);
+ }
+
+ *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap;
+
+ return;
+}
+
+/**
+ Enforce memory map attributes.
+ This function will set EfiRuntimeServicesData/EfiMemoryMappedIO/EfiMemoryMappedIOPortSpace to be EFI_MEMORY_XP.
+
+ @param[in, out] MemoryMap A pointer to the buffer in which firmware places
+ the current memory map.
+ @param[in] MemoryMapSize Size, in bytes, of the MemoryMap buffer.
+ @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+**/
+STATIC
+VOID
+EnforceMemoryMapAttribute (
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ IN UINTN MemoryMapSize,
+ IN UINTN DescriptorSize
+ )
+{
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
+
+ MemoryMapEntry = MemoryMap;
+ MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
+ while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
+ if (MemoryMapEntry->Attribute != 0) {
+ // It is PE image, the attribute is already set.
+ } else {
+ switch (MemoryMapEntry->Type) {
+ case EfiRuntimeServicesCode:
+ MemoryMapEntry->Attribute = EFI_MEMORY_RO;
+ break;
+ case EfiRuntimeServicesData:
+ default:
+ MemoryMapEntry->Attribute |= EFI_MEMORY_XP;
+ break;
+ }
+ }
+
+ MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+ }
+
+ return;
+}
+
+/**
+ This function for GetMemoryMap() with memory attributes table.
+
+ It calls original GetMemoryMap() to get the original memory map information. Then
+ plus the additional memory map entries for PE Code/Data separation.
+
+ @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the
+ MemoryMap buffer. On input, this is the size of
+ the buffer allocated by the caller. On output,
+ it is the size of the buffer returned by the
+ firmware if the buffer was large enough, or the
+ size of the buffer needed to contain the map if
+ the buffer was too small.
+ @param[in, out] MemoryMap A pointer to the buffer in which firmware places
+ the current memory map.
+ @param[out] MapKey A pointer to the location in which firmware
+ returns the key for the current memory map.
+ @param[out] DescriptorSize A pointer to the location in which firmware
+ returns the size, in bytes, of an individual
+ EFI_MEMORY_DESCRIPTOR.
+ @param[out] DescriptorVersion A pointer to the location in which firmware
+ returns the version number associated with the
+ EFI_MEMORY_DESCRIPTOR.
+
+ @retval EFI_SUCCESS The memory map was returned in the MemoryMap
+ buffer.
+ @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current
+ buffer size needed to hold the memory map is
+ returned in MemoryMapSize.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+MmCoreGetMemoryMapMemoryAttributesTable (
+ IN OUT UINTN *MemoryMapSize,
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ OUT UINTN *MapKey,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *DescriptorVersion
+ )
+{
+ EFI_STATUS Status;
+ UINTN OldMemoryMapSize;
+ UINTN AdditionalRecordCount;
+
+ //
+ // If PE code/data is not aligned, just return.
+ //
+ if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {
+ return MmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
+ }
+
+ if (MemoryMapSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount;
+
+ OldMemoryMapSize = *MemoryMapSize;
+ Status = MmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount;
+ } else if (Status == EFI_SUCCESS) {
+ if (OldMemoryMapSize - *MemoryMapSize < (*DescriptorSize) * AdditionalRecordCount) {
+ *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount;
+ //
+ // Need update status to buffer too small
+ //
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else {
+ //
+ // Split PE code/data
+ //
+ ASSERT (MemoryMap != NULL);
+ SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize, &mImagePropertiesPrivateData.ImageRecordList, AdditionalRecordCount);
+
+ //
+ // Set RuntimeData to XP
+ //
+ EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, *DescriptorSize);
+
+ //
+ // Merge same type to save entry size
+ //
+ MergeMemoryMap (MemoryMap, MemoryMapSize, *DescriptorSize);
+ }
+ }
+
+ return Status;
+}
+
+//
+// Below functions are for ImageRecord
+//
+
+/**
+ Insert image record.
+
+ @param[in] DriverEntry Driver information
+**/
+VOID
+MmInsertImageRecord (
+ IN EFI_MM_DRIVER_ENTRY *DriverEntry
+ )
+{
+ EFI_STATUS Status;
+ IMAGE_PROPERTIES_RECORD *ImageRecord;
+ CHAR8 *PdbPointer;
+ UINT32 RequiredAlignment;
+
+ DEBUG ((DEBUG_VERBOSE, "MM InsertImageRecord - 0x%x\n", DriverEntry));
+
+ ImageRecord = AllocatePool (sizeof (*ImageRecord));
+ if (ImageRecord == NULL) {
+ return;
+ }
+
+ InitializeListHead (&ImageRecord->Link);
+ InitializeListHead (&ImageRecord->CodeSegmentList);
+
+ PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)DriverEntry->ImageBuffer);
+ if (PdbPointer != NULL) {
+ DEBUG ((DEBUG_VERBOSE, "MM Image - %a\n", PdbPointer));
+ }
+
+ RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
+ Status = CreateImagePropertiesRecord (
+ (VOID *)(UINTN)DriverEntry->ImageBuffer,
+ LShiftU64 (DriverEntry->NumberOfPage, EFI_PAGE_SHIFT),
+ &RequiredAlignment,
+ ImageRecord
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_ABORTED) {
+ mMemoryProtectionAttribute &=
+ ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
+ }
+
+ goto Finish;
+ }
+
+ if (ImageRecord->CodeSegmentCount == 0) {
+ mMemoryProtectionAttribute &=
+ ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
+ DEBUG ((DEBUG_ERROR, "MM !!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));
+ if (PdbPointer != NULL) {
+ DEBUG ((DEBUG_ERROR, "MM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
+ }
+
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+
+ //
+ // Check overlap all section in ImageBase/Size
+ //
+ if (!IsImageRecordCodeSectionValid (ImageRecord)) {
+ DEBUG ((DEBUG_ERROR, "MM IsImageRecordCodeSectionValid - FAIL\n"));
+ Status = EFI_ABORTED;
+ goto Finish;
+ }
+
+ InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link);
+ mImagePropertiesPrivateData.ImageRecordCount++;
+
+ if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) {
+ mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;
+ }
+
+ SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
+
+Finish:
+ if (EFI_ERROR (Status) && (ImageRecord != NULL)) {
+ DeleteImagePropertiesRecord (ImageRecord);
+ }
+
+ return;
+}
+
+/**
+ Publish MemoryAttributesTable to MM configuration table.
+**/
+VOID
+PublishMemoryAttributesTable (
+ VOID
+ )
+{
+ UINTN MemoryMapSize;
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;
+ UINTN MapKey;
+ UINTN DescriptorSize;
+ UINT32 DescriptorVersion;
+ UINTN Index;
+ EFI_STATUS Status;
+ UINTN RuntimeEntryCount;
+ EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
+ EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry;
+ UINTN MemoryAttributesTableSize;
+
+ MemoryMapSize = 0;
+ MemoryMap = NULL;
+ Status = MmCoreGetMemoryMapMemoryAttributesTable (
+ &MemoryMapSize,
+ MemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ do {
+ DEBUG ((DEBUG_VERBOSE, "MemoryMapSize - 0x%x\n", MemoryMapSize));
+ MemoryMap = AllocatePool (MemoryMapSize);
+ ASSERT (MemoryMap != NULL);
+ DEBUG ((DEBUG_VERBOSE, "MemoryMap - 0x%x\n", MemoryMap));
+
+ Status = MmCoreGetMemoryMapMemoryAttributesTable (
+ &MemoryMapSize,
+ MemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (MemoryMap);
+ }
+ } while (Status == EFI_BUFFER_TOO_SMALL);
+
+ //
+ // Allocate MemoryAttributesTable
+ //
+ RuntimeEntryCount = MemoryMapSize/DescriptorSize;
+ MemoryAttributesTableSize = sizeof (EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount;
+ MemoryAttributesTable = AllocatePool (sizeof (EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount);
+ ASSERT (MemoryAttributesTable != NULL);
+ if (MemoryAttributesTable == NULL) {
+ return;
+ }
+
+ MemoryAttributesTable->Version = EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE_VERSION;
+ MemoryAttributesTable->NumberOfEntries = (UINT32)RuntimeEntryCount;
+ MemoryAttributesTable->DescriptorSize = (UINT32)DescriptorSize;
+ MemoryAttributesTable->Reserved = 0;
+ DEBUG ((DEBUG_VERBOSE, "MemoryAttributesTable:\n"));
+ DEBUG ((DEBUG_VERBOSE, " Version - 0x%08x\n", MemoryAttributesTable->Version));
+ DEBUG ((DEBUG_VERBOSE, " NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries));
+ DEBUG ((DEBUG_VERBOSE, " DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize));
+ MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1);
+ for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) {
+ CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize);
+ DEBUG ((DEBUG_VERBOSE, "Entry (0x%x)\n", MemoryAttributesEntry));
+ DEBUG ((DEBUG_VERBOSE, " Type - 0x%x\n", MemoryAttributesEntry->Type));
+ DEBUG ((DEBUG_VERBOSE, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart));
+ DEBUG ((DEBUG_VERBOSE, " VirtualStart - 0x%016lx\n", MemoryAttributesEntry->VirtualStart));
+ DEBUG ((DEBUG_VERBOSE, " NumberOfPages - 0x%016lx\n", MemoryAttributesEntry->NumberOfPages));
+ DEBUG ((DEBUG_VERBOSE, " Attribute - 0x%016lx\n", MemoryAttributesEntry->Attribute));
+ MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR (MemoryAttributesEntry, DescriptorSize);
+
+ MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, DescriptorSize);
+ }
+
+ Status = MmInstallConfigurationTable (&gMmCoreMmst, &gEdkiiPiSmmMemoryAttributesTableGuid, MemoryAttributesTable, MemoryAttributesTableSize);
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ This function installs all MM image record information.
+**/
+VOID
+MmInstallImageRecord (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN NoHandles;
+ EFI_HANDLE *HandleBuffer;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ UINTN Index;
+ EFI_MM_DRIVER_ENTRY DriverEntry;
+
+ Status = MmLocateHandleBuffer (
+ ByProtocol,
+ &gEfiLoadedImageProtocolGuid,
+ NULL,
+ &NoHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ for (Index = 0; Index < NoHandles; Index++) {
+ Status = MmHandleProtocol (
+ HandleBuffer[Index],
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "LoadedImage - 0x%x 0x%x ", LoadedImage->ImageBase, LoadedImage->ImageSize));
+ {
+ VOID *PdbPointer;
+ PdbPointer = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);
+ if (PdbPointer != NULL) {
+ DEBUG ((DEBUG_VERBOSE, "(%a) ", PdbPointer));
+ }
+ }
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+ ZeroMem (&DriverEntry, sizeof (DriverEntry));
+ DriverEntry.ImageBuffer = (UINTN)LoadedImage->ImageBase;
+ DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)LoadedImage->ImageSize);
+ MmInsertImageRecord (&DriverEntry);
+ }
+
+ FreePool (HandleBuffer);
+}
+
+/**
+ Initialize MemoryAttributesTable support.
+
+**/
+VOID
+EFIAPI
+MmCoreInitializeMemoryAttributesTable (
+ VOID
+ )
+{
+ MmInstallImageRecord ();
+
+ DEBUG ((DEBUG_VERBOSE, "MM MemoryProtectionAttribute - 0x%016lx\n", mMemoryProtectionAttribute));
+ if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {
+ return;
+ }
+
+ DEBUG_CODE_BEGIN ();
+ if ( mImagePropertiesPrivateData.ImageRecordCount > 0) {
+ DEBUG ((DEBUG_INFO, "MM - Total Runtime Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
+ DEBUG ((DEBUG_INFO, "MM - Dump Runtime Image Records:\n"));
+ DumpImageRecords (&mImagePropertiesPrivateData.ImageRecordList);
+ }
+
+ DEBUG_CODE_END ();
+
+ PublishMemoryAttributesTable ();
+
+ return;
+}
diff --git a/StandaloneMmPkg/Core/Page.c b/StandaloneMmPkg/Core/Page.c
index 8ee85d1..5b94876 100644
--- a/StandaloneMmPkg/Core/Page.c
+++ b/StandaloneMmPkg/Core/Page.c
@@ -9,15 +9,447 @@
#include "StandaloneMmCore.h"
-#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
- ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size)))
-
#define TRUNCATE_TO_PAGES(a) ((a) >> EFI_PAGE_SHIFT)
LIST_ENTRY mMmMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (mMmMemoryMap);
UINTN mMapKey;
+//
+// For GetMemoryMap()
+//
+
+#define MEMORY_MAP_SIGNATURE SIGNATURE_32('m','m','a','p')
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link;
+
+ BOOLEAN FromStack;
+ EFI_MEMORY_TYPE Type;
+ UINT64 Start;
+ UINT64 End;
+} MEMORY_MAP;
+
+LIST_ENTRY gMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (gMemoryMap);
+
+#define MAX_MAP_DEPTH 6
+
+///
+/// mMapDepth - depth of new descriptor stack
+///
+UINTN mMapDepth = 0;
+///
+/// mMapStack - space to use as temp storage to build new map descriptors
+///
+MEMORY_MAP mMapStack[MAX_MAP_DEPTH];
+UINTN mFreeMapStack = 0;
+///
+/// This list maintain the free memory map list
+///
+LIST_ENTRY mFreeMemoryMapEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemoryMapEntryList);
+
+/**
+ Allocates pages from the memory map.
+
+ @param[in] Type The type of allocation to perform.
+ @param[in] MemoryType The type of memory to turn the allocated pages
+ into.
+ @param[in] NumberOfPages The number of pages to allocate.
+ @param[out] Memory A pointer to receive the base allocated memory
+ address.
+ @param[in] AddRegion If this memory is new added region.
+
+ @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec.
+ @retval EFI_NOT_FOUND Could not allocate pages match the requirement.
+ @retval EFI_OUT_OF_RESOURCES No enough pages to allocate.
+ @retval EFI_SUCCESS Pages successfully allocated.
+
+**/
+EFI_STATUS
+MmInternalAllocatePagesEx (
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN NumberOfPages,
+ OUT EFI_PHYSICAL_ADDRESS *Memory,
+ IN BOOLEAN AddRegion
+ );
+
+/**
+ Internal function. Deque a descriptor entry from the mFreeMemoryMapEntryList.
+ If the list is empty, then allocate a new page to refuel the list.
+ Please Note this algorithm to allocate the memory map descriptor has a property
+ that the memory allocated for memory entries always grows, and will never really be freed.
+
+ @return The Memory map descriptor dequeued from the mFreeMemoryMapEntryList
+
+**/
+MEMORY_MAP *
+AllocateMemoryMapEntry (
+ VOID
+ )
+{
+ EFI_PHYSICAL_ADDRESS Mem;
+ EFI_STATUS Status;
+ MEMORY_MAP *FreeDescriptorEntries;
+ MEMORY_MAP *Entry;
+ UINTN Index;
+
+ // DEBUG((DEBUG_INFO, "AllocateMemoryMapEntry\n"));
+
+ if (IsListEmpty (&mFreeMemoryMapEntryList)) {
+ // DEBUG((DEBUG_INFO, "mFreeMemoryMapEntryList is empty\n"));
+ //
+ // The list is empty, to allocate one page to refuel the list
+ //
+ Status = MmInternalAllocatePagesEx (
+ AllocateAnyPages,
+ EfiRuntimeServicesData,
+ EFI_SIZE_TO_PAGES (RUNTIME_PAGE_ALLOCATION_GRANULARITY),
+ &Mem,
+ TRUE
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ FreeDescriptorEntries = (MEMORY_MAP *)(UINTN)Mem;
+ // DEBUG((DEBUG_INFO, "New FreeDescriptorEntries - 0x%x\n", FreeDescriptorEntries));
+ //
+ // Enqueue the free memory map entries into the list
+ //
+ for (Index = 0; Index < RUNTIME_PAGE_ALLOCATION_GRANULARITY / sizeof (MEMORY_MAP); Index++) {
+ FreeDescriptorEntries[Index].Signature = MEMORY_MAP_SIGNATURE;
+ InsertTailList (&mFreeMemoryMapEntryList, &FreeDescriptorEntries[Index].Link);
+ }
+ } else {
+ return NULL;
+ }
+ }
+
+ //
+ // dequeue the first descriptor from the list
+ //
+ Entry = CR (mFreeMemoryMapEntryList.ForwardLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ RemoveEntryList (&Entry->Link);
+
+ return Entry;
+}
+
+/**
+ Internal function. Moves any memory descriptors that are on the
+ temporary descriptor stack to heap.
+
+**/
+VOID
+CoreFreeMemoryMapStack (
+ VOID
+ )
+{
+ MEMORY_MAP *Entry;
+
+ //
+ // If already freeing the map stack, then return
+ //
+ if (mFreeMapStack != 0) {
+ ASSERT (FALSE);
+ return;
+ }
+
+ //
+ // Move the temporary memory descriptor stack into pool
+ //
+ mFreeMapStack += 1;
+
+ while (mMapDepth != 0) {
+ //
+ // Deque an memory map entry from mFreeMemoryMapEntryList
+ //
+ Entry = AllocateMemoryMapEntry ();
+ ASSERT (Entry);
+ if (Entry == NULL) {
+ return;
+ }
+
+ //
+ // Update to proper entry
+ //
+ mMapDepth -= 1;
+
+ if (mMapStack[mMapDepth].Link.ForwardLink != NULL) {
+ CopyMem (Entry, &mMapStack[mMapDepth], sizeof (MEMORY_MAP));
+ Entry->FromStack = FALSE;
+
+ //
+ // Move this entry to general memory
+ //
+ InsertTailList (&mMapStack[mMapDepth].Link, &Entry->Link);
+ RemoveEntryList (&mMapStack[mMapDepth].Link);
+ mMapStack[mMapDepth].Link.ForwardLink = NULL;
+ }
+ }
+
+ mFreeMapStack -= 1;
+}
+
+/**
+ Insert new entry from memory map.
+
+ @param[in] Link The old memory map entry to be linked.
+ @param[in] Start The start address of new memory map entry.
+ @param[in] End The end address of new memory map entry.
+ @param[in] Type The type of new memory map entry.
+ @param[in] Next If new entry is inserted to the next of old entry.
+ @param[in] AddRegion If this memory is new added region.
+**/
+VOID
+InsertNewEntry (
+ IN LIST_ENTRY *Link,
+ IN UINT64 Start,
+ IN UINT64 End,
+ IN EFI_MEMORY_TYPE Type,
+ IN BOOLEAN Next,
+ IN BOOLEAN AddRegion
+ )
+{
+ MEMORY_MAP *Entry;
+
+ Entry = &mMapStack[mMapDepth];
+ mMapDepth += 1;
+ ASSERT (mMapDepth < MAX_MAP_DEPTH);
+ Entry->FromStack = TRUE;
+
+ Entry->Signature = MEMORY_MAP_SIGNATURE;
+ Entry->Type = Type;
+ Entry->Start = Start;
+ Entry->End = End;
+ if (Next) {
+ InsertHeadList (Link, &Entry->Link);
+ } else {
+ InsertTailList (Link, &Entry->Link);
+ }
+}
+
+/**
+ Remove old entry from memory map.
+
+ @param[in] Entry Memory map entry to be removed.
+**/
+VOID
+RemoveOldEntry (
+ IN MEMORY_MAP *Entry
+ )
+{
+ RemoveEntryList (&Entry->Link);
+ Entry->Link.ForwardLink = NULL;
+
+ if (!Entry->FromStack) {
+ InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link);
+ }
+}
+
+/**
+ Update MM memory map entry.
+
+ @param[in] Type The type of allocation to perform.
+ @param[in] Memory The base of memory address.
+ @param[in] NumberOfPages The number of pages to allocate.
+ @param[in] AddRegion If this memory is new added region.
+**/
+VOID
+ConvertMmMemoryMapEntry (
+ IN EFI_MEMORY_TYPE Type,
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages,
+ IN BOOLEAN AddRegion
+ )
+{
+ LIST_ENTRY *Link;
+ MEMORY_MAP *Entry;
+ MEMORY_MAP *NextEntry;
+ LIST_ENTRY *NextLink;
+ MEMORY_MAP *PreviousEntry;
+ LIST_ENTRY *PreviousLink;
+ EFI_PHYSICAL_ADDRESS Start;
+ EFI_PHYSICAL_ADDRESS End;
+
+ Start = Memory;
+ End = Memory + EFI_PAGES_TO_SIZE (NumberOfPages) - 1;
+
+ //
+ // Exclude memory region
+ //
+ Link = gMemoryMap.ForwardLink;
+ while (Link != &gMemoryMap) {
+ Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ Link = Link->ForwardLink;
+
+ //
+ // ---------------------------------------------------
+ // | +----------+ +------+ +------+ +------+ |
+ // ---|gMemoryMep|---|Entry1|---|Entry2|---|Entry3|---
+ // +----------+ ^ +------+ +------+ +------+
+ // |
+ // +------+
+ // |EntryX|
+ // +------+
+ //
+ if (Entry->Start > End) {
+ if ((Entry->Start == End + 1) && (Entry->Type == Type)) {
+ Entry->Start = Start;
+ return;
+ }
+
+ InsertNewEntry (
+ &Entry->Link,
+ Start,
+ End,
+ Type,
+ FALSE,
+ AddRegion
+ );
+ return;
+ }
+
+ if ((Entry->Start <= Start) && (Entry->End >= End)) {
+ if (Entry->Type != Type) {
+ if (Entry->Start < Start) {
+ //
+ // ---------------------------------------------------
+ // | +----------+ +------+ +------+ +------+ |
+ // ---|gMemoryMep|---|Entry1|---|EntryX|---|Entry3|---
+ // +----------+ +------+ ^ +------+ +------+
+ // |
+ // +------+
+ // |EntryA|
+ // +------+
+ //
+ InsertNewEntry (
+ &Entry->Link,
+ Entry->Start,
+ Start - 1,
+ Entry->Type,
+ FALSE,
+ AddRegion
+ );
+ }
+
+ if (Entry->End > End) {
+ //
+ // ---------------------------------------------------
+ // | +----------+ +------+ +------+ +------+ |
+ // ---|gMemoryMep|---|Entry1|---|EntryX|---|Entry3|---
+ // +----------+ +------+ +------+ ^ +------+
+ // |
+ // +------+
+ // |EntryZ|
+ // +------+
+ //
+ InsertNewEntry (
+ &Entry->Link,
+ End + 1,
+ Entry->End,
+ Entry->Type,
+ TRUE,
+ AddRegion
+ );
+ }
+
+ //
+ // Update this node
+ //
+ Entry->Start = Start;
+ Entry->End = End;
+ Entry->Type = Type;
+
+ //
+ // Check adjacent
+ //
+ NextLink = Entry->Link.ForwardLink;
+ if (NextLink != &gMemoryMap) {
+ NextEntry = CR (NextLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ //
+ // ---------------------------------------------------
+ // | +----------+ +------+ +-----------------+ |
+ // ---|gMemoryMep|---|Entry1|---|EntryX Entry3|---
+ // +----------+ +------+ +-----------------+
+ //
+ if ((Entry->Type == NextEntry->Type) && (Entry->End + 1 == NextEntry->Start)) {
+ Entry->End = NextEntry->End;
+ RemoveOldEntry (NextEntry);
+ }
+ }
+
+ PreviousLink = Entry->Link.BackLink;
+ if (PreviousLink != &gMemoryMap) {
+ PreviousEntry = CR (PreviousLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ //
+ // ---------------------------------------------------
+ // | +----------+ +-----------------+ +------+ |
+ // ---|gMemoryMep|---|Entry1 EntryX|---|Entry3|---
+ // +----------+ +-----------------+ +------+
+ //
+ if ((PreviousEntry->Type == Entry->Type) && (PreviousEntry->End + 1 == Entry->Start)) {
+ PreviousEntry->End = Entry->End;
+ RemoveOldEntry (Entry);
+ }
+ }
+ }
+
+ return;
+ }
+ }
+
+ //
+ // ---------------------------------------------------
+ // | +----------+ +------+ +------+ +------+ |
+ // ---|gMemoryMep|---|Entry1|---|Entry2|---|Entry3|---
+ // +----------+ +------+ +------+ +------+ ^
+ // |
+ // +------+
+ // |EntryX|
+ // +------+
+ //
+ Link = gMemoryMap.BackLink;
+ if (Link != &gMemoryMap) {
+ Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ if ((Entry->End + 1 == Start) && (Entry->Type == Type)) {
+ Entry->End = End;
+ return;
+ }
+ }
+
+ InsertNewEntry (
+ &gMemoryMap,
+ Start,
+ End,
+ Type,
+ FALSE,
+ AddRegion
+ );
+ return;
+}
+
+/**
+ Return the count of Mm memory map entry.
+
+ @return The count of Mm memory map entry.
+**/
+UINTN
+GetMmMemoryMapEntryCount (
+ VOID
+ )
+{
+ LIST_ENTRY *Link;
+ UINTN Count;
+
+ Count = 0;
+ Link = gMemoryMap.ForwardLink;
+ while (Link != &gMemoryMap) {
+ Link = Link->ForwardLink;
+ Count++;
+ }
+
+ return Count;
+}
+
/**
Internal Function. Allocate n pages from given free page node.
@@ -136,12 +568,13 @@ InternalAllocAddress (
/**
Allocates pages from the memory map.
- @param Type The type of allocation to perform.
- @param MemoryType The type of memory to turn the allocated pages
- into.
- @param NumberOfPages The number of pages to allocate.
- @param Memory A pointer to receive the base allocated memory
- address.
+ @param[in] Type The type of allocation to perform.
+ @param[in] MemoryType The type of memory to turn the allocated pages
+ into.
+ @param[in] NumberOfPages The number of pages to allocate.
+ @param[out] Memory A pointer to receive the base allocated memory
+ address.
+ @param[in] AddRegion If this memory is new added region.
@retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec.
@retval EFI_NOT_FOUND Could not allocate pages match the requirement.
@@ -150,12 +583,12 @@ InternalAllocAddress (
**/
EFI_STATUS
-EFIAPI
-MmInternalAllocatePages (
+MmInternalAllocatePagesEx (
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN NumberOfPages,
- OUT EFI_PHYSICAL_ADDRESS *Memory
+ OUT EFI_PHYSICAL_ADDRESS *Memory,
+ IN BOOLEAN AddRegion
)
{
UINTN RequestedAddress;
@@ -203,12 +636,54 @@ MmInternalAllocatePages (
return EFI_INVALID_PARAMETER;
}
+ //
+ // Update MmMemoryMap here.
+ //
+ ConvertMmMemoryMapEntry (MemoryType, *Memory, NumberOfPages, AddRegion);
+ if (!AddRegion) {
+ CoreFreeMemoryMapStack ();
+ }
+
return EFI_SUCCESS;
}
/**
Allocates pages from the memory map.
+ @param[in] Type The type of allocation to perform.
+ @param[in] MemoryType The type of memory to turn the allocated pages
+ into.
+ @param[in] NumberOfPages The number of pages to allocate.
+ @param[out] Memory A pointer to receive the base allocated memory
+ address.
+
+ @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec.
+ @retval EFI_NOT_FOUND Could not allocate pages match the requirement.
+ @retval EFI_OUT_OF_RESOURCES No enough pages to allocate.
+ @retval EFI_SUCCESS Pages successfully allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+MmInternalAllocatePages (
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN NumberOfPages,
+ OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+{
+ return MmInternalAllocatePagesEx (
+ Type,
+ MemoryType,
+ NumberOfPages,
+ Memory,
+ FALSE
+ );
+}
+
+/**
+ Allocates pages from the memory map.
+
@param Type The type of allocation to perform.
@param MemoryType The type of memory to turn the allocated pages
into.
@@ -269,19 +744,20 @@ InternalMergeNodes (
/**
Frees previous allocated pages.
- @param Memory Base address of memory being freed.
- @param NumberOfPages The number of pages to free.
+ @param[in] Memory Base address of memory being freed.
+ @param[in] NumberOfPages The number of pages to free.
+ @param[in] AddRegion If this memory is new added region.
@retval EFI_NOT_FOUND Could not find the entry that covers the range.
- @retval EFI_INVALID_PARAMETER Address not aligned.
+ @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero.
@return EFI_SUCCESS Pages successfully freed.
**/
EFI_STATUS
-EFIAPI
-MmInternalFreePages (
+MmInternalFreePagesEx (
IN EFI_PHYSICAL_ADDRESS Memory,
- IN UINTN NumberOfPages
+ IN UINTN NumberOfPages,
+ IN BOOLEAN AddRegion
)
{
LIST_ENTRY *Node;
@@ -329,17 +805,46 @@ MmInternalFreePages (
InternalMergeNodes (Pages);
}
+ //
+ // Update MmMemoryMap here.
+ //
+ ConvertMmMemoryMapEntry (EfiConventionalMemory, Memory, NumberOfPages, AddRegion);
+ if (!AddRegion) {
+ CoreFreeMemoryMapStack ();
+ }
+
return EFI_SUCCESS;
}
/**
Frees previous allocated pages.
+ @param[in] Memory Base address of memory being freed.
+ @param[in] NumberOfPages The number of pages to free.
+
+ @retval EFI_NOT_FOUND Could not find the entry that covers the range.
+ @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero.
+ @return EFI_SUCCESS Pages successfully freed.
+
+**/
+EFI_STATUS
+EFIAPI
+MmInternalFreePages (
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+ )
+{
+ return MmInternalFreePagesEx (Memory, NumberOfPages, FALSE);
+}
+
+/**
+ Frees previous allocated pages.
+
@param Memory Base address of memory being freed.
@param NumberOfPages The number of pages to free.
@retval EFI_NOT_FOUND Could not find the entry that covers the range.
- @retval EFI_INVALID_PARAMETER Address not aligned.
+ @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero.
@return EFI_SUCCESS Pages successfully freed.
**/
@@ -376,10 +881,12 @@ MmAddMemoryRegion (
UINTN AlignedMemBase;
//
- // Do not add memory regions that is already allocated, needs testing, or needs ECC initialization
+ // Add EfiRuntimeServicesData for memory regions that is already allocated, needs testing, or needs ECC initialization
//
if ((Attributes & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
- return;
+ Type = EfiRuntimeServicesData;
+ } else {
+ Type = EfiConventionalMemory;
}
//
@@ -387,5 +894,102 @@ MmAddMemoryRegion (
//
AlignedMemBase = (UINTN)(MemBase + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
MemLength -= AlignedMemBase - MemBase;
- MmFreePages (AlignedMemBase, TRUNCATE_TO_PAGES ((UINTN)MemLength));
+ if (Type == EfiConventionalMemory) {
+ MmInternalFreePagesEx (AlignedMemBase, TRUNCATE_TO_PAGES ((UINTN)MemLength), TRUE);
+ } else {
+ ConvertMmMemoryMapEntry (EfiRuntimeServicesData, AlignedMemBase, TRUNCATE_TO_PAGES ((UINTN)MemLength), TRUE);
+ }
+
+ CoreFreeMemoryMapStack ();
+}
+
+/**
+ This function returns a copy of the current memory map. The map is an array of
+ memory descriptors, each of which describes a contiguous block of memory.
+
+ @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the
+ MemoryMap buffer. On input, this is the size of
+ the buffer allocated by the caller. On output,
+ it is the size of the buffer returned by the
+ firmware if the buffer was large enough, or the
+ size of the buffer needed to contain the map if
+ the buffer was too small.
+ @param[in, out] MemoryMap A pointer to the buffer in which firmware places
+ the current memory map.
+ @param[out] MapKey A pointer to the location in which firmware
+ returns the key for the current memory map.
+ @param[out] DescriptorSize A pointer to the location in which firmware
+ returns the size, in bytes, of an individual
+ EFI_MEMORY_DESCRIPTOR.
+ @param[out] DescriptorVersion A pointer to the location in which firmware
+ returns the version number associated with the
+ EFI_MEMORY_DESCRIPTOR.
+
+ @retval EFI_SUCCESS The memory map was returned in the MemoryMap
+ buffer.
+ @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current
+ buffer size needed to hold the memory map is
+ returned in MemoryMapSize.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCoreGetMemoryMap (
+ IN OUT UINTN *MemoryMapSize,
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ OUT UINTN *MapKey,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *DescriptorVersion
+ )
+{
+ UINTN Count;
+ LIST_ENTRY *Link;
+ MEMORY_MAP *Entry;
+ UINTN Size;
+ UINTN BufferSize;
+
+ Size = sizeof (EFI_MEMORY_DESCRIPTOR);
+
+ //
+ // Make sure Size != sizeof(EFI_MEMORY_DESCRIPTOR). This will
+ // prevent people from having pointer math bugs in their code.
+ // now you have to use *DescriptorSize to make things work.
+ //
+ Size += sizeof (UINT64) - (Size % sizeof (UINT64));
+
+ if (DescriptorSize != NULL) {
+ *DescriptorSize = Size;
+ }
+
+ if (DescriptorVersion != NULL) {
+ *DescriptorVersion = EFI_MEMORY_DESCRIPTOR_VERSION;
+ }
+
+ Count = GetMmMemoryMapEntryCount ();
+ BufferSize = Size * Count;
+ if (*MemoryMapSize < BufferSize) {
+ *MemoryMapSize = BufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *MemoryMapSize = BufferSize;
+ if (MemoryMap == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ZeroMem (MemoryMap, BufferSize);
+ Link = gMemoryMap.ForwardLink;
+ while (Link != &gMemoryMap) {
+ Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ Link = Link->ForwardLink;
+
+ MemoryMap->Type = Entry->Type;
+ MemoryMap->PhysicalStart = Entry->Start;
+ MemoryMap->NumberOfPages = RShiftU64 (Entry->End - Entry->Start + 1, EFI_PAGE_SHIFT);
+
+ MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, Size);
+ }
+
+ return EFI_SUCCESS;
}
diff --git a/StandaloneMmPkg/Core/Pool.c b/StandaloneMmPkg/Core/Pool.c
index 282caa9..80a879c 100644
--- a/StandaloneMmPkg/Core/Pool.c
+++ b/StandaloneMmPkg/Core/Pool.c
@@ -40,6 +40,7 @@ MmInitializeMemoryServices (
//
// Initialize free MMRAM regions
+ // Need add Free memory at first, to let mMmMemoryMap record data
//
for (Index = 0; Index < MmramRangeCount; Index++) {
//
@@ -49,6 +50,10 @@ MmInitializeMemoryServices (
continue;
}
+ if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
+ continue;
+ }
+
DEBUG ((
DEBUG_INFO,
"MmAddMemoryRegion %d : 0x%016lx - 0x%016lx\n",
@@ -63,6 +68,26 @@ MmInitializeMemoryServices (
MmramRanges[Index].RegionState
);
}
+
+ for (Index = 0; Index < MmramRangeCount; Index++) {
+ //
+ // BUGBUG: Add legacy MMRAM region is buggy.
+ //
+ if (MmramRanges[Index].CpuStart < BASE_1MB) {
+ continue;
+ }
+
+ if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) == 0) {
+ continue;
+ }
+
+ MmAddMemoryRegion (
+ MmramRanges[Index].CpuStart,
+ MmramRanges[Index].PhysicalSize,
+ EfiConventionalMemory,
+ MmramRanges[Index].RegionState
+ );
+ }
}
/**
diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c
index 1074f30..f38d7d7 100644
--- a/StandaloneMmPkg/Core/StandaloneMmCore.c
+++ b/StandaloneMmPkg/Core/StandaloneMmCore.c
@@ -20,11 +20,6 @@ MmDispatcher (
EFI_HANDLE mMmCpuHandle = NULL;
//
-// Physical pointer to private structure shared between MM IPL and the MM Core
-//
-MM_CORE_PRIVATE_DATA *gMmCorePrivate;
-
-//
// MM Core global variable for MM System Table. Only accessed as a physical structure in MMRAM.
//
EFI_MM_SYSTEM_TABLE gMmCoreMmst = {
@@ -79,16 +74,18 @@ EFI_MM_SYSTEM_TABLE gMmCoreMmst = {
// Table of MMI Handlers that are registered by the MM Core when it is initialized
//
MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = {
+ { MmDriverDispatchHandler, &gEventMmDispatchGuid, NULL, FALSE },
{ MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE },
+ { MmEndOfPeiHandler, &gEfiMmEndOfPeiProtocol, NULL, FALSE },
{ MmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, FALSE },
{ MmExitBootServiceHandler, &gEfiEventExitBootServicesGuid, NULL, FALSE },
{ MmReadyToBootHandler, &gEfiEventReadyToBootGuid, NULL, FALSE },
{ NULL, NULL, NULL, FALSE },
};
-EFI_SYSTEM_TABLE *mEfiSystemTable;
-UINTN mMmramRangeCount;
-EFI_MMRAM_DESCRIPTOR *mMmramRanges;
+BOOLEAN mMmEntryPointRegistered = FALSE;
+MM_COMM_BUFFER *mMmCommunicationBuffer;
+VOID *mInternalCommBufferCopy;
/**
Place holder function until all the MM System Table Service are available.
@@ -279,6 +276,46 @@ MmReadyToLockHandler (
}
/**
+ Software MMI handler that is called when the EndOfPei event is signaled.
+ This function installs the MM EndOfPei Protocol so MM Drivers are informed that
+ EndOfPei event is signaled.
+
+ @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().
+ @param Context Points to an optional handler context which was specified when the handler was registered.
+ @param CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-MM environment into an MM environment.
+ @param CommBufferSize The size of the CommBuffer.
+
+ @return Status Code
+
+**/
+EFI_STATUS
+EFIAPI
+MmEndOfPeiHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE MmHandle;
+
+ DEBUG ((DEBUG_INFO, "MmEndOfPeiHandler\n"));
+ //
+ // Install MM EndOfDxe protocol
+ //
+ MmHandle = NULL;
+ Status = MmInstallProtocolInterface (
+ &MmHandle,
+ &gEfiMmEndOfPeiProtocol,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ return Status;
+}
+
+/**
Software MMI handler that is called when the EndOfDxe event is signaled.
This function installs the MM EndOfDxe Protocol so MM Drivers are informed that
platform code will invoke 3rd part code.
@@ -319,6 +356,142 @@ MmEndOfDxeHandler (
}
/**
+ Install LoadedImage protocol for MM Core.
+
+**/
+VOID
+MmCoreInstallLoadedImage (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MmCoreImageBaseAddress;
+ UINT64 MmCoreImageLength;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_HANDLE ImageHandle;
+
+ //
+ // Searching for Memory Allocation HOB
+ //
+ Hob.Raw = GetHobList ();
+ while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
+ //
+ // Find MM Core HOB
+ //
+ if (CompareGuid (
+ &Hob.MemoryAllocationModule->MemoryAllocationHeader.Name,
+ &gEfiHobMemoryAllocModuleGuid
+ ))
+ {
+ if (CompareGuid (&Hob.MemoryAllocationModule->ModuleName, &gEfiCallerIdGuid)) {
+ break;
+ }
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ if (Hob.Raw == NULL) {
+ return;
+ }
+
+ MmCoreImageBaseAddress = Hob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress;
+ MmCoreImageLength = Hob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength;
+
+ //
+ // Allocate a Loaded Image Protocol in MM
+ //
+ LoadedImage = AllocatePool (sizeof (EFI_LOADED_IMAGE_PROTOCOL));
+ ASSERT (LoadedImage != NULL);
+ if (LoadedImage == NULL) {
+ return;
+ }
+
+ ZeroMem (LoadedImage, sizeof (EFI_LOADED_IMAGE_PROTOCOL));
+
+ //
+ // Fill in the remaining fields of the Loaded Image Protocol instance.
+ //
+ LoadedImage->Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
+ LoadedImage->ParentHandle = NULL;
+ LoadedImage->SystemTable = NULL;
+
+ LoadedImage->ImageBase = (VOID *)(UINTN)MmCoreImageBaseAddress;
+ LoadedImage->ImageSize = MmCoreImageLength;
+ LoadedImage->ImageCodeType = EfiRuntimeServicesCode;
+ LoadedImage->ImageDataType = EfiRuntimeServicesData;
+
+ //
+ // Create a new image handle in the MM handle database for the MM Core
+ //
+ ImageHandle = NULL;
+ Status = MmInstallProtocolInterface (
+ &ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Prepare communication buffer for MMI.
+**/
+VOID
+MmCorePrepareCommunicationBuffer (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ EFI_PHYSICAL_ADDRESS Buffer;
+
+ mMmCommunicationBuffer = NULL;
+ mInternalCommBufferCopy = NULL;
+
+ GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid);
+ ASSERT (GuidHob != NULL);
+ if (GuidHob == NULL) {
+ return;
+ }
+
+ mMmCommunicationBuffer = (MM_COMM_BUFFER *)GET_GUID_HOB_DATA (GuidHob);
+ DEBUG ((
+ DEBUG_INFO,
+ "MM Communication Buffer is at %x, number of pages is %x\n",
+ mMmCommunicationBuffer->PhysicalStart,
+ mMmCommunicationBuffer->NumberOfPages
+ ));
+ ASSERT (mMmCommunicationBuffer->PhysicalStart != 0 && mMmCommunicationBuffer->NumberOfPages != 0);
+
+ if (!MmIsBufferOutsideMmValid (
+ mMmCommunicationBuffer->PhysicalStart,
+ EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)
+ ))
+ {
+ mMmCommunicationBuffer = NULL;
+ DEBUG ((DEBUG_ERROR, "MM Communication Buffer is invalid!\n"));
+ ASSERT (FALSE);
+ return;
+ }
+
+ Status = MmAllocatePages (
+ AllocateAnyPages,
+ EfiRuntimeServicesData,
+ mMmCommunicationBuffer->NumberOfPages,
+ &Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ mInternalCommBufferCopy = (VOID *)(UINTN)Buffer;
+ DEBUG ((DEBUG_INFO, "Internal Communication Buffer Copy is at %p\n", mInternalCommBufferCopy));
+}
+
+/**
The main entry point to MM Foundation.
Note: This function is only used by MMRAM invocation. It is never used by DXE invocation.
@@ -335,6 +508,8 @@ MmEntryPoint (
{
EFI_STATUS Status;
EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
+ MM_COMM_BUFFER_STATUS *CommunicationStatus;
+ UINTN BufferSize;
DEBUG ((DEBUG_INFO, "MmEntryPoint ...\n"));
@@ -349,45 +524,68 @@ MmEntryPoint (
// PlatformHookBeforeMmDispatch ();
//
- // If a legacy boot has occurred, then make sure gMmCorePrivate is not accessed
- //
-
- //
- // TBD: Mark the InMm flag as TRUE
- //
- gMmCorePrivate->InMm = TRUE;
-
- //
// Check to see if this is a Synchronous MMI sent through the MM Communication
// Protocol or an Asynchronous MMI
//
- if (gMmCorePrivate->CommunicationBuffer != 0) {
- //
- // Synchronous MMI for MM Core or request from Communicate protocol
- //
- if (!MmIsBufferOutsideMmValid ((UINTN)gMmCorePrivate->CommunicationBuffer, gMmCorePrivate->BufferSize)) {
- //
- // If CommunicationBuffer is not in valid address scope, return EFI_INVALID_PARAMETER
- //
- gMmCorePrivate->CommunicationBuffer = 0;
- gMmCorePrivate->ReturnStatus = EFI_INVALID_PARAMETER;
- } else {
- CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)gMmCorePrivate->CommunicationBuffer;
- gMmCorePrivate->BufferSize -= OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
- Status = MmiManage (
- &CommunicateHeader->HeaderGuid,
- NULL,
- CommunicateHeader->Data,
- (UINTN *)&gMmCorePrivate->BufferSize
- );
+ if ((mMmCommunicationBuffer != NULL) && (mInternalCommBufferCopy != NULL)) {
+ CommunicationStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)mMmCommunicationBuffer->Status;
+ if (CommunicationStatus->IsCommBufferValid) {
//
- // Update CommunicationBuffer, BufferSize and ReturnStatus
- // Communicate service finished, reset the pointer to CommBuffer to NULL
+ // Synchronous MMI for MM Core or request from Communicate protocol
//
- gMmCorePrivate->BufferSize += OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
- gMmCorePrivate->CommunicationBuffer = 0;
- gMmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
+ CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mMmCommunicationBuffer->PhysicalStart;
+ BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
+ if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) {
+ //
+ // Shadow the data from MM Communication Buffer to internal buffer
+ //
+ CopyMem (
+ mInternalCommBufferCopy,
+ (VOID *)(UINTN)mMmCommunicationBuffer->PhysicalStart,
+ BufferSize
+ );
+ ZeroMem (
+ (UINT8 *)mInternalCommBufferCopy + BufferSize,
+ EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages) - BufferSize
+ );
+
+ CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mInternalCommBufferCopy;
+ BufferSize = CommunicateHeader->MessageLength;
+ Status = MmiManage (
+ &CommunicateHeader->HeaderGuid,
+ NULL,
+ CommunicateHeader->Data,
+ &BufferSize
+ );
+
+ BufferSize = BufferSize + OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
+ if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) {
+ //
+ // Copy the data back to MM Communication Buffer
+ //
+ CopyMem (
+ (VOID *)(UINTN)mMmCommunicationBuffer->PhysicalStart,
+ mInternalCommBufferCopy,
+ BufferSize
+ );
+ } else {
+ DEBUG ((DEBUG_ERROR, "Returned buffer size is larger than the size of MM Communication Buffer\n"));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Update CommunicationBuffer, BufferSize and ReturnStatus
+ // Communicate service finished, reset the pointer to CommBuffer to NULL
+ //
+ CommunicationStatus->ReturnBufferSize = BufferSize;
+ CommunicationStatus->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
+ } else {
+ DEBUG ((DEBUG_ERROR, "Input buffer size is larger than the size of MM Communication Buffer\n"));
+ ASSERT (FALSE);
+ }
}
+ } else {
+ DEBUG ((DEBUG_ERROR, "No valid communication buffer, no Synchronous MMI will be processed\n"));
}
//
@@ -399,11 +597,6 @@ MmEntryPoint (
// TBD: Do not use private data structure ?
//
- //
- // Clear the InMm flag as we are going to leave MM
- //
- gMmCorePrivate->InMm = FALSE;
-
DEBUG ((DEBUG_INFO, "MmEntryPoint Done\n"));
}
@@ -434,22 +627,82 @@ MmConfigurationMmNotify (
//
// Register the MM Entry Point provided by the MM Core with the MM COnfiguration protocol
//
- Status = MmConfiguration->RegisterMmEntry (MmConfiguration, (EFI_MM_ENTRY_POINT)(UINTN)gMmCorePrivate->MmEntryPoint);
+ Status = MmConfiguration->RegisterMmEntry (MmConfiguration, (EFI_MM_ENTRY_POINT)MmEntryPoint);
ASSERT_EFI_ERROR (Status);
//
// Set flag to indicate that the MM Entry Point has been registered which
// means that MMIs are now fully operational.
//
- gMmCorePrivate->MmEntryPointRegistered = TRUE;
+ mMmEntryPointRegistered = TRUE;
//
// Print debug message showing MM Core entry point address.
//
- DEBUG ((DEBUG_INFO, "MM Core registered MM Entry Point address %p\n", (VOID *)(UINTN)gMmCorePrivate->MmEntryPoint));
+ DEBUG ((DEBUG_INFO, "MM Core registered MM Entry Point address %p\n", MmEntryPoint));
return EFI_SUCCESS;
}
+/**
+ Migrate MemoryBaseAddress in memory allocation HOBs with BootServiceData
+ type and non-zero GUID name from Boot Service memory to MMRAM.
+
+ @param[in] HobStart Pointer to the start of the HOB list.
+
+**/
+VOID
+MigrateMemoryAllocationHobs (
+ IN VOID *HobStart
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;
+ VOID *MemoryInMmram;
+
+ MemoryAllocationHob = NULL;
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, HobStart);
+ while (Hob.Raw != NULL) {
+ MemoryAllocationHob = (EFI_HOB_MEMORY_ALLOCATION *)Hob.Raw;
+ if ((MemoryAllocationHob->AllocDescriptor.MemoryType == EfiBootServicesData) &&
+ (MmIsBufferOutsideMmValid (
+ MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress,
+ MemoryAllocationHob->AllocDescriptor.MemoryLength
+ ))
+ )
+ {
+ if (!IsZeroGuid (&MemoryAllocationHob->AllocDescriptor.Name)) {
+ MemoryInMmram = AllocatePages (EFI_SIZE_TO_PAGES (MemoryAllocationHob->AllocDescriptor.MemoryLength));
+ if (MemoryInMmram != NULL) {
+ DEBUG ((
+ DEBUG_INFO,
+ "Migrate Memory Allocation Hob (%g) from %08x to %08p\n",
+ &MemoryAllocationHob->AllocDescriptor.Name,
+ MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress,
+ MemoryInMmram
+ ));
+ CopyMem (
+ MemoryInMmram,
+ (VOID *)(UINTN)MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress,
+ MemoryAllocationHob->AllocDescriptor.MemoryLength
+ );
+ MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryInMmram;
+ MemoryAllocationHob->AllocDescriptor.MemoryType = EfiRuntimeServicesData;
+ }
+ } else {
+ DEBUG ((
+ DEBUG_ERROR,
+ "Error - Memory Allocation Hob [%08x, %08x] doesn't have a GUID name specified\n",
+ MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress,
+ MemoryAllocationHob->AllocDescriptor.MemoryLength
+ ));
+ }
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);
+ }
+}
+
/** Returns the HOB list size.
@param [in] HobStart Pointer to the start of the HOB list.
@@ -500,8 +753,6 @@ StandaloneMmMain (
VOID *MmHobStart;
UINTN HobSize;
VOID *Registration;
- EFI_HOB_GUID_TYPE *GuidHob;
- MM_CORE_DATA_HOB_DATA *DataInHob;
EFI_HOB_GUID_TYPE *MmramRangesHob;
EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData;
EFI_MMRAM_DESCRIPTOR *MmramRanges;
@@ -512,59 +763,28 @@ StandaloneMmMain (
DEBUG ((DEBUG_INFO, "MmMain - 0x%x\n", HobStart));
+ DEBUG_CODE (
+ PrintHobList (HobStart, NULL);
+ );
+
//
- // Determine if the caller has passed a reference to a MM_CORE_PRIVATE_DATA
- // structure in the Hoblist. This choice will govern how boot information is
- // extracted later.
+ // Extract the MMRAM ranges from the MMRAM descriptor HOB
//
- GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart);
- if (GuidHob == NULL) {
- //
- // Allocate and zero memory for a MM_CORE_PRIVATE_DATA table and then
- // initialise it
- //
- gMmCorePrivate = (MM_CORE_PRIVATE_DATA *)AllocateRuntimePages (EFI_SIZE_TO_PAGES (sizeof (MM_CORE_PRIVATE_DATA)));
- SetMem ((VOID *)(UINTN)gMmCorePrivate, sizeof (MM_CORE_PRIVATE_DATA), 0);
- gMmCorePrivate->Signature = MM_CORE_PRIVATE_DATA_SIGNATURE;
- gMmCorePrivate->MmEntryPointRegistered = FALSE;
- gMmCorePrivate->InMm = FALSE;
- gMmCorePrivate->ReturnStatus = EFI_SUCCESS;
-
- //
- // Extract the MMRAM ranges from the MMRAM descriptor HOB
- //
+ MmramRangesHob = GetNextGuidHob (&gEfiSmmSmramMemoryGuid, HobStart);
+ if (MmramRangesHob == NULL) {
MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart);
if (MmramRangesHob == NULL) {
return EFI_UNSUPPORTED;
}
-
- MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
- ASSERT (MmramRangesHobData != NULL);
- MmramRanges = MmramRangesHobData->Descriptor;
- MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions;
- ASSERT (MmramRanges);
- ASSERT (MmramRangeCount);
-
- //
- // Copy the MMRAM ranges into MM_CORE_PRIVATE_DATA table just in case any
- // code relies on them being present there
- //
- gMmCorePrivate->MmramRangeCount = (UINT64)MmramRangeCount;
- gMmCorePrivate->MmramRanges =
- (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (MmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR));
- ASSERT (gMmCorePrivate->MmramRanges != 0);
- CopyMem (
- (VOID *)(UINTN)gMmCorePrivate->MmramRanges,
- MmramRanges,
- MmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR)
- );
- } else {
- DataInHob = GET_GUID_HOB_DATA (GuidHob);
- gMmCorePrivate = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address;
- MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->MmramRanges;
- MmramRangeCount = (UINTN)gMmCorePrivate->MmramRangeCount;
}
+ MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
+ ASSERT (MmramRangesHobData != NULL);
+ MmramRanges = MmramRangesHobData->Descriptor;
+ MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions;
+ ASSERT (MmramRanges);
+ ASSERT (MmramRangeCount);
+
//
// Print the MMRAM ranges passed by the caller
//
@@ -580,29 +800,6 @@ StandaloneMmMain (
}
//
- // Copy the MMRAM ranges into private MMRAM
- //
- mMmramRangeCount = MmramRangeCount;
- DEBUG ((DEBUG_INFO, "mMmramRangeCount - 0x%x\n", mMmramRangeCount));
- mMmramRanges = AllocatePool (mMmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR));
- DEBUG ((DEBUG_INFO, "mMmramRanges - 0x%x\n", mMmramRanges));
- ASSERT (mMmramRanges != NULL);
- CopyMem (mMmramRanges, (VOID *)(UINTN)MmramRanges, mMmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR));
-
- //
- // Get Boot Firmware Volume address from the BFV Hob
- //
- BfvHob = GetFirstHob (EFI_HOB_TYPE_FV);
- if (BfvHob != NULL) {
- DEBUG ((DEBUG_INFO, "BFV address - 0x%x\n", BfvHob->BaseAddress));
- DEBUG ((DEBUG_INFO, "BFV size - 0x%x\n", BfvHob->Length));
- gMmCorePrivate->StandaloneBfvAddress = BfvHob->BaseAddress;
- }
-
- gMmCorePrivate->Mmst = (EFI_PHYSICAL_ADDRESS)(UINTN)&gMmCoreMmst;
- gMmCorePrivate->MmEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)MmEntryPoint;
-
- //
// No need to initialize memory service.
// It is done in the constructor of StandaloneMmCoreMemoryAllocationLib(),
// so that the library linked with StandaloneMmCore can use AllocatePool() in
@@ -620,6 +817,8 @@ StandaloneMmMain (
CopyMem (MmHobStart, HobStart, HobSize);
Status = MmInstallConfigurationTable (&gMmCoreMmst, &gEfiHobListGuid, MmHobStart, HobSize);
ASSERT_EFI_ERROR (Status);
+ MigrateMemoryAllocationHobs (MmHobStart);
+ gHobList = MmHobStart;
//
// Register notification for EFI_MM_CONFIGURATION_PROTOCOL registration and
@@ -634,12 +833,20 @@ StandaloneMmMain (
ASSERT_EFI_ERROR (Status);
//
- // Dispatch standalone BFV
+ // Get Boot Firmware Volume address from the BFV Hob
//
- DEBUG ((DEBUG_INFO, "Mm Dispatch StandaloneBfvAddress - 0x%08x\n", gMmCorePrivate->StandaloneBfvAddress));
- if (gMmCorePrivate->StandaloneBfvAddress != 0) {
- MmCoreFfsFindMmDriver ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)gMmCorePrivate->StandaloneBfvAddress, 0);
- MmDispatcher ();
+ BfvHob = GetFirstHob (EFI_HOB_TYPE_FV);
+ if (BfvHob != NULL) {
+ DEBUG ((DEBUG_INFO, "BFV address - 0x%x\n", BfvHob->BaseAddress));
+ DEBUG ((DEBUG_INFO, "BFV size - 0x%x\n", BfvHob->Length));
+ //
+ // Dispatch standalone BFV
+ //
+ if (BfvHob->BaseAddress != 0) {
+ DEBUG ((DEBUG_INFO, "Mm Dispatch StandaloneBfvAddress - 0x%08x\n", BfvHob->BaseAddress));
+ MmCoreFfsFindMmDriver ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)BfvHob->BaseAddress, 0);
+ MmDispatcher ();
+ }
}
//
@@ -654,6 +861,13 @@ StandaloneMmMain (
DEBUG ((DEBUG_INFO, "MmiHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status));
}
+ MmCorePrepareCommunicationBuffer ();
+
+ //
+ // Install Loaded Image Protocol form MM Core
+ //
+ MmCoreInstallLoadedImage ();
+
DEBUG ((DEBUG_INFO, "MmMain Done!\n"));
return EFI_SUCCESS;
diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h
index cfb417d..093a35f 100644
--- a/StandaloneMmPkg/Core/StandaloneMmCore.h
+++ b/StandaloneMmPkg/Core/StandaloneMmCore.h
@@ -30,6 +30,8 @@
#include <Guid/HobList.h>
#include <Guid/MmFvDispatch.h>
#include <Guid/MmramMemoryReserve.h>
+#include <Guid/MmCommBuffer.h>
+#include <Guid/PiSmmMemoryAttributesTable.h>
#include <Library/StandaloneMmCoreEntryPoint.h>
#include <Library/BaseLib.h>
@@ -40,7 +42,9 @@
#include <Library/ReportStatusCodeLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
-
+#include <Library/HobPrintLib.h>
+#include <Library/ImagePropertiesRecordLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/StandaloneMmMemLib.h>
#include <Library/HobLib.h>
@@ -85,7 +89,7 @@ typedef struct {
BOOLEAN DepexProtocolError;
EFI_HANDLE ImageHandle;
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_LOADED_IMAGE_PROTOCOL LoadedImage;
//
// Image EntryPoint in MMRAM
//
@@ -174,9 +178,9 @@ typedef struct {
//
// MM Core Global Variables
//
-extern MM_CORE_PRIVATE_DATA *gMmCorePrivate;
-extern EFI_MM_SYSTEM_TABLE gMmCoreMmst;
-extern LIST_ENTRY gHandleList;
+extern EFI_MM_SYSTEM_TABLE gMmCoreMmst;
+extern LIST_ENTRY gHandleList;
+extern BOOLEAN mMmEntryPointRegistered;
/**
Called to initialize the memory service.
@@ -514,6 +518,38 @@ MmLocateHandle (
);
/**
+ Function returns an array of handles that support the requested protocol
+ in a buffer allocated from pool. This is a version of MmLocateHandle()
+ that allocates a buffer for the caller.
+
+ @param SearchType Specifies which handle(s) are to be returned.
+ @param Protocol Provides the protocol to search by. This
+ parameter is only valid for SearchType
+ ByProtocol.
+ @param SearchKey Supplies the search key depending on the
+ SearchType.
+ @param NumberHandles The number of handles returned in Buffer.
+ @param Buffer A pointer to the buffer to return the requested
+ array of handles that support Protocol.
+
+ @retval EFI_SUCCESS The result array of handles was returned.
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the
+ matching results.
+ @retval EFI_INVALID_PARAMETER One or more parameters are not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+MmLocateHandleBuffer (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *NumberHandles,
+ OUT EFI_HANDLE **Buffer
+ );
+
+/**
Return the first Protocol Interface that matches the Protocol GUID. If
Registration is passed in return a Protocol Instance that was just add
to the system. If Registration is NULL return the first Protocol Interface
@@ -683,6 +719,29 @@ MmReadyToLockHandler (
);
/**
+ Software MMI handler that is called when the EndOfPei event is signaled.
+ This function installs the MM EndOfPei Protocol so MM Drivers are informed that
+ EndOfPei event is signaled.
+
+ @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().
+ @param Context Points to an optional handler context which was specified when the handler was registered.
+ @param CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-MM environment into an MM environment.
+ @param CommBufferSize The size of the CommBuffer.
+
+ @return Status Code
+
+**/
+EFI_STATUS
+EFIAPI
+MmEndOfPeiHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ );
+
+/**
This function is the main entry point for an MM handler dispatch
or communicate-based callback.
@@ -871,8 +930,56 @@ MmCoreFfsFindMmDriver (
IN UINT32 Depth
);
-extern UINTN mMmramRangeCount;
-extern EFI_MMRAM_DESCRIPTOR *mMmramRanges;
-extern EFI_SYSTEM_TABLE *mEfiSystemTable;
+#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
+ ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size)))
+
+/**
+ Initialize MemoryAttributesTable support.
+**/
+VOID
+EFIAPI
+MmCoreInitializeMemoryAttributesTable (
+ VOID
+ );
+
+/**
+ This function returns a copy of the current memory map. The map is an array of
+ memory descriptors, each of which describes a contiguous block of memory.
+
+ @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the
+ MemoryMap buffer. On input, this is the size of
+ the buffer allocated by the caller. On output,
+ it is the size of the buffer returned by the
+ firmware if the buffer was large enough, or the
+ size of the buffer needed to contain the map if
+ the buffer was too small.
+ @param[in, out] MemoryMap A pointer to the buffer in which firmware places
+ the current memory map.
+ @param[out] MapKey A pointer to the location in which firmware
+ returns the key for the current memory map.
+ @param[out] DescriptorSize A pointer to the location in which firmware
+ returns the size, in bytes, of an individual
+ EFI_MEMORY_DESCRIPTOR.
+ @param[out] DescriptorVersion A pointer to the location in which firmware
+ returns the version number associated with the
+ EFI_MEMORY_DESCRIPTOR.
+
+ @retval EFI_SUCCESS The memory map was returned in the MemoryMap
+ buffer.
+ @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current
+ buffer size needed to hold the memory map is
+ returned in MemoryMapSize.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCoreGetMemoryMap (
+ IN OUT UINTN *MemoryMapSize,
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ OUT UINTN *MapKey,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *DescriptorVersion
+ );
#endif
diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf
index 02ecd68..f5ecda3 100644
--- a/StandaloneMmPkg/Core/StandaloneMmCore.inf
+++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf
@@ -33,6 +33,7 @@
Mmi.c
InstallConfigurationTable.c
FwVol.c
+ MemoryAttributesTable.c
[Packages]
MdePkg/MdePkg.dec
@@ -52,6 +53,8 @@
PeCoffLib
ReportStatusCodeLib
StandaloneMmCoreEntryPoint
+ HobPrintLib
+ ImagePropertiesRecordLib
[Protocols]
gEfiDxeMmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister
@@ -59,10 +62,11 @@
gEfiMmEndOfDxeProtocolGuid ## PRODUCES
gEfiLoadedImageProtocolGuid ## PRODUCES
gEfiMmConfigurationProtocolGuid ## CONSUMES
+ gEfiMmEndOfPeiProtocol ## PRODUCES
[Guids]
gAprioriGuid ## SOMETIMES_CONSUMES ## File
- gEfiEventDxeDispatchGuid ## PRODUCES ## GUID # SmiHandlerRegister
+ gEventMmDispatchGuid ## PRODUCES ## GUID # SmiHandlerRegister
gEfiEndOfDxeEventGroupGuid ## PRODUCES ## GUID # SmiHandlerRegister
## SOMETIMES_CONSUMES ## GUID # Locate protocol
## SOMETIMES_PRODUCES ## GUID # SmiHandlerRegister
@@ -70,14 +74,17 @@
gZeroGuid ## SOMETIMES_CONSUMES ## GUID
gEfiHobListGuid
gEfiHobMemoryAllocModuleGuid
- gMmCoreDataHobGuid
gMmFvDispatchGuid
gEfiEventLegacyBootGuid
gEfiEventExitBootServicesGuid
gEfiEventReadyToBootGuid
+ gMmCommBufferHobGuid
+ gEfiSmmSmramMemoryGuid
+ gEdkiiPiSmmMemoryAttributesTableGuid
[Pcd]
gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES
+ gStandaloneMmPkgTokenSpaceGuid.PcdRestartMmDispatcherOnceMmEntryRegistered ##CONSUMES
#
# This configuration fails for CLANGPDB, which does not support PIE in the GCC
diff --git a/StandaloneMmPkg/Core/StandaloneMmCorePrivateData.h b/StandaloneMmPkg/Core/StandaloneMmCorePrivateData.h
index 58d3bc3..03b0261 100644
--- a/StandaloneMmPkg/Core/StandaloneMmCorePrivateData.h
+++ b/StandaloneMmPkg/Core/StandaloneMmCorePrivateData.h
@@ -11,8 +11,6 @@
#ifndef _STANDALONE_MM_CORE_PRIVATE_DATA_H_
#define _STANDALONE_MM_CORE_PRIVATE_DATA_H_
-#include <Guid/MmCoreData.h>
-
//
// Page management
//
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c
new file mode 100644
index 0000000..7b1e063
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.c
@@ -0,0 +1,478 @@
+/** @file
+ MmCommunicationDxe driver produces MmCommunication protocol and
+ create the notifications of some protocols and event.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MmCommunicationDxe.h"
+
+//
+// PI 1.7 MM Communication Protocol 2 instance
+//
+EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = {
+ MmCommunicate2
+};
+
+//
+// PI 1.7 MM Communication Protocol instance
+//
+EFI_MM_COMMUNICATION_PROTOCOL mMmCommunication = {
+ MmCommunicate
+};
+
+MM_COMM_BUFFER mMmCommonBuffer;
+EFI_SMM_CONTROL2_PROTOCOL *mSmmControl2;
+EFI_SMM_ACCESS2_PROTOCOL *mSmmAccess;
+BOOLEAN mSmmLocked = FALSE;
+BOOLEAN mEndOfDxe = FALSE;
+
+//
+// Table of Protocol notification and GUIDed Event notifications that the Standalone Mm requires
+//
+MM_EVENT_NOTIFICATION mMmEvents[] = {
+ //
+ // Declare protocol notification on DxeMmReadyToLock protocols. When this notification is established,
+ // the associated event is immediately signalled, so the notification function will be executed and the
+ // DXE Mm Ready To Lock Protocol will be found if it is already in the handle database.
+ //
+ { ProtocolNotify, TRUE, &gEfiDxeMmReadyToLockProtocolGuid, MmReadyToLockEventNotify, &gEfiDxeMmReadyToLockProtocolGuid, NULL },
+ //
+ // Declare event notification on Ready To Boot Event Group. This is an extra event notification that is
+ // used to make sure SMRAM is locked before any boot options are processed.
+ //
+ { EventNotify, TRUE, &gEfiEventReadyToBootGuid, MmReadyToLockEventNotify, &gEfiEventReadyToBootGuid, NULL },
+ //
+ // Declare event notification on Ready To Boot Event Group. This is used to inform the MM Core
+ // to notify MM driver that system enter ready to boot.
+ //
+ { EventNotify, FALSE, &gEfiEventReadyToBootGuid, MmGuidedEventNotify, &gEfiEventReadyToBootGuid, NULL },
+ //
+ // Declare event notification on EndOfDxe event. When this notification is established,
+ // the associated event is immediately signalled, so the notification function will be executed and the
+ // End Of Dxe Protocol will be found if it is already in the handle database.
+ //
+ { EventNotify, TRUE, &gEfiEndOfDxeEventGroupGuid, MmGuidedEventNotify, &gEfiEndOfDxeEventGroupGuid, NULL },
+ //
+ // Declare event notification on EndOfDxe event. This is used to set EndOfDxe event signaled flag.
+ //
+ { EventNotify, TRUE, &gEfiEndOfDxeEventGroupGuid, MmEndOfDxeEventNotify, &gEfiEndOfDxeEventGroupGuid, NULL },
+ //
+ // Declare event notification on Exit Boot Services Event Group. This is used to inform the MM Core
+ // to notify MM driver that system enter exit boot services.
+ //
+ { EventNotify, FALSE, &gEfiEventExitBootServicesGuid, MmGuidedEventNotify, &gEfiEventExitBootServicesGuid, NULL },
+ //
+ // Declare event notification on SetVirtualAddressMap() Event Group. This is used to convert fixed MM communication buffer
+ // and MM_COMM_BUFFER_STATUS in mMmCommonBuffer, mSmmControl2 from physical addresses to virtual addresses.
+ //
+ { EventNotify, FALSE, &gEfiEventVirtualAddressChangeGuid, MmVirtualAddressChangeEvent, NULL, NULL },
+ //
+ // Terminate the table of event notifications
+ //
+ { EndNotify, FALSE, NULL, NULL, NULL, NULL }
+};
+
+/**
+ Event notification that is fired when GUIDed Event Group is signaled.
+
+ @param Event The Event that is being processed, not used.
+ @param Context Event Context, not used.
+
+**/
+VOID
+EFIAPI
+MmGuidedEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Size;
+ EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
+
+ CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mMmCommonBuffer.PhysicalStart;
+
+ //
+ // Use Guid to initialize EFI_MM_COMMUNICATE_HEADER structure
+ //
+ CopyGuid (&CommunicateHeader->HeaderGuid, (EFI_GUID *)Context);
+ CommunicateHeader->MessageLength = 1;
+ CommunicateHeader->Data[0] = 0;
+
+ //
+ // Generate the Software SMI and return the result
+ //
+ Size = sizeof (EFI_MM_COMMUNICATE_HEADER);
+ MmCommunicate2 (&mMmCommunication2, CommunicateHeader, CommunicateHeader, &Size);
+}
+
+/**
+ Event notification that is fired every time a DxeSmmReadyToLock protocol is added
+ or if gEfiEventReadyToBootGuid is signaled.
+
+ @param Event The Event that is being processed, not used.
+ @param Context Event Context, not used.
+
+**/
+VOID
+EFIAPI
+MmReadyToLockEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ VOID *Interface;
+ UINTN Index;
+
+ //
+ // See if we are already locked
+ //
+ if (mSmmLocked) {
+ return;
+ }
+
+ //
+ // Make sure this notification is for this handler
+ //
+ if (CompareGuid ((EFI_GUID *)Context, &gEfiDxeMmReadyToLockProtocolGuid)) {
+ Status = gBS->LocateProtocol (&gEfiDxeMmReadyToLockProtocolGuid, NULL, &Interface);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+ } else {
+ //
+ // If MM is not locked yet and we got here from gEfiEventReadyToBootGuid being
+ // signaled, then gEfiDxeMmReadyToLockProtocolGuid was not installed as expected.
+ // Print a warning on debug builds.
+ //
+ DEBUG ((DEBUG_WARN, "DXE Mm Ready To Lock Protocol not installed before Ready To Boot signal\n"));
+ }
+
+ if (!mEndOfDxe) {
+ DEBUG ((DEBUG_ERROR, "EndOfDxe Event must be signaled before DxeSmmReadyToLock Protocol installation!\n"));
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED,
+ (EFI_SOFTWARE_SMM_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)
+ );
+ ASSERT (FALSE);
+ }
+
+ //
+ // Lock the SMRAM (Note: Locking SMRAM may not be supported on all platforms)
+ //
+ mSmmAccess->Lock (mSmmAccess);
+
+ //
+ // Close protocol and event notification events that do not apply after the
+ // DXE MM Ready To Lock Protocol has been installed or the Ready To Boot
+ // event has been signalled.
+ //
+ for (Index = 0; mMmEvents[Index].NotifyFunction != NULL; Index++) {
+ if (mMmEvents[Index].CloseOnLock) {
+ gBS->CloseEvent (mMmEvents[Index].Event);
+ }
+ }
+
+ //
+ // Inform MM Core that the DxeSmmReadyToLock protocol was installed
+ //
+ MmGuidedEventNotify (Event, (VOID *)&gEfiDxeMmReadyToLockProtocolGuid);
+
+ //
+ // Print debug message that the SMRAM window is now locked.
+ //
+ DEBUG ((DEBUG_INFO, "MmCommunicationDxe locked SMRAM window\n"));
+
+ //
+ // Set flag so this operation will not be performed again
+ //
+ mSmmLocked = TRUE;
+}
+
+/**
+ Event notification that is fired when EndOfDxe Event Group is signaled.
+
+ @param Event The Event that is being processed, not used.
+ @param Context Event Context, not used.
+
+**/
+VOID
+EFIAPI
+MmEndOfDxeEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ mEndOfDxe = TRUE;
+}
+
+/**
+ Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+
+ This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+ It convers pointer to new virtual address.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+MmVirtualAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EfiConvertPointer (0x0, (VOID **)&mMmCommonBuffer.Status);
+ EfiConvertPointer (0x0, (VOID **)&mMmCommonBuffer.PhysicalStart);
+ EfiConvertPointer (0x0, (VOID **)&mSmmControl2);
+}
+
+/**
+ Processes the communication buffer for Mm communication protocols.
+
+ This function encapsulates the common logic for handling communication buffers
+ used by MmCommunicate2 and MmCommunicate functions.
+
+ @param[in, out] CommBuffer Pointer to the MM communication buffer
+ @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data
+ being returned. Zero if the handler does not wish to reply with any data.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageLength field
+ in the CommBuffer header or the integer pointed by
+ CommSize, are updated to reflect the maximum payload
+ size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
+ if not omitted, are in address range that cannot be
+ accessed by the MM environment.
+**/
+EFI_STATUS
+EFIAPI
+ProcessCommunicationBuffer (
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
+ MM_COMM_BUFFER_STATUS *CommonBufferStatus;
+ UINTN BufferSize;
+
+ //
+ // Check parameters
+ //
+ if (CommBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)CommBuffer;
+ BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
+
+ if (CommSize != NULL) {
+ ASSERT (*CommSize == BufferSize);
+ }
+
+ CommonBufferStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)mMmCommonBuffer.Status;
+
+ //
+ // Copy the content at input CommBuffer to fixed MM communication buffer
+ // if CommBuffer is not equal to fixed MM communication buffer.
+ //
+ if ((UINTN)CommBuffer != mMmCommonBuffer.PhysicalStart) {
+ CopyMem ((VOID *)(UINTN)mMmCommonBuffer.PhysicalStart, CommBuffer, BufferSize);
+ }
+
+ CommonBufferStatus->IsCommBufferValid = TRUE;
+
+ //
+ // Generate Software SMI
+ //
+ Status = mSmmControl2->Trigger (mSmmControl2, NULL, NULL, FALSE, 0);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Copy the returned data to the non-mmram buffer (CommBuffer)
+ //
+ if ((UINTN)CommBuffer != mMmCommonBuffer.PhysicalStart) {
+ CopyMem (CommBuffer, (VOID *)(UINTN)mMmCommonBuffer.PhysicalStart, CommonBufferStatus->ReturnBufferSize);
+ }
+
+ //
+ // Retrieve BufferSize and return status from CommonBufferStatus
+ //
+ if (CommSize != NULL) {
+ *CommSize = CommonBufferStatus->ReturnBufferSize;
+ }
+
+ CommonBufferStatus->IsCommBufferValid = FALSE;
+
+ return CommonBufferStatus->ReturnStatus;
+}
+
+/**
+ Communicates with a registered handler.
+
+ This function provides a service to send and receive messages from a registered UEFI service.
+
+ @param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance.
+ @param[in, out] CommBufferPhysical Physical address of the MM communication buffer.
+ @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer.
+ @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data
+ being returned. Zero if the handler does not wish to reply with any data.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageLength field
+ in the CommBuffer header or the integer pointed by
+ CommSize, are updated to reflect the maximum payload
+ size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
+ if not omitted, are in address range that cannot be
+ accessed by the MM environment.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicate2 (
+ IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual,
+ IN OUT UINTN *CommSize OPTIONAL
+ )
+{
+ return ProcessCommunicationBuffer (CommBufferVirtual, CommSize);
+}
+
+/**
+ Communicates with a registered handler.
+
+ This function provides a service to send and receive messages from a registered UEFI service.
+
+ @param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance.
+ @param[in, out] CommBuffer Pointer to the MM communication buffer
+ @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data
+ being returned. Zero if the handler does not wish to reply with any data.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageLength field
+ in the CommBuffer header or the integer pointed by
+ CommSize, are updated to reflect the maximum payload
+ size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
+ if not omitted, are in address range that cannot be
+ accessed by the MM environment.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicate (
+ IN CONST EFI_MM_COMMUNICATION_PROTOCOL *This,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommSize OPTIONAL
+ )
+{
+ return ProcessCommunicationBuffer (CommBuffer, CommSize);
+}
+
+/**
+ The Entry Point for MmCommunicateDxe driver.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval Other Some error occurred when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicationEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ MM_COMM_BUFFER *MmCommonBuffer;
+ UINTN Index;
+ VOID *Registration;
+
+ //
+ // Locate gMmCommBufferHobGuid and cache the content
+ //
+ GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid);
+ ASSERT (GuidHob != NULL);
+ MmCommonBuffer = GET_GUID_HOB_DATA (GuidHob);
+ CopyMem (&mMmCommonBuffer, MmCommonBuffer, sizeof (MM_COMM_BUFFER));
+
+ //
+ // Get SMM Control2 Protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiSmmControl2ProtocolGuid, NULL, (VOID **)&mSmmControl2);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get SMM Access Protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&mSmmAccess);
+ ASSERT_EFI_ERROR (Status);
+
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiMmCommunication2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mMmCommunication2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiMmCommunicationProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mMmCommunication
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create the set of protocol and event notifications that the Standalone Mm requires
+ //
+ for (Index = 0; mMmEvents[Index].NotificationType != EndNotify; Index++) {
+ if (mMmEvents[Index].NotificationType == ProtocolNotify) {
+ mMmEvents[Index].Event = EfiCreateProtocolNotifyEvent (
+ mMmEvents[Index].Guid,
+ TPL_CALLBACK,
+ mMmEvents[Index].NotifyFunction,
+ mMmEvents[Index].NotifyContext,
+ &Registration
+ );
+ } else {
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ mMmEvents[Index].NotifyFunction,
+ mMmEvents[Index].NotifyContext,
+ mMmEvents[Index].Guid,
+ &mMmEvents[Index].Event
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h
new file mode 100644
index 0000000..d84d821
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.h
@@ -0,0 +1,176 @@
+/** @file
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_COMMUNICATION_DXE_H_
+#define MM_COMMUNICATION_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/ReportStatusCodeLib.h>
+
+#include <Protocol/SmmControl2.h>
+#include <Protocol/MmCommunication2.h>
+#include <Protocol/MmCommunication.h>
+#include <Protocol/DxeMmReadyToLock.h>
+#include <Protocol/SmmAccess2.h>
+
+#include <Guid/MmCommBuffer.h>
+#include <Guid/EventGroup.h>
+
+typedef enum {
+ EventNotify,
+ ProtocolNotify,
+ EndNotify,
+} NOTIFICATION_TYPE;
+
+//
+// Data structure used to declare a table of protocol notifications and event
+// notifications required by the Standalone Mm environment
+//
+typedef struct {
+ NOTIFICATION_TYPE NotificationType;
+ BOOLEAN CloseOnLock;
+ EFI_GUID *Guid;
+ EFI_EVENT_NOTIFY NotifyFunction;
+ VOID *NotifyContext;
+ EFI_EVENT Event;
+} MM_EVENT_NOTIFICATION;
+
+/**
+ Communicates with a registered handler.
+
+ This function provides a service to send and receive messages from a registered UEFI service.
+
+ @param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance.
+ @param[in, out] CommBufferPhysical Physical address of the MM communication buffer.
+ @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer.
+ @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data
+ being returned. Zero if the handler does not wish to reply with any data.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageLength field
+ in the CommBuffer header or the integer pointed by
+ CommSize, are updated to reflect the maximum payload
+ size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
+ if not omitted, are in address range that cannot be
+ accessed by the MM environment.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicate2 (
+ IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual,
+ IN OUT UINTN *CommSize OPTIONAL
+ );
+
+/**
+ Communicates with a registered handler.
+
+ This function provides a service to send and receive messages from a registered UEFI service.
+
+ @param[in] This The EFI_MM_COMMUNICATION_PROTOCOL instance.
+ @param[in, out] CommBufferPhysical Physical address of the MM communication buffer
+ @param[in, out] CommSize The size of the data buffer being passed in. On exit, the size of data
+ being returned. Zero if the handler does not wish to reply with any data.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageLength field
+ in the CommBuffer header or the integer pointed by
+ CommSize, are updated to reflect the maximum payload
+ size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
+ if not omitted, are in address range that cannot be
+ accessed by the MM environment.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicate (
+ IN CONST EFI_MM_COMMUNICATION_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT UINTN *CommSize OPTIONAL
+ );
+
+/**
+ Event notification that is fired every time a DxeSmmReadyToLock protocol is added
+ or if gEfiEventReadyToBootGuid is signaled.
+
+ @param Event The Event that is being processed, not used.
+ @param Context Event Context, not used.
+
+**/
+VOID
+EFIAPI
+MmReadyToLockEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Event notification that is fired when GUIDed Event Group is signaled.
+
+ @param Event The Event that is being processed, not used.
+ @param Context Event Context, not used.
+
+**/
+VOID
+EFIAPI
+MmGuidedEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Event notification that is fired when EndOfDxe Event Group is signaled.
+
+ @param Event The Event that is being processed, not used.
+ @param Context Event Context, not used.
+
+**/
+VOID
+EFIAPI
+MmEndOfDxeEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+
+ This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+ It convers pointer to new virtual address.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+MmVirtualAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+#endif
diff --git a/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf
new file mode 100644
index 0000000..821df02
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf
@@ -0,0 +1,56 @@
+## @file
+# MmCommunicationDxe driver produces MmCommunication protocol and
+# create the notifications of some protocols and event.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = MmCommunicationDxe
+ FILE_GUID = 8d4b8bc7-e66b-4be2-add8-4988e08743ed
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ ENTRY_POINT = MmCommunicationEntryPoint
+
+[Sources]
+ MmCommunicationDxe.c
+ MmCommunicationDxe.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseLib
+ DebugLib
+ HobLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiLib
+ UefiRuntimeLib
+ ReportStatusCodeLib
+
+[Guids]
+ gMmCommBufferHobGuid
+ gEfiEventVirtualAddressChangeGuid
+ gEfiEndOfDxeEventGroupGuid
+ gEfiEventExitBootServicesGuid
+
+[Protocols]
+ gEfiMmCommunication2ProtocolGuid
+ gEfiSmmControl2ProtocolGuid
+ gEfiMmCommunicationProtocolGuid
+ gEfiDxeMmReadyToLockProtocolGuid
+ gEfiSmmAccess2ProtocolGuid
+
+[Depex]
+ gEfiSmmAccess2ProtocolGuid AND gEfiSmmControl2ProtocolGuid
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c
new file mode 100644
index 0000000..a0f8d1f
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c
@@ -0,0 +1,932 @@
+/** @file
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <StandaloneMmIplPei.h>
+#include <Guid/MpInformation2.h>
+#include <Guid/AcpiS3Context.h>
+#include <Guid/MmAcpiS3Enable.h>
+#include <Guid/MmCpuSyncConfig.h>
+#include <Guid/MmProfileData.h>
+#include <Guid/MmUnblockRegion.h>
+#include <Register/Intel/Cpuid.h>
+#include <Register/Intel/ArchitecturalMsr.h>
+
+typedef struct {
+ EFI_PHYSICAL_ADDRESS Base;
+ UINT64 Length;
+} MM_IPL_MEMORY_REGION;
+
+/**
+ Add a new HOB to the HOB List.
+
+ @param[in] Hob The pointer of new HOB buffer.
+ @param[in] HobType Type of the new HOB.
+ @param[in] HobLength Length of the new HOB to allocate.
+
+ @return NULL if there is no space to create a hob.
+ @return The address point to the new created hob.
+
+**/
+VOID *
+MmIplCreateHob (
+ IN VOID *Hob,
+ IN UINT16 HobType,
+ IN UINT16 HobLength
+ )
+{
+ //
+ // Check Length to avoid data overflow.
+ //
+ ASSERT (HobLength < MAX_UINT16 - 0x7);
+
+ HobLength = (UINT16)ALIGN_VALUE (HobLength, 8);
+
+ ((EFI_HOB_GENERIC_HEADER *)Hob)->HobType = HobType;
+ ((EFI_HOB_GENERIC_HEADER *)Hob)->HobLength = HobLength;
+ ((EFI_HOB_GENERIC_HEADER *)Hob)->Reserved = 0;
+
+ return Hob;
+}
+
+/**
+ Builds a HOB that describes a chunk of system memory.
+
+ This function builds a HOB that describes a chunk of system memory.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param[in] Hob The pointer of new HOB buffer.
+ @param[in] ResourceType The type of resource described by this HOB.
+ @param[in] ResourceAttribute The resource attributes of the memory described by this HOB.
+ @param[in] PhysicalStart The 64 bit physical address of memory described by this HOB.
+ @param[in] NumberOfBytes The length of the memory described by this HOB in bytes.
+ @param[in] Owner The pointer of GUID.
+
+**/
+VOID
+MmIplBuildMemoryResourceHob (
+ IN EFI_HOB_RESOURCE_DESCRIPTOR *Hob,
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes,
+ IN EFI_GUID *Owner
+ )
+{
+ ASSERT (Hob != NULL);
+ MmIplCreateHob (Hob, EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
+
+ Hob->ResourceType = EFI_RESOURCE_SYSTEM_MEMORY;
+ Hob->ResourceAttribute = ResourceAttribute;
+ Hob->PhysicalStart = PhysicalStart;
+ Hob->ResourceLength = NumberOfBytes;
+
+ if (Owner != NULL) {
+ CopyGuid (&Hob->Owner, Owner);
+ } else {
+ ZeroMem (&Hob->Owner, sizeof (EFI_GUID));
+ }
+}
+
+/**
+ Builds a Firmware Volume HOB.
+
+ This function builds a Firmware Volume HOB.
+ It can only be invoked during PEI phase;
+ If new HOB buffer is NULL, then ASSERT().
+
+ @param[in] Hob The pointer of new HOB buffer.
+ @param[in, out] HobBufferSize The available size of the HOB buffer when as input.
+ The used size of when as output.
+ @param[in] BaseAddress The base address of the Firmware Volume.
+ @param[in] Length The size of the Firmware Volume in bytes.
+
+**/
+VOID
+MmIplBuildFvHob (
+ IN UINT8 *Hob,
+ IN OUT UINTN *HobBufferSize,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+{
+ EFI_HOB_FIRMWARE_VOLUME *FvHob;
+ UINT16 HobLength;
+
+ ASSERT (Hob != NULL);
+
+ HobLength = ALIGN_VALUE (sizeof (EFI_HOB_FIRMWARE_VOLUME), 8);
+ if (*HobBufferSize >= HobLength) {
+ MmIplCreateHob (Hob, EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
+
+ FvHob = (EFI_HOB_FIRMWARE_VOLUME *)Hob;
+ FvHob->BaseAddress = BaseAddress;
+ FvHob->Length = Length;
+ }
+
+ *HobBufferSize = HobLength;
+}
+
+/**
+ Builds MM ACPI S3 Enable HOB.
+
+ This function builds MM ACPI S3 Enable HOB.
+ It can only be invoked during PEI phase;
+ If new HOB buffer is NULL, then ASSERT().
+
+ @param[in] Hob The pointer of new HOB buffer.
+ @param[in, out] HobBufferSize The available size of the HOB buffer when as input.
+ The used size of when as output.
+
+**/
+VOID
+MmIplBuildMmAcpiS3EnableHob (
+ IN UINT8 *Hob,
+ IN OUT UINTN *HobBufferSize
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ MM_ACPI_S3_ENABLE *MmAcpiS3Enable;
+ UINT16 HobLength;
+
+ ASSERT (Hob != NULL);
+
+ HobLength = ALIGN_VALUE (sizeof (EFI_HOB_GUID_TYPE) + sizeof (MM_ACPI_S3_ENABLE), 8);
+ if (*HobBufferSize >= HobLength) {
+ MmIplCreateHob (Hob, EFI_HOB_TYPE_GUID_EXTENSION, HobLength);
+
+ GuidHob = (EFI_HOB_GUID_TYPE *)Hob;
+ CopyGuid (&GuidHob->Name, &gMmAcpiS3EnableHobGuid);
+
+ MmAcpiS3Enable = (MM_ACPI_S3_ENABLE *)(GuidHob + 1);
+ MmAcpiS3Enable->AcpiS3Enable = PcdGetBool (PcdAcpiS3Enable);
+ }
+
+ *HobBufferSize = HobLength;
+}
+
+/**
+ Builds MM cpu sync configuration HOB.
+
+ This function builds smm cpu sync configuration HOB.
+ It can only be invoked during PEI phase;
+ If new HOB buffer is NULL, then ASSERT().
+
+ @param[in] Hob The pointer of new HOB buffer.
+ @param[in, out] HobBufferSize The available size of the HOB buffer when as input.
+ The used size of when as output.
+
+**/
+VOID
+MmIplBuildMmCpuSyncConfigHob (
+ IN UINT8 *Hob,
+ IN OUT UINTN *HobBufferSize
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ MM_CPU_SYNC_CONFIG *MmSyncModeInfoHob;
+ UINT16 HobLength;
+
+ ASSERT (Hob != NULL);
+
+ GuidHob = (EFI_HOB_GUID_TYPE *)(UINTN)Hob;
+
+ HobLength = ALIGN_VALUE (sizeof (EFI_HOB_GUID_TYPE) + sizeof (MM_CPU_SYNC_CONFIG), 8);
+ if (*HobBufferSize >= HobLength) {
+ MmIplCreateHob (GuidHob, EFI_HOB_TYPE_GUID_EXTENSION, HobLength);
+
+ CopyGuid (&GuidHob->Name, &gMmCpuSyncConfigHobGuid);
+
+ MmSyncModeInfoHob = (MM_CPU_SYNC_CONFIG *)(UINTN)(GuidHob + 1);
+ MmSyncModeInfoHob->RelaxedApMode = (BOOLEAN)(PcdGet8 (PcdCpuSmmSyncMode) == MmCpuSyncModeRelaxedAp);
+ MmSyncModeInfoHob->Timeout = PcdGet64 (PcdCpuSmmApSyncTimeout);
+ MmSyncModeInfoHob->Timeout2 = PcdGet64 (PcdCpuSmmApSyncTimeout2);
+ }
+
+ *HobBufferSize = HobLength;
+}
+
+/**
+ Copies a data buffer to a newly-built HOB for GUID HOB
+
+ This function builds a customized HOB tagged with a GUID for identification, copies the
+ input data to the HOB data field and returns the start address of the GUID HOB data.
+ If new HOB buffer is NULL or the GUID HOB could not found, then ASSERT().
+
+ @param[in] HobBuffer The pointer of HOB buffer.
+ @param[in, out] HobBufferSize The available size of the HOB buffer when as input.
+ The used size of when as output.
+ @param[in] Guid The GUID of the GUID type HOB.
+ @param[in] MultiInstances TRUE indicating copying multiple HOBs with the same Guid.
+**/
+VOID
+MmIplCopyGuidHob (
+ IN UINT8 *HobBuffer,
+ IN OUT UINTN *HobBufferSize,
+ IN EFI_GUID *Guid,
+ IN BOOLEAN MultiInstances
+ )
+{
+ EFI_HOB_GENERIC_HEADER *GuidHob;
+ UINTN UsedSize;
+
+ UsedSize = 0;
+ GuidHob = GetFirstGuidHob (Guid);
+ ASSERT (GuidHob != NULL);
+
+ while (GuidHob != NULL) {
+ if (*HobBufferSize >= UsedSize + GuidHob->HobLength) {
+ CopyMem (HobBuffer + UsedSize, GuidHob, GuidHob->HobLength);
+ }
+
+ UsedSize += GuidHob->HobLength;
+
+ if (!MultiInstances) {
+ break;
+ }
+
+ GuidHob = GetNextGuidHob (Guid, GET_NEXT_HOB (GuidHob));
+ }
+
+ *HobBufferSize = UsedSize;
+}
+
+/**
+ Builds a HOB for a loaded PE32 module.
+
+ This function builds a HOB for a loaded PE32 module.
+ It can only be invoked during PEI phase;
+ If physical address of the Module is not 4K aligned, then ASSERT().
+ If new HOB buffer is NULL, then ASSERT().
+
+ @param[in] Hob The pointer of new HOB buffer.
+ @param[in, out] HobBufferSize The available size of the HOB buffer when as input.
+ The used size of when as output.
+ @param[in] ModuleName The GUID File Name of the module.
+ @param[in] Base The 64 bit physical address of the module.
+ @param[in] Length The length of the module in bytes.
+ @param[in] EntryPoint The 64 bit physical address of the module entry point.
+
+**/
+VOID
+MmIplBuildMmCoreModuleHob (
+ IN UINT8 *Hob,
+ IN OUT UINTN *HobBufferSize,
+ IN CONST EFI_GUID *ModuleName,
+ IN EFI_PHYSICAL_ADDRESS Base,
+ IN UINT64 Length,
+ IN EFI_PHYSICAL_ADDRESS EntryPoint
+ )
+{
+ UINT16 HobLength;
+ EFI_HOB_MEMORY_ALLOCATION_MODULE *MmCoreModuleHob;
+
+ ASSERT (Hob != NULL);
+ ASSERT (ADDRESS_IS_ALIGNED (Base, EFI_PAGE_SIZE));
+ ASSERT (IS_ALIGNED (Length, EFI_PAGE_SIZE));
+ ASSERT (EntryPoint >= Base && EntryPoint < Base + Length);
+
+ HobLength = ALIGN_VALUE (sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE), 8);
+ if (*HobBufferSize >= HobLength) {
+ MmIplCreateHob (Hob, EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
+
+ MmCoreModuleHob = (EFI_HOB_MEMORY_ALLOCATION_MODULE *)Hob;
+ CopyGuid (&MmCoreModuleHob->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid);
+ MmCoreModuleHob->MemoryAllocationHeader.MemoryBaseAddress = Base;
+ MmCoreModuleHob->MemoryAllocationHeader.MemoryLength = Length;
+ MmCoreModuleHob->MemoryAllocationHeader.MemoryType = EfiReservedMemoryType;
+ ZeroMem (MmCoreModuleHob->MemoryAllocationHeader.Reserved, sizeof (MmCoreModuleHob->MemoryAllocationHeader.Reserved));
+
+ CopyGuid (&MmCoreModuleHob->ModuleName, ModuleName);
+ MmCoreModuleHob->EntryPoint = EntryPoint;
+ }
+
+ *HobBufferSize = HobLength;
+}
+
+/**
+ Build memory allocation HOB in PEI HOB list for MM profile data.
+
+ This function is to allocate memory for MM profile data.
+
+ @return NULL if MM profile data memory allocation HOB build fail.
+ @return Pointer of MM profile data memory allocation HOB if build successfully.
+
+**/
+EFI_HOB_MEMORY_ALLOCATION *
+BuildMmProfileDataHobInPeiHobList (
+ VOID
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINTN TotalSize;
+ VOID *Alloc;
+
+ TotalSize = PcdGet32 (PcdCpuSmmProfileSize);
+ Alloc = AllocateReservedPages (EFI_SIZE_TO_PAGES (TotalSize));
+ if (Alloc == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (Alloc, TotalSize);
+
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
+ while (Hob.Raw != NULL) {
+ if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)Alloc) {
+ //
+ // Find the HOB just created and change the Name to gMmProfileDataHobGuid in PEI HOB list
+ //
+ CopyGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gMmProfileDataHobGuid);
+ return Hob.MemoryAllocation;
+ }
+
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob));
+ }
+
+ return NULL;
+}
+
+/**
+ Build memory allocation and resource HOB for MM profile data
+
+ This function builds HOBs for MM profile data, one is memory
+ allocation HOB, another is resource HOB.
+
+ @param[in] HobBuffer The pointer of new HOB buffer.
+ @param[in, out] HobBufferSize The total size of the same GUID HOBs when as input.
+ The size will be 0 for output when build HOB fail.
+
+**/
+VOID
+MmIplBuildMmProfileHobs (
+ IN UINT8 *HobBuffer,
+ IN OUT UINTN *HobBufferSize
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINTN HobLength;
+
+ Hob.MemoryAllocation = NULL;
+ HobLength = ALIGN_VALUE (sizeof (EFI_HOB_MEMORY_ALLOCATION), 8) + ALIGN_VALUE (sizeof (EFI_HOB_RESOURCE_DESCRIPTOR), 8);
+
+ if (*HobBufferSize >= HobLength) {
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
+ while (Hob.Raw != NULL) {
+ if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gMmProfileDataHobGuid)) {
+ break;
+ }
+
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob));
+ }
+
+ ASSERT (Hob.MemoryAllocation != NULL);
+
+ //
+ // Build memory allocation HOB
+ //
+ ASSERT (Hob.MemoryAllocation->Header.HobLength == ALIGN_VALUE (sizeof (EFI_HOB_MEMORY_ALLOCATION), 8));
+ CopyMem (HobBuffer, Hob.Raw, Hob.MemoryAllocation->Header.HobLength);
+
+ //
+ // Build resource HOB
+ //
+ MmIplBuildMemoryResourceHob (
+ (EFI_HOB_RESOURCE_DESCRIPTOR *)(HobBuffer + Hob.MemoryAllocation->Header.HobLength),
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ 0,
+ Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,
+ Hob.MemoryAllocation->AllocDescriptor.MemoryLength,
+ &gMmProfileDataHobGuid
+ );
+ }
+
+ *HobBufferSize = HobLength;
+}
+
+/**
+
+ Build resource Hobs from unblocked memory regions
+
+ This function builds resource HOBs for all unblocked memory regions.
+
+ @param[in] HobBuffer The pointer of new HOB buffer.
+ @param[in, out] HobBufferSize The total size of the same GUID HOBs when as output.
+
+**/
+VOID
+MmIplBuildResourceHobForUnblockedRegion (
+ IN UINT8 *HobBuffer,
+ IN OUT UINTN *HobBufferSize
+ )
+{
+ MM_UNBLOCK_REGION *UnblockRegion;
+ EFI_HOB_GENERIC_HEADER *GuidHob;
+ UINTN UsedSize;
+
+ UsedSize = 0;
+
+ GuidHob = GetFirstGuidHob (&gMmUnblockRegionHobGuid);
+ while (GuidHob != NULL) {
+ if (*HobBufferSize >= UsedSize + sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
+ UnblockRegion = GET_GUID_HOB_DATA (GuidHob);
+ MmIplBuildMemoryResourceHob (
+ (EFI_HOB_RESOURCE_DESCRIPTOR *)(HobBuffer + UsedSize),
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ 0,
+ UnblockRegion->PhysicalStart,
+ EFI_PAGES_TO_SIZE (UnblockRegion->NumberOfPages),
+ &UnblockRegion->IdentifierGuid
+ );
+ }
+
+ UsedSize += sizeof (EFI_HOB_RESOURCE_DESCRIPTOR);
+ GuidHob = GetNextGuidHob (&gMmUnblockRegionHobGuid, GET_NEXT_HOB (GuidHob));
+ }
+
+ *HobBufferSize = UsedSize;
+}
+
+/**
+ Collect unblock memory regions.
+
+ @param[in, out] MemoryRegion Pointer to unblock memory regions.
+ @param[in, out] MemoryRegionCount Count of unblock memory regions.
+**/
+VOID
+CollectUnblockMemoryRegions (
+ IN OUT MM_IPL_MEMORY_REGION *MemoryRegion,
+ IN OUT UINTN *MemoryRegionCount
+ )
+{
+ UINTN Index;
+ EFI_HOB_GENERIC_HEADER *GuidHob;
+ MM_UNBLOCK_REGION *UnblockRegion;
+
+ ASSERT (MemoryRegionCount != NULL);
+ ASSERT (*MemoryRegionCount == 0 || MemoryRegion != NULL);
+
+ Index = 0;
+ //
+ // Collect unblock memory ranges
+ //
+ GuidHob = GetFirstGuidHob (&gMmUnblockRegionHobGuid);
+ while (GuidHob != NULL) {
+ if (Index < *MemoryRegionCount) {
+ UnblockRegion = GET_GUID_HOB_DATA (GuidHob);
+ MemoryRegion[Index].Base = UnblockRegion->PhysicalStart;
+ MemoryRegion[Index].Length = EFI_PAGES_TO_SIZE (UnblockRegion->NumberOfPages);
+ }
+
+ Index++;
+ GuidHob = GetNextGuidHob (&gMmUnblockRegionHobGuid, GET_NEXT_HOB (GuidHob));
+ }
+
+ *MemoryRegionCount = Index;
+}
+
+/**
+ Create MMIO memory map according to platform HOB.
+
+ @param[in] PlatformHobList Platform HOB list.
+ @param[in] PlatformHobSize Platform HOB size.
+ @param[in, out] MemoryRegion Memory regions.
+ @param[in, out] MemoryRegionCount Count of MMIO regions
+**/
+VOID
+CollectPlatformMemoryRegions (
+ IN UINT8 *PlatformHobList,
+ IN UINTN PlatformHobSize,
+ IN OUT MM_IPL_MEMORY_REGION *MemoryRegion,
+ IN OUT UINTN *MemoryRegionCount
+ )
+{
+ UINTN Index;
+ EFI_PEI_HOB_POINTERS Hob;
+
+ ASSERT (MemoryRegionCount != NULL);
+ ASSERT (*MemoryRegionCount == 0 || MemoryRegion != NULL);
+
+ Index = 0;
+ //
+ // Get the HOB list for processing
+ //
+ Hob.Raw = PlatformHobList;
+
+ //
+ // Collect memory ranges
+ //
+ while (Hob.Raw < PlatformHobList + PlatformHobSize) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if ( (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_MAPPED_IO)
+ || (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)
+ || (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_FIRMWARE_DEVICE)
+ || (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED))
+ {
+ if (Index < *MemoryRegionCount) {
+ MemoryRegion[Index].Base = Hob.ResourceDescriptor->PhysicalStart;
+ MemoryRegion[Index].Length = Hob.ResourceDescriptor->ResourceLength;
+ }
+
+ Index++;
+ }
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ *MemoryRegionCount = Index;
+}
+
+/**
+ Function to compare 2 MM_IPL_MEMORY_REGION pointer based on Base.
+
+ @param[in] Buffer1 pointer to MM_IPL_MEMORY_REGION pointer to compare
+ @param[in] Buffer2 pointer to second MM_IPL_MEMORY_REGION pointer to compare
+
+ @retval 0 Buffer1 equal to Buffer2
+ @retval <0 Buffer1 is less than Buffer2
+ @retval >0 Buffer1 is greater than Buffer2
+**/
+INTN
+EFIAPI
+MemoryRegionBaseAddressCompare (
+ IN CONST VOID *Buffer1,
+ IN CONST VOID *Buffer2
+ )
+{
+ if (((MM_IPL_MEMORY_REGION *)Buffer1)->Base > ((MM_IPL_MEMORY_REGION *)Buffer2)->Base) {
+ return 1;
+ } else if (((MM_IPL_MEMORY_REGION *)Buffer1)->Base < ((MM_IPL_MEMORY_REGION *)Buffer2)->Base) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ Calculate the maximum support address.
+
+ @return the maximum support address.
+**/
+UINT8
+MmIplCalculateMaximumSupportAddress (
+ VOID
+ )
+{
+ UINT32 RegEax;
+ UINT8 PhysicalAddressBits;
+ VOID *Hob;
+
+ //
+ // Get physical address bits supported.
+ //
+ Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
+ if (Hob != NULL) {
+ PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
+ } else {
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
+ AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);
+ PhysicalAddressBits = (UINT8)RegEax;
+ } else {
+ PhysicalAddressBits = 36;
+ }
+ }
+
+ return PhysicalAddressBits;
+}
+
+/**
+ Build resource HOB to cover [0, PhysicalAddressBits length] by excluding
+ all Mmram ranges, MM Profile data, Unblock memory ranges and MMIO ranges.
+
+ @param[in] HobBuffer The pointer of new HOB buffer.
+ @param[in, out] HobBufferSize The available size of the HOB buffer when as input.
+ The used size of when as output.
+ @param[in] PlatformHobList Platform HOB list.
+ @param[in] PlatformHobSize Platform HOB size.
+ @param[in] Block Pointer of MMRAM descriptor block.
+ @param[in] MmProfileDataHob Pointer to MM profile data HOB.
+**/
+VOID
+MmIplBuildResourceHobForAllSystemMemory (
+ IN UINT8 *HobBuffer,
+ IN OUT UINTN *HobBufferSize,
+ IN VOID *PlatformHobList,
+ IN UINTN PlatformHobSize,
+ IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block,
+ IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob
+ )
+{
+ UINTN Index;
+ UINTN Count;
+ UINTN PlatformRegionCount;
+ UINTN UsedSize;
+ UINT64 PreviousAddress;
+ UINT64 MaxAddress;
+ MM_IPL_MEMORY_REGION *MemoryRegions;
+ MM_IPL_MEMORY_REGION SortBuffer;
+ UINTN UnblockRegionCount;
+
+ MaxAddress = LShiftU64 (1, MmIplCalculateMaximumSupportAddress ());
+
+ //
+ // Get the count of platform memory regions
+ //
+ PlatformRegionCount = 0;
+ if ((PlatformHobList != NULL) && (PlatformHobSize != 0)) {
+ CollectPlatformMemoryRegions (PlatformHobList, PlatformHobSize, NULL, &PlatformRegionCount);
+ }
+
+ //
+ // Get the count of platform memory regions
+ //
+ UnblockRegionCount = 0;
+ CollectUnblockMemoryRegions (NULL, &UnblockRegionCount);
+
+ //
+ // Allocate buffer for platform memory regions, unblock memory regions,
+ // MM Profile data, MMRam ranges, an extra terminator.
+ //
+ Count = PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions + ((MmProfileDataHob != NULL) ? 1 : 0) + 1;
+ MemoryRegions = AllocatePages (EFI_SIZE_TO_PAGES (Count * sizeof (*MemoryRegions)));
+ ASSERT (MemoryRegions != NULL);
+ if (MemoryRegions == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a:%d - No enough memory\n", __func__, __LINE__));
+ CpuDeadLoop ();
+ return;
+ }
+
+ //
+ // The very last region is the terminator
+ //
+ MemoryRegions[Count - 1].Base = MaxAddress;
+ MemoryRegions[Count - 1].Length = 0;
+
+ //
+ // Collect platform memory regions
+ //
+ if (PlatformRegionCount != 0) {
+ CollectPlatformMemoryRegions (PlatformHobList, PlatformHobSize, MemoryRegions, &PlatformRegionCount);
+ }
+
+ //
+ // Collect unblock memory regions
+ //
+ if (UnblockRegionCount != 0) {
+ CollectUnblockMemoryRegions (&MemoryRegions[PlatformRegionCount], &UnblockRegionCount);
+ }
+
+ //
+ // Collect SMRAM regions
+ //
+ for (Index = 0; Index < Block->NumberOfMmReservedRegions; Index++) {
+ MemoryRegions[PlatformRegionCount + UnblockRegionCount + Index].Base = Block->Descriptor[Index].CpuStart;
+ MemoryRegions[PlatformRegionCount + UnblockRegionCount + Index].Length = Block->Descriptor[Index].PhysicalSize;
+ }
+
+ //
+ // Collect MM profile database region
+ //
+ if (MmProfileDataHob != NULL) {
+ MemoryRegions[PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions].Base = MmProfileDataHob->AllocDescriptor.MemoryBaseAddress;
+ MemoryRegions[PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions].Length = MmProfileDataHob->AllocDescriptor.MemoryLength;
+ }
+
+ //
+ // Build system memory resource HOBs excluding platform memory regions, SMRAM regions, MmProfile database, Unblocked memory regions.
+ //
+ QuickSort (MemoryRegions, Count, sizeof (*MemoryRegions), MemoryRegionBaseAddressCompare, &SortBuffer);
+ UsedSize = 0;
+ PreviousAddress = 0;
+ for (Index = 0; Index < Count; Index++) {
+ ASSERT (MaxAddress >= MemoryRegions[Index].Base + MemoryRegions[Index].Length);
+
+ if (MemoryRegions[Index].Base > PreviousAddress) {
+ if (*HobBufferSize >= UsedSize + sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
+ MmIplBuildMemoryResourceHob (
+ (EFI_HOB_RESOURCE_DESCRIPTOR *)(HobBuffer + UsedSize),
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ FeaturePcdGet (PcdCpuSmmProfileEnable) ? MM_RESOURCE_ATTRIBUTE_LOGGING : 0,
+ PreviousAddress,
+ MemoryRegions[Index].Base - PreviousAddress,
+ &gEfiCallerIdGuid
+ );
+ }
+
+ UsedSize += sizeof (EFI_HOB_RESOURCE_DESCRIPTOR);
+ }
+
+ PreviousAddress = MemoryRegions[Index].Base + MemoryRegions[Index].Length;
+ }
+
+ *HobBufferSize = UsedSize;
+ FreePages (MemoryRegions, EFI_SIZE_TO_PAGES (Count * sizeof (EFI_MEMORY_DESCRIPTOR)));
+}
+
+/**
+ Get remaining size for building HOBs.
+
+ @param[in] TotalHobSize Total size of foundation HOBs.
+ @param[in] UsedSize Required HOBs' size.
+
+ @retval MAX remaining size for building HOBs
+**/
+UINTN
+GetRemainingHobSize (
+ IN UINTN TotalHobSize,
+ IN UINTN UsedSize
+ )
+{
+ if (TotalHobSize > UsedSize) {
+ return TotalHobSize - UsedSize;
+ } else {
+ return 0;
+ }
+}
+
+/**
+ Create the MM foundation specific HOB list which StandaloneMm Core needed.
+
+ This function build the MM foundation specific HOB list needed by StandaloneMm Core
+ based on the PEI HOB list.
+
+ @param[in] FoundationHobList The foundation HOB list to be used for HOB creation.
+ @param[in, out] FoundationHobSize The foundation HOB size.
+ On return, the expected/used size.
+ @param[in] PlatformHobList Platform HOB list.
+ @param[in] PlatformHobSize Platform HOB size.
+ @param[in] MmFvBase Base of firmare volume which included MM core dirver.
+ @param[in] MmFvSize Size of firmare volume which included MM core dirver.
+ @param[in] MmCoreFileName File name of MM core dirver.
+ @param[in] MmCoreImageAddress Image address of MM core dirver.
+ @param[in] MmCoreImageSize Image size of MM core dirver.
+ @param[in] MmCoreEntryPoint Entry pinter of MM core dirver.
+ @param[in] MmProfileDataHob Pointer to Mm profile data HOB.
+ @param[in] Block Pointer of MMRAM descriptor block.
+
+ @retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation.
+ BufferSize is updated to indicate the expected buffer size.
+ When the input BufferSize is bigger than the expected buffer size,
+ the BufferSize value will be changed the used buffer size.
+ @retval RETURN_SUCCESS HOB List is created/updated successfully or the input Length is 0.
+
+**/
+RETURN_STATUS
+CreateMmFoundationHobList (
+ IN UINT8 *FoundationHobList,
+ IN OUT UINTN *FoundationHobSize,
+ IN UINT8 *PlatformHobList,
+ IN UINTN PlatformHobSize,
+ IN EFI_PHYSICAL_ADDRESS MmFvBase,
+ IN UINT64 MmFvSize,
+ IN EFI_GUID *MmCoreFileName,
+ IN EFI_PHYSICAL_ADDRESS MmCoreImageAddress,
+ IN UINT64 MmCoreImageSize,
+ IN EFI_PHYSICAL_ADDRESS MmCoreEntryPoint,
+ IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob,
+ IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block
+ )
+{
+ UINTN UsedSize;
+ RETURN_STATUS Status;
+ UINTN HobLength;
+
+ ASSERT (FoundationHobSize != NULL);
+
+ ASSERT (
+ ((*FoundationHobSize != 0) && (FoundationHobList != NULL)) ||
+ ((*FoundationHobSize == 0) && (FoundationHobList == NULL))
+ );
+
+ if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ //
+ // When SmmProfile is enabled, all DRAM is accessible from SMM drivers' perspective.
+ // However, underline Cpu SMM driver does not map the DRAM so that every access to it triggers #PF.
+ // #PF handler records the access then sets up the mapping in the page table to allow the temporary access by current instruction.
+ // The mapping is revoked before next instruction runs.
+ //
+ ASSERT (!PcdGetBool (PcdCpuSmmRestrictedMemoryAccess));
+ }
+
+ UsedSize = 0;
+
+ //
+ // Build communication buffer HOB in MM HOB list
+ //
+ HobLength = *FoundationHobSize;
+ MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gMmCommBufferHobGuid, FALSE);
+ UsedSize += HobLength;
+
+ //
+ // Build MmCore module HOB in MM HOB list
+ //
+ HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
+ MmIplBuildMmCoreModuleHob (
+ FoundationHobList + UsedSize,
+ &HobLength,
+ MmCoreFileName,
+ MmCoreImageAddress,
+ MmCoreImageSize,
+ MmCoreEntryPoint
+ );
+
+ UsedSize += HobLength;
+
+ //
+ // BFV address for StandaloneMm Core
+ //
+ HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
+ MmIplBuildFvHob (FoundationHobList + UsedSize, &HobLength, MmFvBase, MmFvSize);
+ UsedSize += HobLength;
+
+ //
+ // Build MM ACPI S3 Enable HOB
+ //
+ HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
+ MmIplBuildMmAcpiS3EnableHob (FoundationHobList + UsedSize, &HobLength);
+ UsedSize += HobLength;
+
+ //
+ // Build MM CPU sync configuration HOB
+ //
+ HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
+ MmIplBuildMmCpuSyncConfigHob (FoundationHobList + UsedSize, &HobLength);
+ UsedSize += HobLength;
+
+ //
+ // Build CPU SMM base HOB in MM HOB list
+ //
+ HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
+ MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gSmmBaseHobGuid, TRUE);
+ UsedSize += HobLength;
+
+ //
+ // Build SMRAM memory Hob in MM HOB list
+ //
+ HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
+ MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gEfiSmmSmramMemoryGuid, FALSE);
+ UsedSize += HobLength;
+
+ //
+ // Build Mp Information2 Hob in MM HOB list
+ //
+ HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
+ MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gMpInformation2HobGuid, TRUE);
+ UsedSize += HobLength;
+
+ //
+ // Build ACPI variable HOB
+ //
+ HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
+ MmIplCopyGuidHob (FoundationHobList + UsedSize, &HobLength, &gEfiAcpiVariableGuid, FALSE);
+ UsedSize += HobLength;
+
+ if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ //
+ // Build memory allocation and resource HOB for MM profile data
+ //
+ HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
+ MmIplBuildMmProfileHobs (FoundationHobList + UsedSize, &HobLength);
+ UsedSize += HobLength;
+ }
+
+ //
+ // Build resource HOB for unblocked region
+ //
+ HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
+ MmIplBuildResourceHobForUnblockedRegion (FoundationHobList + UsedSize, &HobLength);
+ UsedSize += HobLength;
+
+ if (!PcdGetBool (PcdCpuSmmRestrictedMemoryAccess)) {
+ //
+ // All system memory (DRAM) is accessible.
+ // When SMM Profile is enabled:
+ // * Access to regions included all Mmram ranges, MM Profile data, Unblock memory ranges and MMIO ranges do not require logging.
+ // * Access to other system memory requires logging.
+ //
+ HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
+ MmIplBuildResourceHobForAllSystemMemory (
+ FoundationHobList + UsedSize,
+ &HobLength,
+ PlatformHobList,
+ PlatformHobSize,
+ Block,
+ MmProfileDataHob
+ );
+ UsedSize += HobLength;
+ }
+
+ if (*FoundationHobSize < UsedSize) {
+ Status = RETURN_BUFFER_TOO_SMALL;
+ } else {
+ Status = RETURN_SUCCESS;
+ }
+
+ *FoundationHobSize = UsedSize;
+ return Status;
+}
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
new file mode 100644
index 0000000..b1cd3c1
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
@@ -0,0 +1,800 @@
+/** @file
+ MM IPL that load the MM Core into MMRAM at PEI stage
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "StandaloneMmIplPei.h"
+
+EFI_PEI_MM_COMMUNICATION_PPI mMmCommunicationPpi = { Communicate };
+
+EFI_PEI_PPI_DESCRIPTOR mPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMmCommunicationPpiGuid,
+ &mMmCommunicationPpi
+};
+
+EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiEndOfPeiSignalPpiGuid,
+ EndOfPeiCallback
+};
+
+/**
+ Communicates with a registered handler.
+
+ This function provides a service to send and receive messages from a registered UEFI service.
+
+ @param[in] This The EFI_PEI_MM_COMMUNICATION_PPI instance.
+ @param[in, out] CommBuffer A pointer to the buffer to convey into MMRAM.
+ @param[in, out] CommSize The size of the data buffer being passed in.On exit, the size of data
+ being returned. Zero if the handler does not wish to reply with any data.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+ @retval EFI_NOT_STARTED The service is NOT started.
+**/
+EFI_STATUS
+EFIAPI
+Communicate (
+ IN CONST EFI_PEI_MM_COMMUNICATION_PPI *This,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_MM_CONTROL_PPI *MmControl;
+ UINT8 SmiCommand;
+ UINTN Size;
+ UINTN TempCommSize;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ MM_COMM_BUFFER *MmCommBuffer;
+ MM_COMM_BUFFER_STATUS *MmCommBufferStatus;
+
+ DEBUG ((DEBUG_INFO, "StandaloneMmIpl Communicate Enter\n"));
+
+ GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid);
+ if (GuidHob != NULL) {
+ MmCommBuffer = GET_GUID_HOB_DATA (GuidHob);
+ MmCommBufferStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)MmCommBuffer->Status;
+ } else {
+ DEBUG ((DEBUG_ERROR, "MmCommBuffer is not existed !!!\n"));
+ ASSERT (GuidHob != NULL);
+ return EFI_NOT_FOUND;
+ }
+
+ SmiCommand = 0;
+ Size = sizeof (SmiCommand);
+
+ //
+ // Check parameters
+ //
+ if ((CommBuffer == NULL) || (CommSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ TempCommSize = *CommSize;
+ //
+ // CommSize must hold HeaderGuid and MessageLength
+ //
+ if (TempCommSize < OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (TempCommSize > EFI_PAGES_TO_SIZE (MmCommBuffer->NumberOfPages)) {
+ DEBUG ((DEBUG_ERROR, "Communicate buffer size (%d) is over MAX (%d) size!", TempCommSize, EFI_PAGES_TO_SIZE (MmCommBuffer->NumberOfPages)));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CopyMem ((VOID *)(UINTN)MmCommBuffer->PhysicalStart, CommBuffer, TempCommSize);
+ MmCommBufferStatus->IsCommBufferValid = TRUE;
+
+ //
+ // Generate Software SMI
+ //
+ Status = PeiServicesLocatePpi (&gEfiPeiMmControlPpiGuid, 0, NULL, (VOID **)&MmControl);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = MmControl->Trigger (
+ (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (),
+ MmControl,
+ (INT8 *)&SmiCommand,
+ &Size,
+ FALSE,
+ 0
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Return status from software SMI
+ //
+ *CommSize = (UINTN)MmCommBufferStatus->ReturnBufferSize;
+
+ //
+ // Copy the returned data to the non-mmram buffer (CommBuffer)
+ //
+ CopyMem (CommBuffer, (VOID *)(MmCommBuffer->PhysicalStart), *CommSize);
+
+ Status = (EFI_STATUS)MmCommBufferStatus->ReturnStatus;
+ if (Status != EFI_SUCCESS) {
+ DEBUG ((DEBUG_ERROR, "StandaloneMmIpl Communicate failed (%r)\n", Status));
+ } else {
+ MmCommBufferStatus->IsCommBufferValid = FALSE;
+ }
+
+ return Status;
+}
+
+/**
+ Search all the available firmware volumes for MM Core driver.
+
+ @param MmFvBase Base address of FV which included MM Core driver.
+ @param MmFvSize Size of FV which included MM Core driver.
+ @param MmCoreFileName GUID of MM Core.
+ @param MmCoreImageAddress MM Core image address.
+
+ @retval EFI_SUCCESS The specified FFS section was returned.
+ @retval EFI_NOT_FOUND The specified FFS section could not be found.
+
+**/
+EFI_STATUS
+LocateMmCoreFv (
+ OUT EFI_PHYSICAL_ADDRESS *MmFvBase,
+ OUT UINTN *MmFvSize,
+ OUT EFI_GUID *MmCoreFileName,
+ OUT VOID **MmCoreImageAddress
+ )
+{
+ EFI_STATUS Status;
+ UINTN FvIndex;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+ EFI_PEI_FILE_HANDLE FileHandle;
+ EFI_PE32_SECTION *SectionData;
+ EFI_FV_INFO VolumeInfo;
+
+ //
+ // Search all FV
+ //
+ VolumeHandle = NULL;
+ for (FvIndex = 0; ; FvIndex++) {
+ Status = PeiServicesFfsFindNextVolume (FvIndex, &VolumeHandle);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ //
+ // Search MM Core FFS
+ //
+ FileHandle = NULL;
+ Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_MM_CORE_STANDALONE, VolumeHandle, &FileHandle);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ ASSERT (FileHandle != NULL);
+ if (FileHandle != NULL) {
+ CopyGuid (MmCoreFileName, &((EFI_FFS_FILE_HEADER *)FileHandle)->Name);
+ }
+
+ //
+ // Search Section
+ //
+ Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, MmCoreImageAddress);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Get MM Core section data.
+ //
+ SectionData = (EFI_PE32_SECTION *)((UINT8 *)*MmCoreImageAddress - sizeof (EFI_PE32_SECTION));
+ ASSERT (SectionData->Type == EFI_SECTION_PE32);
+
+ //
+ // This is the FV that contains MM Core.
+ //
+ Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);
+ if (!EFI_ERROR (Status)) {
+ *MmFvBase = (EFI_PHYSICAL_ADDRESS)(UINTN)VolumeInfo.FvStart;
+ *MmFvSize = VolumeInfo.FvSize;
+ return EFI_SUCCESS;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Create HOB list for Standalone MM core.
+
+ @param[out] HobSize HOB size of fundation and platform HOB list.
+ @param[in] MmCommBuffer Pointer of MM communication buffer.
+ @param[in] MmFvBase Base of MM FV which included MM core driver.
+ @param[in] MmFvSize Size of MM FV which included MM core driver.
+ @param[in] MmCoreFileName File GUID of MM core driver.
+ @param[in] MmCoreImageAddress Address of MM core image.
+ @param[in] MmCoreImageSize Size of MM core image.
+ @param[in] MmCoreEntryPoint Entry point of MM core driver.
+ @param[in] Block Pointer of MMRAM descriptor block.
+
+ @retval HobList If fundation and platform HOBs not existed,
+ it is pointed to PEI HOB List. If existed,
+ it is pointed to fundation and platform HOB list.
+**/
+VOID *
+CreatMmHobList (
+ OUT UINTN *HobSize,
+ IN MM_COMM_BUFFER *MmCommBuffer,
+ IN EFI_PHYSICAL_ADDRESS MmFvBase,
+ IN UINT64 MmFvSize,
+ IN EFI_GUID *MmCoreFileName,
+ IN PHYSICAL_ADDRESS MmCoreImageAddress,
+ IN UINT64 MmCoreImageSize,
+ IN PHYSICAL_ADDRESS MmCoreEntryPoint,
+ IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block
+ )
+{
+ EFI_STATUS Status;
+ VOID *HobList;
+ VOID *PlatformHobList;
+ UINTN PlatformHobSize;
+ UINTN BufferSize;
+ UINTN FoundationHobSize;
+ EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob;
+
+ //
+ // Get platform HOBs
+ //
+ PlatformHobSize = 0;
+ Status = CreateMmPlatformHob (NULL, &PlatformHobSize);
+ if (Status == RETURN_BUFFER_TOO_SMALL) {
+ ASSERT (PlatformHobSize != 0);
+ //
+ // Create platform HOBs for MM foundation to get MMIO HOB data.
+ //
+ PlatformHobList = AllocatePages (EFI_SIZE_TO_PAGES (PlatformHobSize));
+ ASSERT (PlatformHobList != NULL);
+ if (PlatformHobList == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Out of resource to create platform MM HOBs\n", __func__));
+ CpuDeadLoop ();
+ }
+
+ BufferSize = PlatformHobSize;
+ Status = CreateMmPlatformHob (PlatformHobList, &PlatformHobSize);
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (BufferSize == PlatformHobSize);
+ }
+
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Build memory allocation HOB in PEI HOB list for MM profile data.
+ //
+ MmProfileDataHob = NULL;
+ if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ MmProfileDataHob = BuildMmProfileDataHobInPeiHobList ();
+ }
+
+ //
+ // Get size of foundation HOBs
+ //
+ FoundationHobSize = 0;
+ Status = CreateMmFoundationHobList (
+ NULL,
+ &FoundationHobSize,
+ PlatformHobList,
+ PlatformHobSize,
+ MmFvBase,
+ MmFvSize,
+ MmCoreFileName,
+ MmCoreImageAddress,
+ MmCoreImageSize,
+ MmCoreEntryPoint,
+ MmProfileDataHob,
+ Block
+ );
+ FreePages (PlatformHobList, EFI_SIZE_TO_PAGES (PlatformHobSize));
+ ASSERT (Status == RETURN_BUFFER_TOO_SMALL);
+ ASSERT (FoundationHobSize != 0);
+
+ //
+ // Final result includes platform HOBs, foundation HOBs and a END node.
+ //
+ *HobSize = PlatformHobSize + FoundationHobSize + sizeof (EFI_HOB_GENERIC_HEADER);
+ HobList = AllocatePages (EFI_SIZE_TO_PAGES (*HobSize));
+ ASSERT (HobList != NULL);
+ if (HobList == NULL) {
+ DEBUG ((DEBUG_ERROR, "Out of resource to create MM HOBs\n"));
+ CpuDeadLoop ();
+ }
+
+ //
+ // Get platform HOBs
+ //
+ Status = CreateMmPlatformHob (HobList, &PlatformHobSize);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get foundation HOBs
+ //
+ Status = CreateMmFoundationHobList (
+ (UINT8 *)HobList + PlatformHobSize,
+ &FoundationHobSize,
+ HobList,
+ PlatformHobSize,
+ MmFvBase,
+ MmFvSize,
+ MmCoreFileName,
+ MmCoreImageAddress,
+ MmCoreImageSize,
+ MmCoreEntryPoint,
+ MmProfileDataHob,
+ Block
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create MM HOB list end.
+ //
+ MmIplCreateHob ((UINT8 *)HobList + PlatformHobSize + FoundationHobSize, EFI_HOB_TYPE_END_OF_HOB_LIST, sizeof (EFI_HOB_GENERIC_HEADER));
+
+ return HobList;
+}
+
+/**
+ Find largest unallocated MMRAM in current MMRAM descriptor block
+
+ @param[in, out] LagestMmramRangeIndex Lagest mmram range index.
+ @param[in] CurrentBlock Current MMRAM descriptor block.
+
+**/
+VOID
+FindLargestMmramRange (
+ IN OUT UINTN *LagestMmramRangeIndex,
+ IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *CurrentBlock
+ )
+{
+ UINTN Index;
+ UINT64 MaxSize;
+ BOOLEAN Found;
+ EFI_MMRAM_DESCRIPTOR *MmramRanges;
+
+ MmramRanges = CurrentBlock->Descriptor;
+
+ //
+ // Find largest Mmram range.
+ //
+ Found = FALSE;
+ for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < CurrentBlock->NumberOfMmReservedRegions; Index++) {
+ //
+ // Skip any MMRAM region that is already allocated, needs testing, or needs ECC initialization
+ //
+ if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
+ continue;
+ }
+
+ if (MmramRanges[Index].CpuStart >= BASE_1MB) {
+ if ((MmramRanges[Index].CpuStart + MmramRanges[Index].PhysicalSize) <= BASE_4GB) {
+ if (MmramRanges[Index].PhysicalSize >= MaxSize) {
+ Found = TRUE;
+ *LagestMmramRangeIndex = Index;
+ MaxSize = MmramRanges[Index].PhysicalSize;
+ }
+ }
+ }
+ }
+
+ if (Found == FALSE) {
+ DEBUG ((DEBUG_ERROR, "Not found largest unlocated MMRAM\n"));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+
+ return;
+}
+
+/**
+ Allocate available MMRAM for MM core image.
+
+ @param[in] Pages Page count of MM core image.
+ @param[out] NewBlock Pointer of new mmram block HOB.
+
+ @return EFI_PHYSICAL_ADDRESS Address for MM core image to be loaded in MMRAM.
+**/
+EFI_PHYSICAL_ADDRESS
+MmIplAllocateMmramPage (
+ IN UINTN Pages,
+ OUT EFI_MMRAM_HOB_DESCRIPTOR_BLOCK **NewBlock
+ )
+{
+ UINTN LagestMmramRangeIndex;
+ UINT32 FullMmramRangeCount;
+ EFI_HOB_GUID_TYPE *MmramInfoHob;
+ EFI_MMRAM_DESCRIPTOR *Largest;
+ EFI_MMRAM_DESCRIPTOR *Allocated;
+ EFI_MMRAM_DESCRIPTOR *FullMmramRanges;
+ EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *CurrentBlock;
+ EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *NewDescriptorBlock;
+
+ MmramInfoHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);
+ ASSERT (MmramInfoHob != NULL);
+ if (MmramInfoHob == NULL) {
+ DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
+ return 0;
+ }
+
+ CurrentBlock = (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *)(GET_GUID_HOB_DATA (MmramInfoHob));
+
+ //
+ // 1. Find largest unallocated MMRAM region
+ //
+ FindLargestMmramRange (&LagestMmramRangeIndex, CurrentBlock);
+ ASSERT (LagestMmramRangeIndex < CurrentBlock->NumberOfMmReservedRegions);
+
+ //
+ // 2. Split the largest region and mark the allocated region as ALLOCATED
+ //
+ FullMmramRangeCount = CurrentBlock->NumberOfMmReservedRegions + 1;
+ NewDescriptorBlock = (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *)BuildGuidHob (
+ &gEfiSmmSmramMemoryGuid,
+ sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK) + ((FullMmramRangeCount - 1) * sizeof (EFI_MMRAM_DESCRIPTOR))
+ );
+ ASSERT (NewDescriptorBlock != NULL);
+
+ NewDescriptorBlock->NumberOfMmReservedRegions = FullMmramRangeCount;
+ FullMmramRanges = NewDescriptorBlock->Descriptor;
+
+ //
+ // Get current MMRAM descriptors and fill to the full MMRAM ranges
+ //
+ CopyMem (NewDescriptorBlock->Descriptor, CurrentBlock->Descriptor, CurrentBlock->NumberOfMmReservedRegions * sizeof (EFI_MMRAM_DESCRIPTOR));
+
+ Largest = &FullMmramRanges[LagestMmramRangeIndex];
+ ASSERT ((Largest->PhysicalSize & EFI_PAGE_MASK) == 0);
+ ASSERT (Largest->PhysicalSize > EFI_PAGES_TO_SIZE (Pages));
+
+ Allocated = &NewDescriptorBlock->Descriptor[NewDescriptorBlock->NumberOfMmReservedRegions - 1];
+
+ //
+ // Allocate MMRAM
+ //
+ Largest->PhysicalSize -= EFI_PAGES_TO_SIZE (Pages);
+ Allocated->CpuStart = Largest->CpuStart + Largest->PhysicalSize;
+ Allocated->PhysicalStart = Largest->PhysicalStart + Largest->PhysicalSize;
+ Allocated->RegionState = Largest->RegionState | EFI_ALLOCATED;
+ Allocated->PhysicalSize = EFI_PAGES_TO_SIZE (Pages);
+
+ //
+ // Scrub old one
+ //
+ ZeroMem (&MmramInfoHob->Name, sizeof (MmramInfoHob->Name));
+
+ //
+ // New MMRAM descriptor block
+ //
+ *NewBlock = NewDescriptorBlock;
+
+ return Allocated->CpuStart;
+}
+
+/**
+ Load the MM Core image into MMRAM and executes the MM Core from MMRAM.
+
+ @param[in] MmCommBuffer MM communicate buffer
+
+ @return EFI_STATUS Execute MM core successfully.
+ Other Execute MM core failed.
+**/
+EFI_STATUS
+ExecuteMmCoreFromMmram (
+ IN MM_COMM_BUFFER *MmCommBuffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN PageCount;
+ VOID *MmHobList;
+ UINTN MmHobSize;
+ EFI_GUID MmCoreFileName;
+ UINTN MmFvSize;
+ EFI_PHYSICAL_ADDRESS MmFvBase;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ STANDALONE_MM_FOUNDATION_ENTRY_POINT Entry;
+ EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block;
+
+ MmFvBase = 0;
+ MmFvSize = 0;
+ //
+ // Search all Firmware Volumes for a PE/COFF image in a file of type MM_CORE_STANDALONE.
+ //
+ Status = LocateMmCoreFv (&MmFvBase, &MmFvSize, &MmCoreFileName, &ImageContext.Handle);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Unblock the MM FV range to be accessible from inside MM
+ //
+ if ((MmFvBase != 0) && (MmFvSize != 0)) {
+ Status = MmUnblockMemoryRequest (MmFvBase, EFI_SIZE_TO_PAGES (MmFvSize));
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Initialize ImageContext
+ //
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+ //
+ // Get information about the image being loaded
+ //
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
+
+ //
+ // Allocate memory for the image being loaded from unallocated mmram range
+ //
+ ImageContext.ImageAddress = MmIplAllocateMmramPage (PageCount, &Block);
+ if (ImageContext.ImageAddress == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Align buffer on section boundary
+ //
+ ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
+ ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
+
+ //
+ // Print debug message showing MM Core load address.
+ //
+ DEBUG ((DEBUG_INFO, "StandaloneMM IPL loading MM Core at MMRAM address %p\n", (VOID *)(UINTN)ImageContext.ImageAddress));
+
+ //
+ // Load the image to our new buffer
+ //
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Relocate the image in our new buffer
+ //
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "MmCoreImageBase - 0x%016lx\n", ImageContext.ImageAddress));
+ DEBUG ((DEBUG_INFO, "MmCoreImageSize - 0x%016lx\n", ImageContext.ImageSize));
+
+ //
+ // Flush the instruction cache so the image data are written before we execute it
+ //
+ InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
+
+ //
+ // Get HOB list for Standalone MM Core.
+ //
+ MmHobSize = 0;
+ MmHobList = CreatMmHobList (
+ &MmHobSize,
+ MmCommBuffer,
+ MmFvBase,
+ MmFvSize,
+ &MmCoreFileName,
+ ImageContext.ImageAddress,
+ ImageContext.ImageSize,
+ ImageContext.EntryPoint,
+ Block
+ );
+
+ //
+ // Print debug message showing Standalone MM Core entry point address.
+ //
+ DEBUG ((DEBUG_INFO, "StandaloneMM IPL calling Standalone MM Core at MMRAM address - 0x%016lx\n", ImageContext.EntryPoint));
+
+ //
+ // Execute image
+ //
+ Entry = (STANDALONE_MM_FOUNDATION_ENTRY_POINT)(UINTN)ImageContext.EntryPoint;
+ Status = Entry (MmHobList);
+ ASSERT_EFI_ERROR (Status);
+ FreePages (MmHobList, EFI_SIZE_TO_PAGES (MmHobSize));
+ }
+ }
+
+ return Status;
+}
+
+/**
+ This is the callback function on end of PEI.
+
+ This callback is used for call MmEndOfPeiHandler in standalone MM core.
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param NotifyDescriptor The notification structure this PEIM registered on install.
+ @param Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_SUCCESS Exit boot services successfully.
+ @retval Other Exit boot services failed.
+**/
+EFI_STATUS
+EFIAPI
+EndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_MM_COMMUNICATE_HEADER CommunicateHeader;
+ UINTN Size;
+ EFI_STATUS Status;
+
+ //
+ // Use Guid to initialize EFI_MM_COMMUNICATE_HEADER structure
+ //
+ CopyGuid (&CommunicateHeader.HeaderGuid, &gEfiMmEndOfPeiProtocol);
+ CommunicateHeader.MessageLength = 1;
+ CommunicateHeader.Data[0] = 0;
+
+ //
+ // Generate the Software SMI and return the result
+ //
+ Size = sizeof (CommunicateHeader);
+ Status = Communicate (NULL, &CommunicateHeader, &Size);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Dispatch StandaloneMm drivers in MM.
+
+ StandaloneMm core will exit when MmEntryPoint was registered in CPU
+ StandaloneMm driver, and issue a software SMI by communicate mode to
+ dispatch other StandaloneMm drivers.
+
+ @retval EFI_SUCCESS Dispatch StandaloneMm drivers successfully.
+ @retval Other Dispatch StandaloneMm drivers failed.
+
+**/
+EFI_STATUS
+MmIplDispatchMmDrivers (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ EFI_MM_COMMUNICATE_HEADER CommunicateHeader;
+
+ //
+ // Use Guid to initialize EFI_MM_COMMUNICATE_HEADER structure
+ //
+ CopyGuid (&CommunicateHeader.HeaderGuid, &gEventMmDispatchGuid);
+ CommunicateHeader.MessageLength = 1;
+ CommunicateHeader.Data[0] = 0;
+
+ //
+ // Generate the Software SMI and return the result
+ //
+ Size = sizeof (CommunicateHeader);
+ Status = Communicate (NULL, &CommunicateHeader, &Size);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Build communication buffer HOB.
+
+ @return MM_COMM_BUFFER Pointer of MM communication buffer
+
+**/
+MM_COMM_BUFFER *
+MmIplBuildCommBufferHob (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ MM_COMM_BUFFER *MmCommBuffer;
+ UINT64 MmCommBufferPages;
+
+ MmCommBufferPages = PcdGet32 (PcdMmCommBufferPages);
+
+ MmCommBuffer = BuildGuidHob (&gMmCommBufferHobGuid, sizeof (MM_COMM_BUFFER));
+ ASSERT (MmCommBuffer != NULL);
+
+ //
+ // Set MM communicate buffer size
+ //
+ MmCommBuffer->NumberOfPages = MmCommBufferPages;
+
+ //
+ // Allocate runtime memory for MM communicate buffer
+ //
+ MmCommBuffer->PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateRuntimePages (MmCommBufferPages);
+ if (MmCommBuffer->PhysicalStart == 0) {
+ DEBUG ((DEBUG_ERROR, "Fail to allocate MM communication buffer\n"));
+ ASSERT (MmCommBuffer->PhysicalStart != 0);
+ }
+
+ //
+ // Build MM unblock memory region HOB for MM communication buffer
+ //
+ Status = MmUnblockMemoryRequest (MmCommBuffer->PhysicalStart, MmCommBufferPages);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Allocate runtime memory for MM communication status parameters :
+ // ReturnStatus, ReturnBufferSize, IsCommBufferValid
+ //
+ MmCommBuffer->Status = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateRuntimePages (EFI_SIZE_TO_PAGES (sizeof (MM_COMM_BUFFER_STATUS)));
+ if (MmCommBuffer->Status == 0) {
+ DEBUG ((DEBUG_ERROR, "Fail to allocate memory for MM communication status\n"));
+ ASSERT (MmCommBuffer->Status != 0);
+ }
+
+ //
+ // Build MM unblock memory region HOB for MM communication status
+ //
+ Status = MmUnblockMemoryRequest (MmCommBuffer->Status, EFI_SIZE_TO_PAGES (sizeof (MM_COMM_BUFFER_STATUS)));
+ ASSERT_EFI_ERROR (Status);
+
+ return MmCommBuffer;
+}
+
+/**
+ The Entry Point for MM IPL at PEI stage.
+
+ Load MM Core into MMRAM.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval Other Some error occurred when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+StandaloneMmIplPeiEntry (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ MM_COMM_BUFFER *MmCommBuffer;
+
+ //
+ // Build communication buffer HOB.
+ //
+ MmCommBuffer = MmIplBuildCommBufferHob ();
+ ASSERT (MmCommBuffer != NULL);
+
+ //
+ // Locate and execute Mm Core to dispatch MM drivers.
+ //
+ Status = ExecuteMmCoreFromMmram (MmCommBuffer);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install MmCommunicationPpi
+ //
+ Status = PeiServicesInstallPpi (&mPpiList);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create end of pei callback to call MmEndOfPeiHandler
+ //
+ Status = PeiServicesNotifyPpi (&mNotifyList);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Dispatch StandaloneMm drivers in MM
+ //
+ Status = MmIplDispatchMmDrivers ();
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h
new file mode 100644
index 0000000..9301b8f
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h
@@ -0,0 +1,145 @@
+/** @file
+ Standalone MM IPL Header file
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef STANDALONE_MM_IPL_PEI_H_
+#define STANDALONE_MM_IPL_PEI_H_
+
+#include <StandaloneMm.h>
+#include <Guid/MmCommBuffer.h>
+#include <Guid/MmramMemoryReserve.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MmUnblockMemoryLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Ppi/MmControl.h>
+#include <Ppi/MmCommunication.h>
+#include <Protocol/MmCommunication.h>
+#include <Library/MmPlatformHobProducerLib.h>
+
+/**
+ Communicates with a registered handler.
+
+ This function provides a service to send and receive messages from a registered UEFI service.
+
+ @param[in] This The EFI_PEI_MM_COMMUNICATION_PPI instance.
+ @param[in, out] CommBuffer A pointer to the buffer to convey into MMRAM.
+ @param[in, out] CommSize The size of the data buffer being passed in.On exit, the size of data
+ being returned. Zero if the handler does not wish to reply with any data.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER The CommBuffer was NULL.
+ @retval EFI_NOT_STARTED The service is NOT started.
+**/
+EFI_STATUS
+EFIAPI
+Communicate (
+ IN CONST EFI_PEI_MM_COMMUNICATION_PPI *This,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommSize
+ );
+
+/**
+ This is the callback function on end of PEI.
+
+ This callback is used for call MmEndOfPeiHandler in standalone MM core.
+
+ @param PeiServices General purpose services available to every PEIM.
+ @param NotifyDescriptor The notification structure this PEIM registered on install.
+ @param Ppi Pointer to the PPI data associated with this function.
+ @retval EFI_SUCCESS Exit boot services successfully.
+ @retval Other Exit boot services failed.
+**/
+EFI_STATUS
+EFIAPI
+EndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ Add a new HOB to the HOB List.
+
+ @param[in] Hob The pointer of new HOB buffer.
+ @param[in] HobType Type of the new HOB.
+ @param[in] HobLength Length of the new HOB to allocate.
+
+ @return NULL if there is no space to create a hob.
+ @return The address point to the new created hob.
+
+**/
+VOID *
+MmIplCreateHob (
+ IN VOID *Hob,
+ IN UINT16 HobType,
+ IN UINT16 HobLength
+ );
+
+/**
+ Create the MM foundation specific HOB list which StandaloneMm Core needed.
+
+ This function build the MM foundation specific HOB list needed by StandaloneMm Core
+ based on the PEI HOB list.
+
+ @param[in] FoundationHobList The foundation HOB list to be used for HOB creation.
+ @param[in, out] FoundationHobSize The foundation HOB size.
+ On return, the expected/used size.
+ @param[in] PlatformHobList Platform HOB list.
+ @param[in] PlatformHobSize Platform HOB size.
+ @param[in] MmFvBase Base of firmare volume which included MM core dirver.
+ @param[in] MmFvSize Size of firmare volume which included MM core dirver.
+ @param[in] MmCoreFileName File name of MM core dirver.
+ @param[in] MmCoreImageAddress Image address of MM core dirver.
+ @param[in] MmCoreImageSize Image size of MM core dirver.
+ @param[in] MmCoreEntryPoint Entry pinter of MM core dirver.
+ @param[in] MmProfileDataHob Pointer to MM profile data HOB.
+ @param[in] Block Pointer of MMRAM descriptor block.
+
+ @retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation.
+ BufferSize is updated to indicate the expected buffer size.
+ When the input BufferSize is bigger than the expected buffer size,
+ the BufferSize value will be changed the used buffer size.
+ @retval RETURN_SUCCESS HOB List is created/updated successfully or the input Length is 0.
+
+**/
+RETURN_STATUS
+CreateMmFoundationHobList (
+ IN UINT8 *FoundationHobList,
+ IN OUT UINTN *FoundationHobSize,
+ IN UINT8 *PlatformHobList,
+ IN UINTN PlatformHobSize,
+ IN EFI_PHYSICAL_ADDRESS MmFvBase,
+ IN UINT64 MmFvSize,
+ IN EFI_GUID *MmCoreFileName,
+ IN EFI_PHYSICAL_ADDRESS MmCoreImageAddress,
+ IN UINT64 MmCoreImageSize,
+ IN EFI_PHYSICAL_ADDRESS MmCoreEntryPoint,
+ IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob,
+ IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block
+ );
+
+/**
+ Build memory allocation HOB in PEI HOB list for MM profile data.
+
+ This function is to allocate memory for MM profile data.
+
+ @return NULL if MM profile data memory allocation HOB build fail.
+ @return Pointer of MM profile data memory allocation HOB if build successfully.
+
+**/
+EFI_HOB_MEMORY_ALLOCATION *
+BuildMmProfileDataHobInPeiHobList (
+ VOID
+ );
+
+#endif
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
new file mode 100644
index 0000000..dfc1812
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
@@ -0,0 +1,81 @@
+## @file
+# This module provide a Standalone MM compliant implementation of MM IPL PEIM.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = StandaloneMmIplPei
+ FILE_GUID = 578A0D17-2DC0-4C7D-A121-D8D771923BB0
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ ENTRY_POINT = StandaloneMmIplPeiEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = X64
+#
+
+[Sources]
+ StandaloneMmIplPei.c
+ StandaloneMmIplPei.h
+ MmFoundationHob.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ PeiServicesLib
+ DebugLib
+ HobLib
+ MemoryAllocationLib
+ MmUnblockMemoryLib
+ BaseMemoryLib
+ PeCoffLib
+ CacheMaintenanceLib
+ MmPlatformHobProducerLib
+
+[Guids]
+ gMmCommBufferHobGuid
+ gEfiSmmSmramMemoryGuid
+ gEventMmDispatchGuid
+ gSmmBaseHobGuid
+ gMpInformation2HobGuid
+ gEfiAcpiVariableGuid
+ gMmAcpiS3EnableHobGuid
+ gMmCpuSyncConfigHobGuid
+ gMmProfileDataHobGuid
+ gMmUnblockRegionHobGuid
+
+[Ppis]
+ gEfiPeiMmControlPpiGuid
+ gEfiPeiMmCommunicationPpiGuid
+ gEfiEndOfPeiSignalPpiGuid
+
+[Protocols]
+ gEfiMmEndOfPeiProtocol
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2 ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## CONSUMES
+
+[Pcd.X64]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess ## CONSUMES
+
+[Depex]
+ gEfiPeiMmControlPpiGuid AND gEfiPeiMpServicesPpiGuid
diff --git a/StandaloneMmPkg/Include/Guid/MmCoreData.h b/StandaloneMmPkg/Include/Guid/MmCoreData.h
deleted file mode 100644
index b8be92c..0000000
--- a/StandaloneMmPkg/Include/Guid/MmCoreData.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/** @file
- MM Core data.
-
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
-Copyright (c) 2018 - 2021, Arm Limited. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __MM_CORE_DATA_H__
-#define __MM_CORE_DATA_H__
-
-#define MM_CORE_DATA_HOB_GUID \
- { 0xa160bf99, 0x2aa4, 0x4d7d, { 0x99, 0x93, 0x89, 0x9c, 0xb1, 0x2d, 0xf3, 0x76 }}
-
-extern EFI_GUID gMmCoreDataHobGuid;
-
-typedef struct {
- //
- // Address pointer to MM_CORE_PRIVATE_DATA
- //
- EFI_PHYSICAL_ADDRESS Address;
-} MM_CORE_DATA_HOB_DATA;
-
-///
-/// Define values for the communications buffer used when gEfiEventDxeDispatchGuid is
-/// event signaled. This event is signaled by the DXE Core each time the DXE Core
-/// dispatcher has completed its work. When this event is signaled, the MM Core
-/// if notified, so the MM Core can dispatch MM drivers. If COMM_BUFFER_MM_DISPATCH_ERROR
-/// is returned in the communication buffer, then an error occurred dispatching MM
-/// Drivers. If COMM_BUFFER_MM_DISPATCH_SUCCESS is returned, then the MM Core
-/// dispatched all the drivers it could. If COMM_BUFFER_MM_DISPATCH_RESTART is
-/// returned, then the MM Core just dispatched the MM Driver that registered
-/// the MM Entry Point enabling the use of MM Mode. In this case, the MM Core
-/// should be notified again to dispatch more MM Drivers using MM Mode.
-///
-#define COMM_BUFFER_MM_DISPATCH_ERROR 0x00
-#define COMM_BUFFER_MM_DISPATCH_SUCCESS 0x01
-#define COMM_BUFFER_MM_DISPATCH_RESTART 0x02
-
-///
-/// Signature for the private structure shared between the MM IPL and the MM Core
-///
-#define MM_CORE_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('m', 'm', 'i', 'c')
-
-///
-/// Private structure that is used to share information between the MM IPL and
-/// the MM Core. This structure is allocated from memory of type EfiRuntimeServicesData.
-/// Since runtime memory types are converted to available memory when a legacy boot
-/// is performed, the MM Core must not access any fields of this structure if a legacy
-/// boot is performed. As a result, the MM IPL must create an event notification
-/// for the Legacy Boot event and notify the MM Core that a legacy boot is being
-/// performed. The MM Core can then use this information to filter accesses to
-/// thos structure.
-///
-typedef struct {
- UINT64 Signature;
-
- ///
- /// The number of MMRAM ranges passed from the MM IPL to the MM Core. The MM
- /// Core uses these ranges of MMRAM to initialize the MM Core memory manager.
- ///
- UINT64 MmramRangeCount;
-
- ///
- /// A table of MMRAM ranges passed from the MM IPL to the MM Core. The MM
- /// Core uses these ranges of MMRAM to initialize the MM Core memory manager.
- ///
- EFI_PHYSICAL_ADDRESS MmramRanges;
-
- ///
- /// The MM Foundation Entry Point. The MM Core fills in this field when the
- /// MM Core is initialized. The MM IPL is responsbile for registering this entry
- /// point with the MM Configuration Protocol. The MM Configuration Protocol may
- /// not be available at the time the MM IPL and MM Core are started, so the MM IPL
- /// sets up a protocol notification on the MM Configuration Protocol and registers
- /// the MM Foundation Entry Point as soon as the MM Configuration Protocol is
- /// available.
- ///
- EFI_PHYSICAL_ADDRESS MmEntryPoint;
-
- ///
- /// Boolean flag set to TRUE while an MMI is being processed by the MM Core.
- ///
- BOOLEAN MmEntryPointRegistered;
-
- ///
- /// Boolean flag set to TRUE while an MMI is being processed by the MM Core.
- ///
- BOOLEAN InMm;
-
- ///
- /// This field is set by the MM Core then the MM Core is initialized. This field is
- /// used by the MM Base 2 Protocol and MM Communication Protocol implementations in
- /// the MM IPL.
- ///
- EFI_PHYSICAL_ADDRESS Mmst;
-
- ///
- /// This field is used by the MM Communication Protocol to pass a buffer into
- /// a software MMI handler and for the software MMI handler to pass a buffer back to
- /// the caller of the MM Communication Protocol.
- ///
- EFI_PHYSICAL_ADDRESS CommunicationBuffer;
-
- ///
- /// This field is used by the MM Communication Protocol to pass the size of a buffer,
- /// in bytes, into a software MMI handler and for the software MMI handler to pass the
- /// size, in bytes, of a buffer back to the caller of the MM Communication Protocol.
- ///
- UINT64 BufferSize;
-
- ///
- /// This field is used by the MM Communication Protocol to pass the return status from
- /// a software MMI handler back to the caller of the MM Communication Protocol.
- ///
- UINT64 ReturnStatus;
-
- EFI_PHYSICAL_ADDRESS MmCoreImageBase;
- UINT64 MmCoreImageSize;
- EFI_PHYSICAL_ADDRESS MmCoreEntryPoint;
-
- EFI_PHYSICAL_ADDRESS StandaloneBfvAddress;
-} MM_CORE_PRIVATE_DATA;
-
-#endif
diff --git a/StandaloneMmPkg/Include/Library/FvLib.h b/StandaloneMmPkg/Include/Library/FvLib.h
index 1eb9ea7..3b603e4 100644
--- a/StandaloneMmPkg/Include/Library/FvLib.h
+++ b/StandaloneMmPkg/Include/Library/FvLib.h
@@ -87,7 +87,7 @@ FindFfsSectionInSections (
@param FfsFileHeader Pointer to the current file to search.
@param SectionData Pointer to the Section matching SectionType in FfsFileHeader.
NULL if section not found
- @param SectionDataSize The size of SectionData
+ @param SectionDataSize The size of SectionData, excluding the section header.
@retval EFI_NOT_FOUND No files matching the search criteria were found
@retval EFI_SUCCESS
diff --git a/StandaloneMmPkg/Include/Library/MmPlatformHobProducerLib.h b/StandaloneMmPkg/Include/Library/MmPlatformHobProducerLib.h
new file mode 100644
index 0000000..2f302bb
--- /dev/null
+++ b/StandaloneMmPkg/Include/Library/MmPlatformHobProducerLib.h
@@ -0,0 +1,54 @@
+/** @file
+ MM Platform HOB Producer Library Class.
+
+ CreateMmPlatformHob() function is called by StandaloneMm IPL to create all
+ Platform specific HOBs that required by Standalone MM environment.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_PLATFORM_HOB_PRODUCER_LIB_H_
+#define MM_PLATFORM_HOB_PRODUCER_LIB_H_
+
+/**
+ Create the platform specific HOBs needed by the Standalone MM environment.
+
+ The following HOBs are created by StandaloneMm IPL common logic
+ hence they should NOT be created by this function:
+ * Single EFI_HOB_TYPE_FV to describe the Firmware Volume where MM Core resides.
+ * Single GUIDed (gEfiSmmSmramMemoryGuid) HOB to describe the MM regions.
+ * Single EFI_HOB_MEMORY_ALLOCATION_MODULE to describe the MM region used by MM Core.
+ * Multiple EFI_HOB_RESOURCE_DESCRIPTOR to describe the non-MM regions and their access permissions.
+ Note: All accessible non-MM regions should be described by EFI_HOB_RESOURCE_DESCRIPTOR HOBs.
+ * Single GUIDed (gMmCommBufferHobGuid) HOB to identify MM Communication buffer in non-MM region.
+ * Multiple GUIDed (gSmmBaseHobGuid) HOB to describe the SMM base address of each processor.
+ * Multiple GUIDed (gMpInformation2HobGuid) HOB to describe the MP information.
+ * Single GUIDed (gMmCpuSyncConfigHobGuid) HOB to describe how BSP synchronizes with APs in x86 SMM.
+ * Single GUIDed (gMmAcpiS3EnableHobGuid) HOB to describe the ACPI S3 enable status.
+ * Single GUIDed (gEfiAcpiVariableGuid) HOB to identify the S3 data root region in x86.
+ * Single GUIDed (gMmProfileDataHobGuid) HOB to describe the MM profile data region.
+
+ @param[in] Buffer The free buffer to be used for HOB creation.
+ @param[in, out] BufferSize The buffer size.
+ On return, the expected/used size.
+
+ @retval RETURN_INVALID_PARAMETER BufferSize is NULL.
+ @retval RETURN_INVALID_PARAMETER Buffer is NULL and BufferSize is not 0.
+ @retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation.
+ BufferSize is updated to indicate the expected buffer size.
+ When the input BufferSize is bigger than the expected buffer size,
+ the BufferSize value will be changed to the used buffer size.
+ @retval RETURN_SUCCESS The HOB list is created successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateMmPlatformHob (
+ IN VOID *Buffer,
+ IN OUT UINTN *BufferSize
+ );
+
+#endif
diff --git a/StandaloneMmPkg/Library/FvLib/FvLib.c b/StandaloneMmPkg/Library/FvLib/FvLib.c
index 89504b9..e0f344a 100644
--- a/StandaloneMmPkg/Library/FvLib/FvLib.c
+++ b/StandaloneMmPkg/Library/FvLib/FvLib.c
@@ -338,11 +338,11 @@ FfsFindSection (
Given the input file pointer, search for the next matching section in the
FFS volume.
- @param SearchType Filter to find only sections of this type.
- @param FfsFileHeader Pointer to the current file to search.
- @param SectionData Pointer to the Section matching SectionType in FfsFileHeader.
- NULL if section not found
- @param SectionDataSize The size of SectionData
+ @param[in] SectionType Filter to find only sections of this type.
+ @param[in] FfsFileHeader Pointer to the current file to search.
+ @param[in,out] SectionData Pointer to the Section matching SectionType in FfsFileHeader.
+ NULL if section not found
+ @param[in,out] SectionDataSize The size of SectionData, excluding the section header.
@retval EFI_NOT_FOUND No files matching the search criteria were found
@retval EFI_SUCCESS
@@ -380,10 +380,10 @@ FfsFindSectionData (
if (Section->Type == SectionType) {
if (IS_SECTION2 (Section)) {
*SectionData = (VOID *)((EFI_COMMON_SECTION_HEADER2 *)Section + 1);
- *SectionDataSize = SECTION2_SIZE (Section);
+ *SectionDataSize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
} else {
*SectionData = (VOID *)(Section + 1);
- *SectionDataSize = SECTION_SIZE (Section);
+ *SectionDataSize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
}
return EFI_SUCCESS;
diff --git a/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.c b/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.c
new file mode 100644
index 0000000..814ea1c
--- /dev/null
+++ b/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.c
@@ -0,0 +1,66 @@
+/** @file
+ Null instance of MM Platform HOB Producer Library Class.
+
+ CreateMmPlatformHob() function is called by StandaloneMm IPL to create all
+ Platform specific HOBs that required by Standalone MM environment.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <PiPei.h>
+#include <Library/MmPlatformHobProducerLib.h>
+
+/**
+ Create the platform specific HOBs needed by the Standalone MM environment.
+
+ The following HOBs are created by StandaloneMm IPL common logic.
+ Hence they should NOT be created by this function:
+ * Single EFI_HOB_TYPE_FV to describe the Firmware Volume where MM Core resides.
+ * Single GUIDed (gEfiSmmSmramMemoryGuid) HOB to describe the MM regions.
+ * Single EFI_HOB_MEMORY_ALLOCATION_MODULE to describe the MM region used by MM Core.
+ * Multiple EFI_HOB_RESOURCE_DESCRIPTOR to describe the non-MM regions and their access permissions.
+ Note: All accessible non-MM regions should be described by EFI_HOB_RESOURCE_DESCRIPTOR HOBs.
+ * Single GUIDed (gMmCommBufferHobGuid) HOB to identify MM Communication buffer in non-MM region.
+ * Multiple GUIDed (gSmmBaseHobGuid) HOB to describe the SMM base address of each processor.
+ * Multiple GUIDed (gMpInformation2HobGuid) HOB to describe the MP information.
+ * Single GUIDed (gMmCpuSyncConfigHobGuid) HOB to describe how BSP synchronizes with APs in x86 SMM.
+ * Single GUIDed (gMmAcpiS3EnableHobGuid) HOB to describe the ACPI S3 enable status.
+ * Single GUIDed (gEfiAcpiVariableGuid) HOB to identify the S3 data root region in x86.
+ * Single GUIDed (gMmProfileDataHobGuid) HOB to describe the MM profile data region.
+
+ @param[in] Buffer The free buffer to be used for HOB creation.
+ @param[in, out] BufferSize The buffer size.
+ On return, the expected/used size.
+
+ @retval RETURN_INVALID_PARAMETER BufferSize is NULL.
+ @retval RETURN_INVALID_PARAMETER Buffer is NULL and BufferSize is not 0.
+ @retval RETURN_BUFFER_TOO_SMALL The buffer is too small for HOB creation.
+ BufferSize is updated to indicate the expected buffer size.
+ When the input BufferSize is bigger than the expected buffer size,
+ the BufferSize value will be changed to the used buffer size.
+ @retval RETURN_SUCCESS The HOB list is created successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CreateMmPlatformHob (
+ IN VOID *Buffer,
+ IN OUT UINTN *BufferSize
+ )
+{
+ if (BufferSize == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if ((*BufferSize != 0) && (Buffer == NULL)) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ *BufferSize = 0;
+
+ return EFI_SUCCESS;
+}
diff --git a/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf b/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf
new file mode 100644
index 0000000..64e1ac1
--- /dev/null
+++ b/StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf
@@ -0,0 +1,28 @@
+## @file
+# Null instance of MM Platform HOB Producer Library Class.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = MmPlatformHobProducerLibNull
+ FILE_GUID = DE6B5E7C-6636-4646-90F8-776408157750
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = MmPlatformHobProducerLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ MmPlatformHobProducerLibNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
diff --git a/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.c b/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.c
new file mode 100644
index 0000000..143a62c
--- /dev/null
+++ b/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.c
@@ -0,0 +1,50 @@
+/** @file
+ LockBox Dependency DXE Library.
+
+ By installing the LockBox protocol with the gEfiLockBoxProtocolGuid,
+ it signals that the LockBox API is fully operational and ready for use.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/LockBox.h>
+
+/**
+ The constructor function of SmmLockBoxMmDependency.
+
+ It attempts to install the gEfiLockBoxProtocolGuid protocol into the system's DXE database
+ with NULL as notify.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the Management mode System Table.
+
+ @retval EFI_SUCCESS The protocol was successfully installed into the DXE database.
+ @retval Others An error occurred while installing the protocol.
+**/
+EFI_STATUS
+EFIAPI
+SmmLockBoxMmDependencyConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install NULL to DXE data base as notify
+ //
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gEfiLockBoxProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf b/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf
new file mode 100644
index 0000000..14931a2
--- /dev/null
+++ b/StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf
@@ -0,0 +1,34 @@
+## @file
+# LockBox Dependency DXE Library.
+#
+# By installing the LockBox protocol with the gEfiLockBoxProtocolGuid,
+# it signals that the LockBox API is fully operational and ready for use.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = SmmLockBoxMmDependency
+ FILE_GUID = c45ce910-7f8b-4f49-88e2-2c26c5743ee2
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL
+ CONSTRUCTOR = SmmLockBoxMmDependencyConstructor
+
+[Sources]
+ SmmLockBoxMmDependency.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[Protocols]
+ gEfiLockBoxProtocolGuid
+
+[LibraryClasses]
+ BaseLib
+ UefiBootServicesTableLib
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c
index 2246823..cd27fc5 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c
@@ -845,9 +845,6 @@ MemoryAllocationLibConstructor (
IN EFI_MM_SYSTEM_TABLE *MmSystemTable
)
{
- MM_CORE_PRIVATE_DATA *MmCorePrivate;
- EFI_HOB_GUID_TYPE *GuidHob;
- MM_CORE_DATA_HOB_DATA *DataInHob;
VOID *HobStart;
EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData;
EFI_MMRAM_DESCRIPTOR *MmramRanges;
@@ -858,35 +855,29 @@ MemoryAllocationLibConstructor (
DEBUG ((DEBUG_INFO, "StandaloneMmCoreMemoryAllocationLibConstructor - 0x%x\n", HobStart));
//
- // Extract MM Core Private context from the Hob. If absent search for
- // a Hob containing the MMRAM ranges
+ // Search for a Hob containing the MMRAM ranges
//
- GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart);
- if (GuidHob == NULL) {
+ MmramRangesHob = GetNextGuidHob (&gEfiSmmSmramMemoryGuid, HobStart);
+ if (MmramRangesHob == NULL) {
MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart);
if (MmramRangesHob == NULL) {
return EFI_UNSUPPORTED;
}
+ }
- MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
- if (MmramRangesHobData == NULL) {
- return EFI_UNSUPPORTED;
- }
+ MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
+ if (MmramRangesHobData == NULL) {
+ return EFI_UNSUPPORTED;
+ }
- MmramRanges = MmramRangesHobData->Descriptor;
- if (MmramRanges == NULL) {
- return EFI_UNSUPPORTED;
- }
+ MmramRanges = MmramRangesHobData->Descriptor;
+ if (MmramRanges == NULL) {
+ return EFI_UNSUPPORTED;
+ }
- MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions;
- if (MmramRanges == NULL) {
- return EFI_UNSUPPORTED;
- }
- } else {
- DataInHob = GET_GUID_HOB_DATA (GuidHob);
- MmCorePrivate = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address;
- MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)MmCorePrivate->MmramRanges;
- MmramRangeCount = (UINTN)MmCorePrivate->MmramRangeCount;
+ MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions;
+ if (MmramRanges == NULL) {
+ return EFI_UNSUPPORTED;
}
{
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf
index bf7530b..2848c4b 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf
@@ -42,3 +42,4 @@
[Guids]
gEfiMmPeiMmramMemoryReserveGuid
+ gEfiSmmSmramMemoryGuid
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationServices.h b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationServices.h
index 833ab0d..1fd0478 100644
--- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationServices.h
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationServices.h
@@ -14,8 +14,6 @@
#ifndef _PI_MM_CORE_MEMORY_ALLOCATION_SERVICES_H_
#define _PI_MM_CORE_MEMORY_ALLOCATION_SERVICES_H_
-#include <Guid/MmCoreData.h>
-
/**
Called to initialize the memory service.
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
index ed3cdf1..a748af5 100644
--- a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
+++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
@@ -51,5 +51,5 @@
MemoryAllocationLib
[Guids]
- gMmCoreDataHobGuid ## SOMETIMES_CONSUMES ## HOB
gEfiMmPeiMmramMemoryReserveGuid ## SOMETIMES_CONSUMES ## HOB
+ gEfiSmmSmramMemoryGuid ## SOMETIMES_CONSUMES ## HOB
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c
index 0b4b117..19e1736 100644
--- a/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c
+++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c
@@ -20,7 +20,6 @@
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
-#include <Guid/MmCoreData.h>
#include <Guid/MmramMemoryReserve.h>
//
@@ -87,9 +86,6 @@ MmMemLibInternalPopulateMmramRanges (
)
{
VOID *HobStart;
- EFI_HOB_GUID_TYPE *GuidHob;
- MM_CORE_DATA_HOB_DATA *DataInHob;
- MM_CORE_PRIVATE_DATA *MmCorePrivateData;
EFI_HOB_GUID_TYPE *MmramRangesHob;
EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData;
EFI_MMRAM_DESCRIPTOR *MmramDescriptors;
@@ -98,38 +94,24 @@ MmMemLibInternalPopulateMmramRanges (
DEBUG ((DEBUG_INFO, "%a - 0x%x\n", __func__, HobStart));
//
- // Extract MM Core Private context from the Hob. If absent search for
- // a Hob containing the MMRAM ranges
+ // Search for a Hob containing the MMRAM ranges
//
- GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart);
- if (GuidHob == NULL) {
+ MmramRangesHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);
+ if (MmramRangesHob == NULL) {
MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid);
if (MmramRangesHob == NULL) {
return EFI_UNSUPPORTED;
}
+ }
- MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
- if ((MmramRangesHobData == NULL) || (MmramRangesHobData->Descriptor == NULL)) {
- return EFI_UNSUPPORTED;
- }
-
- mMmMemLibInternalMmramCount = MmramRangesHobData->NumberOfMmReservedRegions;
- MmramDescriptors = MmramRangesHobData->Descriptor;
- } else {
- DataInHob = GET_GUID_HOB_DATA (GuidHob);
- if (DataInHob == NULL) {
- return EFI_UNSUPPORTED;
- }
-
- MmCorePrivateData = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address;
- if ((MmCorePrivateData == NULL) || (MmCorePrivateData->MmramRanges == 0)) {
- return EFI_UNSUPPORTED;
- }
-
- mMmMemLibInternalMmramCount = (UINTN)MmCorePrivateData->MmramRangeCount;
- MmramDescriptors = (EFI_MMRAM_DESCRIPTOR *)(UINTN)MmCorePrivateData->MmramRanges;
+ MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
+ if ((MmramRangesHobData == NULL) || (MmramRangesHobData->Descriptor == NULL)) {
+ return EFI_UNSUPPORTED;
}
+ mMmMemLibInternalMmramCount = MmramRangesHobData->NumberOfMmReservedRegions;
+ MmramDescriptors = MmramRangesHobData->Descriptor;
+
mMmMemLibInternalMmramRanges = AllocatePool (mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR));
if (mMmMemLibInternalMmramRanges) {
CopyMem (
diff --git a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml b/StandaloneMmPkg/StandaloneMmPkg.ci.yaml
index 4777532..7d9b0c9 100644
--- a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml
+++ b/StandaloneMmPkg/StandaloneMmPkg.ci.yaml
@@ -1,10 +1,14 @@
## @file
# CI configuration for StandaloneMmPkg
#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "StandaloneMmPkg.dsc",
+ },
"EccCheck": {
## Exception sample looks like below:
## "ExceptionList": [
@@ -39,7 +43,8 @@
"EmbeddedPkg/EmbeddedPkg.dec",
"StandaloneMmPkg/StandaloneMmPkg.dec",
"MdeModulePkg/MdeModulePkg.dec",
- "MdePkg/MdePkg.dec"
+ "MdePkg/MdePkg.dec",
+ "UefiCpuPkg/UefiCpuPkg.dec"
],
# For host based unit tests
"AcceptableDependencies-HOST_APPLICATION":[
diff --git a/StandaloneMmPkg/StandaloneMmPkg.dec b/StandaloneMmPkg/StandaloneMmPkg.dec
index fc91bb4..5ac57c1 100644
--- a/StandaloneMmPkg/StandaloneMmPkg.dec
+++ b/StandaloneMmPkg/StandaloneMmPkg.dec
@@ -3,6 +3,7 @@
# required by Standalone MM platform.
#
# Copyright (c) 2016-2021, Arm Ltd. All rights reserved.<BR>
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -29,6 +30,9 @@
## MM Memory Operation.
MemLib|Include/Library/StandaloneMmMemLib.h
+[LibraryClasses.X64.PEIM]
+ MmPlatformHobProducerLib|Include/Library/MmPlatformHobProducerLib.h
+
[LibraryClasses.AArch64, LibraryClasses.ARM]
## @libraryclass Defines a set of interfaces for the MM core entrypoint for
## AArch64 and ARM.
@@ -39,17 +43,30 @@
gMpInformationHobGuid = { 0xba33f15d, 0x4000, 0x45c1, { 0x8e, 0x88, 0xf9, 0x16, 0x92, 0xd4, 0x57, 0xe3 }}
gMmFvDispatchGuid = { 0xb65694cc, 0x09e3, 0x4c3b, { 0xb5, 0xcd, 0x05, 0xf4, 0x4d, 0x3c, 0xdb, 0xff }}
- ## Include/Guid/MmCoreData.h
- gMmCoreDataHobGuid = { 0xa160bf99, 0x2aa4, 0x4d7d, { 0x99, 0x93, 0x89, 0x9c, 0xb1, 0x2d, 0xf3, 0x76 }}
-
## Include/Guid/MmramMemoryReserve.h
gEfiMmPeiMmramMemoryReserveGuid = { 0x0703f912, 0xbf8d, 0x4e2a, { 0xbe, 0x07, 0xab, 0x27, 0x25, 0x25, 0xc5, 0x92 }}
gEfiStandaloneMmNonSecureBufferGuid = { 0xf00497e3, 0xbfa2, 0x41a1, { 0x9d, 0x29, 0x54, 0xc2, 0xe9, 0x37, 0x21, 0xc5 }}
gEfiMmCpuDriverEpDescriptorGuid = { 0x6ecbd5a1, 0xc0f8, 0x4702, { 0x83, 0x01, 0x4f, 0xc2, 0xc5, 0x47, 0x0a, 0x51 }}
+ gEventMmDispatchGuid = { 0x7e6efffa, 0x69b4, 0x4c1b, { 0xa4, 0xc7, 0xaf, 0xf9, 0xc9, 0x24, 0x4f, 0xee }}
+
[PcdsFixedAtBuild, PcdsPatchableInModule]
## Maximum permitted encapsulation levels of sections in a firmware volume,
# in the MM phase. Minimum value is 1. Sections nested more deeply are rejected.
# @Prompt Maximum permitted FwVol section nesting depth (exclusive) in MM.
gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth|0x10|UINT32|0x00000001
+
+[PcdsFeatureFlag]
+ ## Indicates if restart MM Dispatcher once MM Entry Point is registered.<BR><BR>
+ # TRUE - Restart MM Dispatcher once MM Entry Point is registered.<BR>
+ # FALSE - Do not restart MM Dispatcher once MM Entry Point is registered.<BR>
+ # @Prompt Restart MM Dispatcher once MM Entry Point is registered.
+ gStandaloneMmPkgTokenSpaceGuid.PcdRestartMmDispatcherOnceMmEntryRegistered|FALSE|BOOLEAN|0x00000002
+
+[PcdsFeatureFlag.X64]
+ ## Indicates if restart MM Dispatcher once MM Entry Point is registered.<BR><BR>
+ # TRUE - Restart MM Dispatcher once MM Entry Point is registered.<BR>
+ # FALSE - Do not restart MM Dispatcher once MM Entry Point is registered.<BR>
+ # @Prompt Restart MM Dispatcher once MM Entry Point is registered.
+ gStandaloneMmPkgTokenSpaceGuid.PcdRestartMmDispatcherOnceMmEntryRegistered|TRUE|BOOLEAN|0x00000002
diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc
index 8012f93..51dd134 100644
--- a/StandaloneMmPkg/StandaloneMmPkg.dsc
+++ b/StandaloneMmPkg/StandaloneMmPkg.dsc
@@ -1,7 +1,7 @@
## @file
# Standalone MM Platform.
#
-# Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
# Copyright (C) Microsoft Corporation<BR>
#
@@ -59,6 +59,18 @@
StandaloneMmCoreEntryPoint|StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/StandaloneMmCoreEntryPoint.inf
StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf
VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf
+ HobPrintLib|MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf
+ MmPlatformHobProducerLib|StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf
+ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+
+[LibraryClasses.common.PEIM]
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+ MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf
[LibraryClasses.AARCH64, LibraryClasses.ARM]
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
@@ -67,15 +79,22 @@
CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
PeCoffExtraActionLib|StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
[LibraryClasses.common.MM_CORE_STANDALONE]
HobLib|StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
[LibraryClasses.common.MM_STANDALONE]
MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+ UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+
################################################################################
#
# Pcd Section - list of all EDK II PCD Entries defined by this Platform
@@ -117,11 +136,17 @@
StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf
+ StandaloneMmPkg/Library/SmmLockBoxMmDependency/SmmLockBoxMmDependency.inf
+ StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf
+ StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf
[Components.AARCH64, Components.ARM]
StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf
StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf
+[Components.X64]
+ StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
+
###################################################################################################
#
# BuildOptions Section - Define the module specific tool chain flags that should be used as
diff --git a/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c b/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c
index 754549c..0662b6f 100644
--- a/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c
+++ b/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c
@@ -137,7 +137,7 @@ InitializeExceptions (
//
Status = UpdateExceptionStartEntry ();
if (EFI_ERROR (Status)) {
- DebugPrint (EFI_D_ERROR, "[%a]: Exception start entry code out of bounds!\n", __func__);
+ DebugPrint (DEBUG_ERROR, "[%a]: Exception start entry code out of bounds!\n", __func__);
ASSERT_EFI_ERROR (Status);
}
@@ -150,7 +150,7 @@ InitializeExceptions (
//
// Enable interrupts
//
- DebugPrint (EFI_D_INFO, "InitializeExceptions,IrqEnabled = %x\n", IrqEnabled);
+ DebugPrint (DEBUG_INFO, "InitializeExceptions,IrqEnabled = %x\n", IrqEnabled);
if (!IrqEnabled) {
Status = Cpu->EnableInterrupt (Cpu);
}
diff --git a/UefiCpuPkg/Include/Guid/MmAcpiS3Enable.h b/UefiCpuPkg/Include/Guid/MmAcpiS3Enable.h
new file mode 100644
index 0000000..8c16559
--- /dev/null
+++ b/UefiCpuPkg/Include/Guid/MmAcpiS3Enable.h
@@ -0,0 +1,34 @@
+/** @file
+ This file defines ACPI_S3_ENABLE structure which indicates to x86 standalone MM whether S3 is enabled.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_ACPI_S3_ENABLE_H_
+#define MM_ACPI_S3_ENABLE_H_
+
+///
+/// The GUID of the MmAcpiS3Enable GUIDed HOB.
+///
+#define MM_ACPI_S3_ENABLE_HOB_GUID \
+ { \
+ 0xe7402821, 0x2654, 0x4c1b, {0x99, 0x0e, 0x04, 0x8f, 0x8d, 0x82, 0xcf, 0x67} \
+ }
+
+///
+/// The structure defines the data layout of the MmAcpiS3Enable GUIDed HOB.
+///
+typedef struct {
+ ///
+ /// Whether ACPI S3 is enabled.
+ /// The value shall match with the PcdAcpiS3Enable.
+ ///
+ BOOLEAN AcpiS3Enable;
+} MM_ACPI_S3_ENABLE;
+
+extern EFI_GUID gMmAcpiS3EnableHobGuid;
+
+#endif
diff --git a/UefiCpuPkg/Include/Guid/MmCpuSyncConfig.h b/UefiCpuPkg/Include/Guid/MmCpuSyncConfig.h
new file mode 100644
index 0000000..16d96a8
--- /dev/null
+++ b/UefiCpuPkg/Include/Guid/MmCpuSyncConfig.h
@@ -0,0 +1,53 @@
+/** @file
+ This file defines MM_CPU_SYNC_CONFIG which controls how BSP synchronizes with APs
+ in x86 SMM environment.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_CPU_SYNC_CONFIG_H_
+#define MM_CPU_SYNC_CONFIG_H_
+
+///
+/// The GUID of the MmCpuSyncConfig GUIDed HOB.
+///
+#define MM_CPU_SYNC_CONFIG_HOB_GUID \
+ { \
+ 0x8b90bd26, 0xe4f9, 0x45c2, {0x92, 0xa2, 0x9e, 0xac, 0xe6, 0x0e, 0x9d, 0xcc} \
+ }
+
+typedef enum {
+ MmCpuSyncModeTradition,
+ MmCpuSyncModeRelaxedAp,
+ MmCpuSyncModeMax
+} MM_CPU_SYNC_MODE;
+
+///
+/// The structure defines the data layout of the MmCpuSyncConfig GUIDed HOB.
+///
+typedef struct {
+ ///
+ /// 0: Traditional CPU synchronization method is used when processing an SMI.
+ /// 1: Relaxed CPU synchronization method is used when processing an SMI.
+ ///
+ MM_CPU_SYNC_MODE RelaxedApMode;
+
+ ///
+ /// The 1st BSP/AP synchronization timeout value in SMM.
+ /// The value shall match with the PcdCpuSmmApSyncTimeout.
+ ///
+ UINT64 Timeout;
+
+ ///
+ /// The 2nd BSP/AP synchronization timeout value in SMM.
+ /// The value shall match with the PcdCpuSmmApSyncTimeout2.
+ ///
+ UINT64 Timeout2;
+} MM_CPU_SYNC_CONFIG;
+
+extern EFI_GUID gMmCpuSyncConfigHobGuid;
+
+#endif
diff --git a/UefiCpuPkg/Include/Guid/MmProfileData.h b/UefiCpuPkg/Include/Guid/MmProfileData.h
new file mode 100644
index 0000000..64c9f78
--- /dev/null
+++ b/UefiCpuPkg/Include/Guid/MmProfileData.h
@@ -0,0 +1,35 @@
+/** @file
+ This file contains related definitions to support MM Profile feature in standalone MM.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_PROFILE_DATA_H_
+#define MM_PROFILE_DATA_H_
+
+///
+/// This GUID is assigned to the Name field of EFI_HOB_MEMORY_ALLOCATION.AllocDescriptor.
+/// It signifies that the corresponding EFI_HOB_MEMORY_ALLOCATION HOB points to the location of MM Profile data.
+/// MM Profile is a feature designed to log accesses to non-MM regions by standalone MM.
+/// It stores these access logs within the MM Profile data.
+///
+#define MM_PROFILE_DATA_HOB_GUID \
+ { \
+ 0x26ef081d, 0x19b0, 0x4c42, {0xa2, 0x57, 0xa7, 0xf5, 0x9f, 0x8b, 0xd0, 0x38} \
+ }
+
+///
+/// In standalone MM, the policy for accessing non-MM regions is simplified:
+/// Non-MM regions and their access policies are specified by EFI_HOB_RESOURCE_DESCRIPTOR HOBs.
+/// Accesses to regions marked with the MM_RESOURCE_ATTRIBUTE_LOGGING attribute
+/// are permitted in standalone MM, and these accesses are logged in the MM Profile data.
+/// This attribute is not utilized by the SMM Profile feature in traditional SMM.
+///
+#define MM_RESOURCE_ATTRIBUTE_LOGGING 0x10000000
+
+extern EFI_GUID gMmProfileDataHobGuid;
+
+#endif
diff --git a/UefiCpuPkg/Include/Guid/MmUnblockRegion.h b/UefiCpuPkg/Include/Guid/MmUnblockRegion.h
new file mode 100644
index 0000000..f6a33c3
--- /dev/null
+++ b/UefiCpuPkg/Include/Guid/MmUnblockRegion.h
@@ -0,0 +1,42 @@
+/** @file
+ Defines the GUIDed HOB that describes the memory region to be unblocked in MM environment.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef MM_UNBLOCK_REGION_H_
+#define MM_UNBLOCK_REGION_H_
+
+///
+/// The GUID of the UnblockRegion GUIDed HOB.
+///
+#define MM_UNBLOCK_REGION_HOB_GUID \
+ { \
+ 0x7c316fb3, 0x849e, 0x4ee7, {0x87, 0xfc, 0x16, 0x2d, 0x0b, 0x03, 0x42, 0xbf } \
+ }
+
+///
+/// The structure defines the data layout of the UnblockRegion GUIDed HOB.
+///
+typedef struct {
+ ///
+ /// Physical address of the first byte in the memory region. PhysicalStart must be
+ /// aligned on a 4 KiB boundary.
+ ///
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+
+ ///
+ /// Number of 4 KiB pages in the memory region.
+ ///
+ UINT64 NumberOfPages;
+
+ ///
+ /// GUID to identify the memory region.
+ ///
+ EFI_GUID IdentifierGuid;
+} MM_UNBLOCK_REGION;
+
+extern EFI_GUID gMmUnblockRegionHobGuid;
+
+#endif
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ArchExceptionHandler.c
index c0219de..519fe1e 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/LoongArch64/ArchExceptionHandler.c
@@ -260,7 +260,7 @@ IpiInterruptHandler (
//
// Set $a0 as APIC ID and $a1 as parameter value.
//
- SystemContext.SystemContextLoongArch64->R4 = CsrRead (LOONGARCH_CSR_CPUNUM);
+ SystemContext.SystemContextLoongArch64->R4 = CsrRead (LOONGARCH_CSR_CPUID);
SystemContext.SystemContextLoongArch64->R5 = Parameter;
}
diff --git a/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c b/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c
index a610011..056aabc 100644
--- a/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c
+++ b/UefiCpuPkg/Library/CpuPageTableLib/UnitTest/CpuPageTableLibUnitTestHost.c
@@ -838,7 +838,8 @@ UefiTestMain (
EFI_STATUS Status;
UNIT_TEST_FRAMEWORK_HANDLE Framework;
UNIT_TEST_SUITE_HANDLE ManualTestCase;
- UNIT_TEST_SUITE_HANDLE RandomTestCase;
+
+ // UNIT_TEST_SUITE_HANDLE RandomTestCase;
Framework = NULL;
@@ -874,12 +875,12 @@ UefiTestMain (
//
// Populate the Random Test Cases.
//
- Status = CreateUnitTestSuite (&RandomTestCase, Framework, "Random Test Cases", "CpuPageTableLib.Random", NULL, NULL);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for Random Test Cases\n"));
- Status = EFI_OUT_OF_RESOURCES;
- goto EXIT;
- }
+ // Status = CreateUnitTestSuite (&RandomTestCase, Framework, "Random Test Cases", "CpuPageTableLib.Random", NULL, NULL);
+ // if (EFI_ERROR (Status)) {
+ // DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for Random Test Cases\n"));
+ // Status = EFI_OUT_OF_RESOURCES;
+ // goto EXIT;
+ // }
// AddTestCase (RandomTestCase, "Random Test for Paging4Level", "Random Test Case1", TestCaseforRandomTest, NULL, NULL, &mTestContextPaging4Level);
// AddTestCase (RandomTestCase, "Random Test for Paging4Level1G", "Random Test Case2", TestCaseforRandomTest, NULL, NULL, &mTestContextPaging4Level1GB);
diff --git a/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c b/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c
new file mode 100644
index 0000000..790392b
--- /dev/null
+++ b/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c
@@ -0,0 +1,81 @@
+/** @file
+ The instance of MM Unblock Page Library.
+ This library provides an interface to request non-MMRAM pages to be mapped/unblocked
+ from inside MM environment.
+ For MM modules that need to access regions outside of MMRAMs, the agents that set up
+ these regions are responsible for invoking this API in order for these memory areas
+ to be accessed from inside MM.
+
+ Copyright (c) Microsoft Corporation.
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi.h>
+#include <Guid/MmUnblockRegion.h>
+#include <Ppi/MmCommunication.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Base.h>
+
+/**
+ This API provides a way to unblock certain data pages to be accessible inside MM environment.
+
+ @param UnblockAddress The address of buffer caller requests to unblock, the address
+ has to be page aligned.
+ @param NumberOfPages The number of pages requested to be unblocked from MM
+ environment.
+ @retval RETURN_SUCCESS The request goes through successfully.
+ @retval RETURN_NOT_AVAILABLE_YET The requested functionality is not produced yet.
+ @retval RETURN_UNSUPPORTED The requested functionality is not supported on current platform.
+ @retval RETURN_SECURITY_VIOLATION The requested address failed to pass security check for
+ unblocking.
+ @retval RETURN_INVALID_PARAMETER Input address either NULL pointer or not page aligned.
+ @retval RETURN_ACCESS_DENIED The request is rejected due to system has passed certain boot
+ phase.
+**/
+EFI_STATUS
+EFIAPI
+MmUnblockMemoryRequest (
+ IN EFI_PHYSICAL_ADDRESS UnblockAddress,
+ IN UINT64 NumberOfPages
+ )
+{
+ EFI_STATUS Status;
+ MM_UNBLOCK_REGION *MmUnblockMemoryHob;
+ EFI_PEI_MM_COMMUNICATION_PPI *MmCommunicationPpi;
+
+ if (!IS_ALIGNED (UnblockAddress, SIZE_4KB)) {
+ DEBUG ((DEBUG_ERROR, "Error: UnblockAddress is not 4KB aligned: %p\n", UnblockAddress));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Unblock requests are rejected when MmIpl finishes execution.
+ //
+ Status = PeiServicesLocatePpi (&gEfiPeiMmCommunicationPpiGuid, 0, NULL, (VOID **)&MmCommunicationPpi);
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Unblock requests are rejected since the MmIpl finishes execution\n"));
+ return RETURN_ACCESS_DENIED;
+ }
+
+ //
+ // Build the GUID'd HOB for MmCore
+ //
+ MmUnblockMemoryHob = BuildGuidHob (&gMmUnblockRegionHobGuid, sizeof (MM_UNBLOCK_REGION));
+ if (MmUnblockMemoryHob == NULL) {
+ DEBUG ((DEBUG_ERROR, "MmUnblockMemoryRequest: Failed to allocate hob for unblocked data parameter!!\n"));
+ return Status;
+ }
+
+ ZeroMem (MmUnblockMemoryHob, sizeof (MM_UNBLOCK_REGION));
+
+ //
+ // Caller ID is filled in.
+ //
+ CopyGuid (&MmUnblockMemoryHob->IdentifierGuid, &gEfiCallerIdGuid);
+ MmUnblockMemoryHob->PhysicalStart = UnblockAddress;
+ MmUnblockMemoryHob->NumberOfPages = NumberOfPages;
+ return EFI_SUCCESS;
+}
diff --git a/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf b/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf
new file mode 100644
index 0000000..c3c748d
--- /dev/null
+++ b/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf
@@ -0,0 +1,47 @@
+## @file
+# Instance of MM Unblock Page Library.
+#
+# This library provides an interface to request non-MMRAM pages to be mapped/unblocked
+# from inside MM environment.
+#
+# For MM modules that need to access regions outside of MMRAMs, the agents that set up
+# these regions are responsible for invoking this API in order for these memory areas
+# to be accessed from inside MM.
+#
+# Copyright (c) Microsoft Corporation.
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = MmUnblockMemoryLib
+ FILE_GUID = CBFE5800-70FD-4D9A-AA78-DB617294077E
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = MmUnblockMemoryLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ MmUnblockMemoryLib.c
+
+[Packages]
+ UefiCpuPkg/UefiCpuPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ HobLib
+ DebugLib
+ BaseMemoryLib
+ PeiServicesLib
+
+[Ppis]
+ gEfiPeiMmCommunicationPpiGuid
+
+[Guids]
+ gMmUnblockRegionHobGuid
diff --git a/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c b/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c
index c18671e..ff2c033 100644
--- a/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c
@@ -60,7 +60,7 @@ GetApicId (
{
UINTN CpuNum;
- CpuNum = CsrRead (LOONGARCH_CSR_CPUNUM);
+ CpuNum = CsrRead (LOONGARCH_CSR_CPUID);
return CpuNum & 0x3ff;
}
@@ -130,8 +130,8 @@ SortApicId (
} else {
for ( ; Index2 <= ApCount; Index2++) {
if (CpuInfoInHob[Index2].ApicId == INVALID_APIC_ID) {
- CopyMem (&CpuInfoInHob[Index2], &CpuInfoInHob[Index1], sizeof (CPU_INFO_IN_HOB));
- CpuMpData->CpuData[Index2] = CpuMpData->CpuData[Index1];
+ CopyMem (CpuInfoInHob + Index2, CpuInfoInHob + Index1, sizeof (CPU_INFO_IN_HOB));
+ CopyMem (CpuMpData->CpuData + Index2, CpuMpData->CpuData + Index1, sizeof (CPU_AP_DATA));
CpuInfoInHob[Index1].ApicId = INVALID_APIC_ID;
break;
}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 8fbcebd..67e8556 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -41,8 +41,7 @@ SaveVolatileRegisters (
**/
VOID
RestoreVolatileRegisters (
- IN CPU_VOLATILE_REGISTERS *VolatileRegisters,
- IN BOOLEAN IsRestoreDr
+ IN CPU_VOLATILE_REGISTERS *VolatileRegisters
);
/**
@@ -118,11 +117,7 @@ FutureBSPProc (
//
SaveVolatileRegisters (&DataInHob->APInfo.VolatileRegisters);
AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo);
- RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters, FALSE);
- //
- // Update VolatileRegisters saved in CpuMpData->CpuData
- //
- CopyMem (&DataInHob->CpuData[DataInHob->BspNumber].VolatileRegisters, &DataInHob->APInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));
+ RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters);
}
/**
@@ -167,16 +162,19 @@ SaveLocalApicTimerSetting (
IN CPU_MP_DATA *CpuMpData
)
{
- //
- // Record the current local APIC timer setting of BSP
- //
- GetApicTimerState (
- &CpuMpData->DivideValue,
- &CpuMpData->PeriodicMode,
- &CpuMpData->Vector
- );
- CpuMpData->CurrentTimerCount = GetApicTimerCurrentCount ();
- CpuMpData->TimerInterruptState = GetApicTimerInterruptState ();
+ CpuMpData->InitTimerCount = GetApicTimerInitCount ();
+ if (CpuMpData->InitTimerCount != 0) {
+ //
+ // Record the current local APIC timer setting of BSP
+ //
+ GetApicTimerState (
+ &CpuMpData->DivideValue,
+ &CpuMpData->PeriodicMode,
+ &CpuMpData->Vector
+ );
+
+ CpuMpData->TimerInterruptState = GetApicTimerInterruptState ();
+ }
}
/**
@@ -189,19 +187,21 @@ SyncLocalApicTimerSetting (
IN CPU_MP_DATA *CpuMpData
)
{
- //
- // Sync local APIC timer setting from BSP to AP
- //
- InitializeApicTimer (
- CpuMpData->DivideValue,
- CpuMpData->CurrentTimerCount,
- CpuMpData->PeriodicMode,
- CpuMpData->Vector
- );
- //
- // Disable AP's local APIC timer interrupt
- //
- DisableApicTimerInterrupt ();
+ if (CpuMpData->InitTimerCount != 0) {
+ //
+ // Sync local APIC timer setting from BSP to AP
+ //
+ InitializeApicTimer (
+ CpuMpData->DivideValue,
+ CpuMpData->InitTimerCount,
+ CpuMpData->PeriodicMode,
+ CpuMpData->Vector
+ );
+ //
+ // Disable AP's local APIC timer interrupt
+ //
+ DisableApicTimerInterrupt ();
+ }
}
/**
@@ -243,13 +243,11 @@ SaveVolatileRegisters (
Restore the volatile registers following INIT IPI.
@param[in] VolatileRegisters Pointer to volatile resisters
- @param[in] IsRestoreDr TRUE: Restore DRx if supported
- FALSE: Do not restore DRx
+
**/
VOID
RestoreVolatileRegisters (
- IN CPU_VOLATILE_REGISTERS *VolatileRegisters,
- IN BOOLEAN IsRestoreDr
+ IN CPU_VOLATILE_REGISTERS *VolatileRegisters
)
{
CPUID_VERSION_INFO_EDX VersionInfoEdx;
@@ -259,20 +257,18 @@ RestoreVolatileRegisters (
AsmWriteCr4 (VolatileRegisters->Cr4);
AsmWriteCr0 (VolatileRegisters->Cr0);
- if (IsRestoreDr) {
- AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
- if (VersionInfoEdx.Bits.DE != 0) {
- //
- // If processor supports Debugging Extensions feature
- // by CPUID.[EAX=01H]:EDX.BIT2
- //
- AsmWriteDr0 (VolatileRegisters->Dr0);
- AsmWriteDr1 (VolatileRegisters->Dr1);
- AsmWriteDr2 (VolatileRegisters->Dr2);
- AsmWriteDr3 (VolatileRegisters->Dr3);
- AsmWriteDr6 (VolatileRegisters->Dr6);
- AsmWriteDr7 (VolatileRegisters->Dr7);
- }
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
+ if (VersionInfoEdx.Bits.DE != 0) {
+ //
+ // If processor supports Debugging Extensions feature
+ // by CPUID.[EAX=01H]:EDX.BIT2
+ //
+ AsmWriteDr0 (VolatileRegisters->Dr0);
+ AsmWriteDr1 (VolatileRegisters->Dr1);
+ AsmWriteDr2 (VolatileRegisters->Dr2);
+ AsmWriteDr3 (VolatileRegisters->Dr3);
+ AsmWriteDr6 (VolatileRegisters->Dr6);
+ AsmWriteDr7 (VolatileRegisters->Dr7);
}
AsmWriteGdtr (&VolatileRegisters->Gdtr);
@@ -377,10 +373,9 @@ SortApicId (
UINTN Index3;
UINT32 ApicId;
CPU_INFO_IN_HOB CpuInfo;
+ CPU_AP_DATA CpuApData;
UINT32 ApCount;
CPU_INFO_IN_HOB *CpuInfoInHob;
- volatile UINT32 *StartupApSignal;
- VOID *SevEsSaveArea;
ApCount = CpuMpData->CpuCount - 1;
CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
@@ -407,18 +402,13 @@ SortApicId (
);
CopyMem (&CpuInfoInHob[Index1], &CpuInfo, sizeof (CPU_INFO_IN_HOB));
- //
- // Also exchange the StartupApSignal and SevEsSaveArea.
- //
- StartupApSignal = CpuMpData->CpuData[Index3].StartupApSignal;
- CpuMpData->CpuData[Index3].StartupApSignal =
- CpuMpData->CpuData[Index1].StartupApSignal;
- CpuMpData->CpuData[Index1].StartupApSignal = StartupApSignal;
-
- SevEsSaveArea = CpuMpData->CpuData[Index3].SevEsSaveArea;
- CpuMpData->CpuData[Index3].SevEsSaveArea =
- CpuMpData->CpuData[Index1].SevEsSaveArea;
- CpuMpData->CpuData[Index1].SevEsSaveArea = SevEsSaveArea;
+ CopyMem (&CpuApData, &CpuMpData->CpuData[Index3], sizeof (CPU_AP_DATA));
+ CopyMem (
+ &CpuMpData->CpuData[Index3],
+ &CpuMpData->CpuData[Index1],
+ sizeof (CPU_AP_DATA)
+ );
+ CopyMem (&CpuMpData->CpuData[Index1], &CpuApData, sizeof (CPU_AP_DATA));
}
}
@@ -512,33 +502,20 @@ GetProcessorNumber (
}
/**
- This function will get CPU count in the system.
+ Enable x2APIC mode if
+ 1. Number of CPU is greater than 255; or
+ 2. There are any logical processors reporting an Initial APIC ID of 255 or greater.
@param[in] CpuMpData Pointer to PEI CPU MP Data
-
- @return CPU count detected
**/
-UINTN
-CollectProcessorCount (
+VOID
+AutoEnableX2Apic (
IN CPU_MP_DATA *CpuMpData
)
{
+ BOOLEAN X2Apic;
UINTN Index;
CPU_INFO_IN_HOB *CpuInfoInHob;
- BOOLEAN X2Apic;
-
- //
- // Send 1st broadcast IPI to APs to wakeup APs
- //
- CpuMpData->InitFlag = ApInitConfig;
- WakeUpAP (CpuMpData, TRUE, 0, NULL, NULL, TRUE);
- CpuMpData->InitFlag = ApInitDone;
- //
- // When InitFlag == ApInitConfig, WakeUpAP () guarantees all APs are checked in.
- // FinishedCount is the number of check-in APs.
- //
- CpuMpData->CpuCount = CpuMpData->FinishedCount + 1;
- ASSERT (CpuMpData->CpuCount <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
//
// Enable x2APIC mode if
@@ -587,12 +564,32 @@ CollectProcessorCount (
}
DEBUG ((DEBUG_INFO, "APIC MODE is %d\n", GetApicMode ()));
+}
+
+/**
+ This function will get CPU count in the system.
+
+ @param[in] CpuMpData Pointer to PEI CPU MP Data
+
+ @return CPU count detected
+**/
+UINTN
+CollectProcessorCount (
+ IN CPU_MP_DATA *CpuMpData
+ )
+{
//
- // Sort BSP/Aps by CPU APIC ID in ascending order
+ // Send 1st broadcast IPI to APs to wakeup APs
//
- SortApicId (CpuMpData);
-
- DEBUG ((DEBUG_INFO, "MpInitLib: Find %d processors in system.\n", CpuMpData->CpuCount));
+ CpuMpData->InitFlag = ApInitConfig;
+ WakeUpAP (CpuMpData, TRUE, 0, NULL, NULL, TRUE);
+ CpuMpData->InitFlag = ApInitDone;
+ //
+ // When InitFlag == ApInitConfig, WakeUpAP () guarantees all APs are checked in.
+ // FinishedCount is the number of check-in APs.
+ //
+ CpuMpData->CpuCount = CpuMpData->FinishedCount + 1;
+ ASSERT (CpuMpData->CpuCount <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
return CpuMpData->CpuCount;
}
@@ -761,6 +758,12 @@ ApWakeupFunction (
CurrentApicMode = GetApicMode ();
while (TRUE) {
if (CpuMpData->InitFlag == ApInitConfig) {
+ //
+ // Synchronize APIC mode with BSP in the first time AP wakeup ONLY.
+ //
+ SetApicMode (CpuMpData->InitialBspApicMode);
+ CurrentApicMode = CpuMpData->InitialBspApicMode;
+
ProcessorNumber = ApIndex;
//
// This is first time AP wakeup, get BIST information from AP stack
@@ -770,11 +773,11 @@ ApWakeupFunction (
BistData = (UINT32)ApStackData->Bist;
//
- // CpuMpData->CpuData[BspNumber].VolatileRegisters is initialized based on BSP environment,
+ // CpuMpData->CpuData[ProcessorNumber].VolatileRegisters is initialized based on BSP environment,
// to initialize AP in InitConfig path.
- // NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a different IDT shared by all APs.
+ // NOTE: IDTR.BASE stored in CpuMpData->CpuData[ProcessorNumber].VolatileRegisters points to a different IDT shared by all APs.
//
- RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
+ RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack);
ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal;
} else {
@@ -801,31 +804,7 @@ ApWakeupFunction (
0
);
- if (CpuMpData->InitFlag == ApInitReconfig) {
- //
- // ApInitReconfig happens when:
- // 1. AP is re-enabled after it's disabled, in either PEI or DXE phase.
- // 2. AP is initialized in DXE phase.
- // In either case, use the volatile registers value derived from BSP.
- // NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a
- // different IDT shared by all APs.
- //
- RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
- } else {
- if (CpuMpData->ApLoopMode == ApInHltLoop) {
- //
- // Restore AP's volatile registers saved before AP is halted
- //
- RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);
- } else {
- //
- // The CPU driver might not flush TLB for APs on spot after updating
- // page attributes. AP in mwait loop mode needs to take care of it when
- // woken up.
- //
- CpuFlushTlb ();
- }
- }
+ RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateReady) {
Procedure = (EFI_AP_PROCEDURE)CpuMpData->CpuData[ProcessorNumber].ApFunction;
@@ -876,12 +855,7 @@ ApWakeupFunction (
}
}
- if (CpuMpData->ApLoopMode == ApInHltLoop) {
- //
- // Save AP volatile registers
- //
- SaveVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
- }
+ SaveVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
//
// AP finished executing C code
@@ -936,7 +910,7 @@ DxeApEntryPoint (
AsmWriteMsr64 (MSR_IA32_EFER, EferMsr.Uint64);
}
- RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
+ RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
InterlockedIncrement ((UINT32 *)&CpuMpData->FinishedCount);
PlaceAPInMwaitLoopOrRunLoop (
CpuMpData->ApLoopMode,
@@ -1258,13 +1232,12 @@ WakeUpAP (
ResetVectorRequired = FALSE;
if (CpuMpData->WakeUpByInitSipiSipi ||
- (CpuMpData->InitFlag != ApInitDone))
+ (CpuMpData->InitFlag == ApInitConfig))
{
ResetVectorRequired = TRUE;
AllocateResetVectorBelow1Mb (CpuMpData);
AllocateSevEsAPMemory (CpuMpData);
FillExchangeInfoData (CpuMpData);
- SaveLocalApicTimerSetting (CpuMpData);
}
if (CpuMpData->ApLoopMode == ApInMwaitLoop) {
@@ -1293,7 +1266,7 @@ WakeUpAP (
CpuData->ApFunction = (UINTN)Procedure;
CpuData->ApFunctionArgument = (UINTN)ProcedureArgument;
SetApState (CpuData, CpuStateReady);
- if (CpuMpData->InitFlag != ApInitConfig) {
+ if (CpuMpData->InitFlag == ApInitDone) {
*(UINT32 *)CpuData->StartupApSignal = WAKEUP_AP_SIGNAL;
}
}
@@ -1411,7 +1384,7 @@ WakeUpAP (
//
// Wakeup specified AP
//
- ASSERT (CpuMpData->InitFlag != ApInitConfig);
+ ASSERT (CpuMpData->InitFlag == ApInitDone);
*(UINT32 *)CpuData->StartupApSignal = WAKEUP_AP_SIGNAL;
if (ResetVectorRequired) {
CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
@@ -1683,14 +1656,12 @@ ResetProcessorToIdleState (
CpuMpData = GetCpuMpData ();
- CpuMpData->InitFlag = ApInitReconfig;
+ CpuMpData->WakeUpByInitSipiSipi = TRUE;
WakeUpAP (CpuMpData, FALSE, ProcessorNumber, NULL, NULL, TRUE);
while (CpuMpData->FinishedCount < 1) {
CpuPause ();
}
- CpuMpData->InitFlag = ApInitDone;
-
SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);
}
@@ -2200,7 +2171,25 @@ MpInitLibInitialize (
// Don't pass BSP's TR to APs to avoid AP init failure.
//
VolatileRegisters.Tr = 0;
- CopyMem (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters));
+ //
+ // Set DR as 0 since DR is set only for BSP.
+ //
+ VolatileRegisters.Dr0 = 0;
+ VolatileRegisters.Dr1 = 0;
+ VolatileRegisters.Dr2 = 0;
+ VolatileRegisters.Dr3 = 0;
+ VolatileRegisters.Dr6 = 0;
+ VolatileRegisters.Dr7 = 0;
+
+ //
+ // Copy volatile registers since either APs are the first time to bring up,
+ // or BSP is in DXE phase but APs are still running in PEI context.
+ // In both cases, APs need use volatile registers from BSP
+ //
+ for (Index = 0; Index < MaxLogicalProcessorNumber; Index++) {
+ CopyMem (&CpuMpData->CpuData[Index].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters));
+ }
+
//
// Set BSP basic information
//
@@ -2239,9 +2228,15 @@ MpInitLibInitialize (
DEBUG ((DEBUG_INFO, "AP Vector: non-16-bit = %p/%x\n", CpuMpData->WakeupBufferHigh, ApResetVectorSizeAbove1Mb));
//
+ // Save APIC mode for AP to sync
+ //
+ CpuMpData->InitialBspApicMode = GetApicMode ();
+
+ //
// Enable the local APIC for Virtual Wire Mode.
//
ProgramVirtualWireMode ();
+ SaveLocalApicTimerSetting (CpuMpData);
if (FirstMpHandOff == NULL) {
if (MaxLogicalProcessorNumber > 1) {
@@ -2249,12 +2244,27 @@ MpInitLibInitialize (
// Wakeup all APs and calculate the processor count in system
//
CollectProcessorCount (CpuMpData);
+
+ //
+ // Enable X2APIC if needed.
+ //
+ if (CpuMpData->InitialBspApicMode == LOCAL_APIC_MODE_XAPIC) {
+ AutoEnableX2Apic (CpuMpData);
+ }
+
+ //
+ // Sort BSP/Aps by CPU APIC ID in ascending order
+ //
+ SortApicId (CpuMpData);
+
+ DEBUG ((DEBUG_INFO, "MpInitLib: Find %d processors in system.\n", CpuMpData->CpuCount));
}
} else {
//
// APs have been wakeup before, just get the CPU Information
// from HOB
//
+ CpuMpData->InitFlag = ApInitDone;
if (CpuMpData->UseSevEsAPMethod) {
AmdSevUpdateCpuMpData (CpuMpData);
}
@@ -2298,7 +2308,6 @@ MpInitLibInitialize (
ASSERT (CpuMpData->ApLoopMode != ApInHltLoop);
CpuMpData->FinishedCount = 0;
- CpuMpData->InitFlag = ApInitDone;
CpuMpData->EnableExecuteDisableForSwitchContext = IsBspExecuteDisableEnabled ();
SaveCpuMpData (CpuMpData);
//
@@ -2331,6 +2340,12 @@ MpInitLibInitialize (
//
InitMpGlobalData (CpuMpData);
return EFI_SUCCESS;
+ } else {
+ //
+ // PEI and DXE are in different Execution Mode
+ // Use Init Sipi Sipi for the first AP wake up in DXE phase.
+ //
+ CpuMpData->WakeUpByInitSipiSipi = TRUE;
}
}
@@ -2359,15 +2374,6 @@ MpInitLibInitialize (
// Wakeup APs to do some AP initialize sync (Microcode & MTRR)
//
if (CpuMpData->CpuCount > 1) {
- if (FirstMpHandOff != NULL) {
- //
- // Only needs to use this flag for DXE phase to update the wake up
- // buffer. Wakeup buffer allocated in PEI phase is no longer valid
- // in DXE.
- //
- CpuMpData->InitFlag = ApInitReconfig;
- }
-
WakeUpAP (CpuMpData, TRUE, 0, ApInitializeSync, CpuMpData, TRUE);
//
// Wait for all APs finished initialization
@@ -2376,10 +2382,6 @@ MpInitLibInitialize (
CpuPause ();
}
- if (FirstMpHandOff != NULL) {
- CpuMpData->InitFlag = ApInitDone;
- }
-
for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
SetApState (&CpuMpData->CpuData[Index], CpuStateIdle);
}
@@ -2618,6 +2620,11 @@ SwitchBSPWorker (
AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
//
+ // Save BSP's local APIC timer setting.
+ //
+ SaveLocalApicTimerSetting (CpuMpData);
+
+ //
// Need to wakeUp AP (future BSP).
//
WakeUpAP (CpuMpData, FALSE, ProcessorNumber, FutureBSPProc, CpuMpData, TRUE);
@@ -2627,13 +2634,7 @@ SwitchBSPWorker (
//
SaveVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters);
AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo);
- RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters, FALSE);
- //
- // Update VolatileRegisters saved in CpuMpData->CpuData
- // Don't pass BSP's TR to APs to avoid AP init failure.
- //
- CopyMem (&CpuMpData->CpuData[CpuMpData->NewBspNumber].VolatileRegisters, &CpuMpData->BSPInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));
- CpuMpData->CpuData[CpuMpData->NewBspNumber].VolatileRegisters.Tr = 0;
+ RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters);
//
// Set the BSP bit of MSR_IA32_APIC_BASE on new BSP
//
@@ -3196,19 +3197,25 @@ AmdMemEncryptionAttrCheck (
IN CONFIDENTIAL_COMPUTING_GUEST_ATTR Attr
)
{
+ UINT64 CurrentLevel;
+
+ CurrentLevel = CurrentAttr & CCAttrTypeMask;
+
switch (Attr) {
case CCAttrAmdSev:
//
// SEV is automatically enabled if SEV-ES or SEV-SNP is active.
//
- return CurrentAttr >= CCAttrAmdSev;
+ return CurrentLevel >= CCAttrAmdSev;
case CCAttrAmdSevEs:
//
// SEV-ES is automatically enabled if SEV-SNP is active.
//
- return CurrentAttr >= CCAttrAmdSevEs;
+ return CurrentLevel >= CCAttrAmdSevEs;
case CCAttrAmdSevSnp:
- return CurrentAttr == CCAttrAmdSevSnp;
+ return CurrentLevel == CCAttrAmdSevSnp;
+ case CCAttrFeatureAmdSevEsDebugVirtualization:
+ return !!(CurrentAttr & CCAttrFeatureAmdSevEsDebugVirtualization);
default:
return FALSE;
}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 88b31fe..690b7b0 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -120,9 +120,8 @@ typedef enum {
// AP initialization state during APs wakeup
//
typedef enum {
- ApInitConfig = 1,
- ApInitReconfig = 2,
- ApInitDone = 3
+ ApInitConfig = 1,
+ ApInitDone = 2
} AP_INIT_STATE;
//
@@ -251,11 +250,23 @@ typedef struct {
// in assembly code.
//
struct _CPU_MP_DATA {
- UINT64 CpuInfoInHob;
- UINT32 CpuCount;
- UINT32 BspNumber;
- SPIN_LOCK MpLock;
- UINTN Buffer;
+ UINT64 CpuInfoInHob;
+ UINT32 CpuCount;
+ UINT32 BspNumber;
+ SPIN_LOCK MpLock;
+ UINTN Buffer;
+
+ //
+ // InitialBspApicMode stores the initial BSP APIC mode.
+ // It is used to synchronize the BSP APIC mode with APs
+ // in the first time APs wake up.
+ // Its value doesn't reflect the current APIC mode since there are
+ // two cases the APIC mode is changed:
+ // 1. MpLib explicitly switches to X2 APIC mode because number of threads is greater than 255,
+ // or there are any logical processors reporting an initial APIC ID of 255 or greater.
+ // 2. Some code switches to X2 APIC mode in all threads through MP services PPI/Protocol.
+ //
+ UINTN InitialBspApicMode;
UINTN CpuApStackSize;
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
UINTN WakeupBuffer;
@@ -289,7 +300,7 @@ struct _CPU_MP_DATA {
CPU_AP_DATA *CpuData;
volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
- UINT32 CurrentTimerCount;
+ UINT32 InitTimerCount;
UINTN DivideValue;
UINT8 Vector;
BOOLEAN PeriodicMode;
diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
index 4d4b52a..61af77d 100644
--- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
+++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
@@ -162,6 +162,13 @@ MtrrLibIsMtrrSupported (
MSR_IA32_MTRRCAP_REGISTER MtrrCap;
//
+ // MTRR is not supported in TD-Guest.
+ //
+ if (TdIsEnabled ()) {
+ return FALSE;
+ }
+
+ //
// Check CPUID(1).EDX[12] for MTRR capability
//
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &Edx.Uint32);
diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.c b/UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.c
index e6d1b50..a424532 100644
--- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.c
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.c
@@ -4,17 +4,19 @@ for AMD based platforms.
Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.<BR>
-Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
+#include <Guid/SmmBaseHob.h>
#include <Library/SmmCpuFeaturesLib.h>
#include <Uefi/UefiBaseType.h>
#include <Register/Amd/SmramSaveStateMap.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/MmSaveStateLib.h>
+#include <Library/HobLib.h>
// EFER register LMA bit
#define LMA BIT10
@@ -27,6 +29,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
// The mode of the CPU at the time an SMI occurs
STATIC UINT8 mSmmSaveStateRegisterLma;
+//
+// Indicate SmBase for each Processors has been relocated or not. If TRUE,
+// means no need to do the relocation in SmmCpuFeaturesInitializeProcessor().
+//
+BOOLEAN mSmmCpuFeaturesSmmRelocated;
+
/**
Performs library initialization.
@@ -46,6 +54,12 @@ CpuFeaturesLibInitialization (
if (LMAValue) {
mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;
}
+
+ //
+ // If gSmmBaseHobGuid found, means SmBase info has been relocated and recorded
+ // in the SmBase array.
+ //
+ mSmmCpuFeaturesSmmRelocated = (BOOLEAN)(GetFirstGuidHob (&gSmmBaseHobGuid) != NULL);
}
/**
@@ -85,10 +99,15 @@ SmmCpuFeaturesInitializeProcessor (
UINT32 LMAValue;
//
- // Configure SMBASE.
+ // No need to configure SMBASE if SmBase relocation has been done.
//
- CpuState = (AMD_SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
- CpuState->x64.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
+ if (!mSmmCpuFeaturesSmmRelocated) {
+ //
+ // Configure SMBASE.
+ //
+ CpuState = (AMD_SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
+ CpuState->x64.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
+ }
// Re-initialize the value of mSmmSaveStateRegisterLma flag which might have been changed in PiCpuSmmDxeSmm Driver
// Entry point, to make sure correct value on AMD platform is assigned to be used by SmmCpuFeaturesLib.
diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.inf b/UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.inf
index 5ee8a2e..9591524 100644
--- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.inf
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/AmdSmmCpuFeaturesLib.inf
@@ -2,7 +2,7 @@
# The CPU specific programming for PiSmmCpuDxeSmm module.
#
# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
-# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -32,6 +32,10 @@
MemoryAllocationLib
DebugLib
MmSaveStateLib
+ HobLib
+
+[Guids]
+ gSmmBaseHobGuid ## CONSUMES
[FeaturePcd]
gUefiCpuPkgTokenSpaceGuid.PcdSmrrEnable ## CONSUMES
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
index c37a2d4..f3b7d44 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
@@ -6,7 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
#include <PiPei.h>
BOOLEAN mRestoreSmmConfigurationInS3 = FALSE;
@@ -41,13 +41,13 @@ RestoreSmmConfigurationInS3 (
//
if (mRestoreSmmConfigurationInS3) {
//
- // Need make sure gSmst is correct because below function may use them.
+ // Need make sure gMmst is correct because below function may use them.
//
- gSmst->SmmStartupThisAp = gSmmCpuPrivate->SmmCoreEntryContext.SmmStartupThisAp;
- gSmst->CurrentlyExecutingCpu = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu;
- gSmst->NumberOfCpus = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;
- gSmst->CpuSaveStateSize = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveStateSize;
- gSmst->CpuSaveState = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveState;
+ gMmst->MmStartupThisAp = gSmmCpuPrivate->SmmCoreEntryContext.SmmStartupThisAp;
+ gMmst->CurrentlyExecutingCpu = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu;
+ gMmst->NumberOfCpus = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;
+ gMmst->CpuSaveStateSize = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveStateSize;
+ gMmst->CpuSaveState = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveState;
//
// Configure SMM Code Access Check feature if available.
@@ -187,12 +187,10 @@ SmmRestoreCpu (
/**
Initialize SMM S3 resume state structure used during S3 Resume.
- @param[in] Cr3 The base address of the page tables to use in SMM.
-
**/
VOID
InitSmmS3ResumeState (
- IN UINT32 Cr3
+ VOID
)
{
VOID *GuidHob;
@@ -222,7 +220,7 @@ InitSmmS3ResumeState (
ZeroMem (SmmS3ResumeState, sizeof (SMM_S3_RESUME_STATE));
mSmmS3ResumeState = SmmS3ResumeState;
- SmmS3ResumeState->Smst = (EFI_PHYSICAL_ADDRESS)(UINTN)gSmst;
+ SmmS3ResumeState->Smst = (EFI_PHYSICAL_ADDRESS)(UINTN)gMmst;
SmmS3ResumeState->SmmS3ResumeEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)SmmRestoreCpu;
@@ -233,7 +231,6 @@ InitSmmS3ResumeState (
}
SmmS3ResumeState->SmmS3Cr0 = (UINT32)AsmReadCr0 ();
- SmmS3ResumeState->SmmS3Cr3 = Cr3;
SmmS3ResumeState->SmmS3Cr4 = (UINT32)AsmReadCr4 ();
if (sizeof (UINTN) == sizeof (UINT64)) {
@@ -246,19 +243,8 @@ InitSmmS3ResumeState (
//
// Patch SmmS3ResumeState->SmmS3Cr3
+ // The SmmS3Cr3 is only used by S3Resume PEIM to switch CPU from 32bit to 64bit
//
- InitSmmS3Cr3 ();
+ InitSmmS3Cr3 ((UINTN *)&SmmS3ResumeState->SmmS3Cr3);
}
}
-
-/**
- Get ACPI S3 enable flag.
-
-**/
-VOID
-GetAcpiS3EnableFlag (
- VOID
- )
-{
- mAcpiS3Enable = PcdGetBool (PcdAcpiS3Enable);
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c
index c0485b0..72ffb5a 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c
@@ -1,12 +1,12 @@
/** @file
Implementation of SMM CPU Services Protocol.
-Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
//
// SMM CPU Service Protocol instance
@@ -98,7 +98,7 @@ SmmSwitchBsp (
}
if ((gSmmCpuPrivate->Operation[ProcessorNumber] != SmmCpuNone) ||
- (gSmst->CurrentlyExecutingCpu == ProcessorNumber))
+ (gMmst->CurrentlyExecutingCpu == ProcessorNumber))
{
return EFI_UNSUPPORTED;
}
@@ -376,7 +376,7 @@ InitializeSmmCpuServices (
{
EFI_STATUS Status;
- Status = gSmst->SmmInstallProtocolInterface (
+ Status = gMmst->MmInstallProtocolInterface (
&Handle,
&gEfiSmmCpuServiceProtocolGuid,
EFI_NATIVE_INTERFACE,
@@ -387,7 +387,7 @@ InitializeSmmCpuServices (
return Status;
}
- Status = gSmst->SmmInstallProtocolInterface (
+ Status = gMmst->MmInstallProtocolInterface (
&Handle,
&gEdkiiSmmCpuRendezvousProtocolGuid,
EFI_NATIVE_INTERFACE,
@@ -431,7 +431,7 @@ SmmCpuRendezvous (
goto ON_EXIT;
}
- if ((mSmmMpSyncData->EffectiveSyncMode != SmmCpuSyncModeTradition) && !SmmCpuFeaturesNeedConfigureMtrrs ()) {
+ if ((mSmmMpSyncData->EffectiveSyncMode != MmCpuSyncModeTradition) && !SmmCpuFeaturesNeedConfigureMtrrs ()) {
//
// There are some APs outside SMM, Wait for all avaiable APs to arrive.
//
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
index b11264c..e1ce36b 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
@@ -1,14 +1,14 @@
/** @file
Page table manipulation functions for IA-32 processors
-Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
/**
Create PageTable for SMM use.
@@ -33,7 +33,7 @@ SmmInitPageTable (
mPhysicalAddressBits = 32;
mPagingMode = PagingPae;
- if (FeaturePcdGet (PcdCpuSmmProfileEnable) ||
+ if (mSmmProfileEnabled ||
HEAP_GUARD_NONSTOP_MODE ||
NULL_DETECTION_NONSTOP_MODE)
{
@@ -67,15 +67,19 @@ SmmInitPageTable (
}
/**
- Page Fault handler for SMM use.
+ Allocate free Page for PageFault handler use.
+
+ @return Page address.
**/
-VOID
-SmiDefaultPFHandler (
+UINT64
+AllocPage (
VOID
)
{
CpuDeadLoop ();
+
+ return 0;
}
/**
@@ -179,24 +183,21 @@ SmiPFHandler (
}
if (IsSmmCommBufferForbiddenAddress (PFAddress)) {
- DumpCpuContext (InterruptType, SystemContext);
DEBUG ((DEBUG_ERROR, "Access SMM communication forbidden address (0x%x)!\n", PFAddress));
- DEBUG_CODE (
- DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip);
- );
- CpuDeadLoop ();
- goto Exit;
}
}
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ if (mSmmProfileEnabled) {
SmmProfilePFHandler (
SystemContext.SystemContextIa32->Eip,
SystemContext.SystemContextIa32->ExceptionData
);
} else {
DumpCpuContext (InterruptType, SystemContext);
- SmiDefaultPFHandler ();
+ DEBUG_CODE (
+ DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip);
+ );
+ CpuDeadLoop ();
}
Exit:
@@ -228,17 +229,3 @@ RestoreCr2 (
{
return;
}
-
-/**
- Return whether access to non-SMRAM is restricted.
-
- @retval TRUE Access to non-SMRAM is restricted.
- @retval FALSE Access to non-SMRAM is not restricted.
-**/
-BOOLEAN
-IsRestrictedMemoryAccess (
- VOID
- )
-{
- return TRUE;
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm
index e7b85a9..208d6bc 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.nasm
@@ -12,7 +12,6 @@
;
;-------------------------------------------------------------------------------
-extern ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable))
extern ASM_PFX(SmiPFHandler)
extern ASM_PFX(mSetupDebugTrap)
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c
index 0c1cc51..2bcbd33 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c
@@ -6,7 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
extern UINT64 gTaskGateDescriptor;
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArchDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArchDxeSmm.c
new file mode 100644
index 0000000..21f7992
--- /dev/null
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArchDxeSmm.c
@@ -0,0 +1,22 @@
+/** @file
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiSmmCpuCommon.h"
+
+/**
+ Return whether access to non-SMRAM is restricted.
+
+ @retval TRUE Access to non-SMRAM is restricted.
+ @retval FALSE Access to non-SMRAM is not restricted.
+**/
+BOOLEAN
+IsRestrictedMemoryAccess (
+ VOID
+ )
+{
+ return TRUE;
+}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c
index 650090e..b522a50 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c
@@ -1,24 +1,28 @@
/** @file
IA-32 processor specific functions to enable SMM profile.
-Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
#include "SmmProfileInternal.h"
/**
Create SMM page table for S3 path.
+ @param[out] Cr3 The base address of the page tables.
+
**/
VOID
InitSmmS3Cr3 (
- VOID
+ OUT UINTN *Cr3
)
{
- mSmmS3ResumeState->SmmS3Cr3 = GenSmmPageTable (PagingPae, mPhysicalAddressBits);
+ ASSERT (Cr3 != NULL);
+
+ *Cr3 = GenSmmPageTable (PagingPae, mPhysicalAddressBits);
return;
}
@@ -72,3 +76,15 @@ ClearTrapFlag (
{
SystemContext.SystemContextIa32->Eflags &= (UINTN) ~BIT8;
}
+
+/**
+ Create new entry in page table for page fault address in SmmProfilePFHandler.
+
+**/
+VOID
+SmmProfileMapPFAddress (
+ VOID
+ )
+{
+ CpuDeadLoop ();
+}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h
index 6c95f2b..de4a3a3 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h
@@ -1,7 +1,7 @@
/** @file
IA-32 processor specific header file to enable SMM profile.
-Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -73,10 +73,12 @@ RestorePageTableAbove4G (
/**
Create SMM page table for S3 path.
+ @param[out] Cr3 The base address of the page tables.
+
**/
VOID
InitSmmS3Cr3 (
- VOID
+ OUT UINTN *Cr3
);
/**
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
index 570e991..210b23a 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
@@ -8,7 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
//
// Slots for all MTRR( FIXED MTRR + VARIABLE MTRR + MTRR_LIB_IA32_MTRR_DEF_TYPE)
@@ -20,7 +20,7 @@ UINTN mSmmMpSyncDataSize;
SMM_CPU_SEMAPHORES mSmmCpuSemaphores;
UINTN mSemaphoreSize;
SPIN_LOCK *mPFLock = NULL;
-SMM_CPU_SYNC_MODE mCpuSmmSyncMode;
+MM_CPU_SYNC_MODE mCpuSmmSyncMode;
BOOLEAN mMachineCheckSupported = FALSE;
MM_COMPLETION mSmmStartupThisApToken;
@@ -454,8 +454,8 @@ ResetTokens (
**/
VOID
BSPHandler (
- IN UINTN CpuIndex,
- IN SMM_CPU_SYNC_MODE SyncMode
+ IN UINTN CpuIndex,
+ IN MM_CPU_SYNC_MODE SyncMode
)
{
UINTN CpuCount;
@@ -504,7 +504,7 @@ BSPHandler (
//
// If Traditional Sync Mode or need to configure MTRRs: gather all available APs.
//
- if ((SyncMode == SmmCpuSyncModeTradition) || SmmCpuFeaturesNeedConfigureMtrrs ()) {
+ if ((SyncMode == MmCpuSyncModeTradition) || SmmCpuFeaturesNeedConfigureMtrrs ()) {
//
// Wait for APs to arrive
//
@@ -594,7 +594,7 @@ BSPHandler (
// make those APs to exit SMI synchronously. APs which arrive later will be excluded and
// will run through freely.
//
- if ((SyncMode != SmmCpuSyncModeTradition) && !SmmCpuFeaturesNeedConfigureMtrrs ()) {
+ if ((SyncMode != MmCpuSyncModeTradition) && !SmmCpuFeaturesNeedConfigureMtrrs ()) {
//
// Lock door for late coming CPU checkin and retrieve the Arrived number of APs
//
@@ -722,9 +722,9 @@ BSPHandler (
**/
VOID
APHandler (
- IN UINTN CpuIndex,
- IN BOOLEAN ValidSmi,
- IN SMM_CPU_SYNC_MODE SyncMode
+ IN UINTN CpuIndex,
+ IN BOOLEAN ValidSmi,
+ IN MM_CPU_SYNC_MODE SyncMode
)
{
UINT64 Timer;
@@ -801,7 +801,7 @@ APHandler (
//
*(mSmmMpSyncData->CpuData[CpuIndex].Present) = TRUE;
- if ((SyncMode == SmmCpuSyncModeTradition) || SmmCpuFeaturesNeedConfigureMtrrs ()) {
+ if ((SyncMode == MmCpuSyncModeTradition) || SmmCpuFeaturesNeedConfigureMtrrs ()) {
//
// Notify BSP of arrival at this point
//
@@ -1131,7 +1131,7 @@ InternalSmmStartupThisAp (
}
if (!(*(mSmmMpSyncData->CpuData[CpuIndex].Present))) {
- if (mSmmMpSyncData->EffectiveSyncMode == SmmCpuSyncModeTradition) {
+ if (mSmmMpSyncData->EffectiveSyncMode == MmCpuSyncModeTradition) {
DEBUG ((DEBUG_ERROR, "!mSmmMpSyncData->CpuData[%d].Present\n", CpuIndex));
}
@@ -1616,7 +1616,7 @@ SmiRendezvous (
InitializeSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);
}
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ if (mSmmProfileEnabled) {
ActivateSmmProfile (CpuIndex);
}
@@ -1677,7 +1677,7 @@ SmiRendezvous (
}
}
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ if (mSmmProfileEnabled) {
SmmProfileRecordSmiNum ();
}
@@ -1924,6 +1924,7 @@ InitializeMpServiceData (
CPUID_VERSION_INFO_EDX RegEdx;
UINT32 MaxExtendedFunction;
CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize;
+ BOOLEAN RelaxedMode;
//
// Determine if this CPU supports machine check
@@ -1943,7 +1944,10 @@ InitializeMpServiceData (
(sizeof (SMM_CPU_DATA_BLOCK) + sizeof (BOOLEAN)) * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;
mSmmMpSyncData = (SMM_DISPATCHER_MP_SYNC_DATA *)AllocatePages (EFI_SIZE_TO_PAGES (mSmmMpSyncDataSize));
ASSERT (mSmmMpSyncData != NULL);
- mCpuSmmSyncMode = (SMM_CPU_SYNC_MODE)PcdGet8 (PcdCpuSmmSyncMode);
+
+ RelaxedMode = FALSE;
+ GetSmmCpuSyncConfigData (&RelaxedMode, NULL, NULL);
+ mCpuSmmSyncMode = RelaxedMode ? MmCpuSyncModeRelaxedAp : MmCpuSyncModeTradition;
InitializeMpSyncData ();
//
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c
new file mode 100644
index 0000000..8c189ff
--- /dev/null
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c
@@ -0,0 +1,742 @@
+/** @file
+
+Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiSmmCpuCommon.h"
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+//
+// attributes for reserved memory before it is promoted to system memory
+//
+#define EFI_MEMORY_PRESENT 0x0100000000000000ULL
+#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL
+#define EFI_MEMORY_TESTED 0x0400000000000000ULL
+
+#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
+ ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
+
+EFI_MEMORY_DESCRIPTOR *mUefiMemoryMap;
+UINTN mUefiMemoryMapSize;
+UINTN mUefiDescriptorSize;
+
+EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mGcdMemSpace = NULL;
+UINTN mGcdMemNumberOfDesc = 0;
+
+EFI_MEMORY_ATTRIBUTES_TABLE *mUefiMemoryAttributesTable = NULL;
+
+/**
+ Sort memory map entries based upon PhysicalStart, from low to high.
+
+ @param MemoryMap A pointer to the buffer in which firmware places
+ the current memory map.
+ @param MemoryMapSize Size, in bytes, of the MemoryMap buffer.
+ @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+**/
+STATIC
+VOID
+SortMemoryMap (
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ IN UINTN MemoryMapSize,
+ IN UINTN DescriptorSize
+ )
+{
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
+ EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry;
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
+ EFI_MEMORY_DESCRIPTOR TempMemoryMap;
+
+ MemoryMapEntry = MemoryMap;
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+ MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
+ while (MemoryMapEntry < MemoryMapEnd) {
+ while (NextMemoryMapEntry < MemoryMapEnd) {
+ if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {
+ CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
+ CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
+ CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR));
+ }
+
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
+ }
+
+ MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+ }
+}
+
+/**
+ Return if a UEFI memory page should be marked as not present in SMM page table.
+ If the memory map entries type is
+ EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory,
+ EfiUnusableMemory, EfiACPIReclaimMemory, return TRUE.
+ Or return FALSE.
+
+ @param[in] MemoryMap A pointer to the memory descriptor.
+
+ @return TRUE The memory described will be marked as not present in SMM page table.
+ @return FALSE The memory described will not be marked as not present in SMM page table.
+**/
+BOOLEAN
+IsUefiPageNotPresent (
+ IN EFI_MEMORY_DESCRIPTOR *MemoryMap
+ )
+{
+ switch (MemoryMap->Type) {
+ case EfiLoaderCode:
+ case EfiLoaderData:
+ case EfiBootServicesCode:
+ case EfiBootServicesData:
+ case EfiConventionalMemory:
+ case EfiUnusableMemory:
+ case EfiACPIReclaimMemory:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ Merge continuous memory map entries whose type is
+ EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory,
+ EfiUnusableMemory, EfiACPIReclaimMemory, because the memory described by
+ these entries will be set as NOT present in SMM page table.
+
+ @param[in, out] MemoryMap A pointer to the buffer in which firmware places
+ the current memory map.
+ @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the
+ MemoryMap buffer. On input, this is the size of
+ the current memory map. On output,
+ it is the size of new memory map after merge.
+ @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+**/
+STATIC
+VOID
+MergeMemoryMapForNotPresentEntry (
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ IN OUT UINTN *MemoryMapSize,
+ IN UINTN DescriptorSize
+ )
+{
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
+ UINT64 MemoryBlockLength;
+ EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry;
+ EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry;
+
+ MemoryMapEntry = MemoryMap;
+ NewMemoryMapEntry = MemoryMap;
+ MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize);
+ while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
+ CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+
+ do {
+ MemoryBlockLength = (UINT64)(EFI_PAGES_TO_SIZE ((UINTN)MemoryMapEntry->NumberOfPages));
+ if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&
+ IsUefiPageNotPresent (MemoryMapEntry) && IsUefiPageNotPresent (NextMemoryMapEntry) &&
+ ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart))
+ {
+ MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
+ if (NewMemoryMapEntry != MemoryMapEntry) {
+ NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
+ }
+
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
+ continue;
+ } else {
+ MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
+ break;
+ }
+ } while (TRUE);
+
+ MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
+ NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);
+ }
+
+ *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap;
+
+ return;
+}
+
+/**
+ This function caches the GCD memory map information.
+**/
+VOID
+GetGcdMemoryMap (
+ VOID
+ )
+{
+ UINTN NumberOfDescriptors;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemSpaceMap;
+ EFI_STATUS Status;
+ UINTN Index;
+
+ Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ mGcdMemNumberOfDesc = 0;
+ for (Index = 0; Index < NumberOfDescriptors; Index++) {
+ if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) &&
+ ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
+ (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
+ )
+ {
+ mGcdMemNumberOfDesc++;
+ }
+ }
+
+ mGcdMemSpace = AllocateZeroPool (mGcdMemNumberOfDesc * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR));
+ ASSERT (mGcdMemSpace != NULL);
+ if (mGcdMemSpace == NULL) {
+ mGcdMemNumberOfDesc = 0;
+ gBS->FreePool (MemSpaceMap);
+ return;
+ }
+
+ mGcdMemNumberOfDesc = 0;
+ for (Index = 0; Index < NumberOfDescriptors; Index++) {
+ if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) &&
+ ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
+ (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
+ )
+ {
+ CopyMem (
+ &mGcdMemSpace[mGcdMemNumberOfDesc],
+ &MemSpaceMap[Index],
+ sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR)
+ );
+ mGcdMemNumberOfDesc++;
+ }
+ }
+
+ gBS->FreePool (MemSpaceMap);
+}
+
+/**
+ Get UEFI MemoryAttributesTable.
+**/
+VOID
+GetUefiMemoryAttributesTable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
+ UINTN MemoryAttributesTableSize;
+
+ Status = EfiGetSystemConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
+ if (!EFI_ERROR (Status) && (MemoryAttributesTable != NULL)) {
+ MemoryAttributesTableSize = sizeof (EFI_MEMORY_ATTRIBUTES_TABLE) + MemoryAttributesTable->DescriptorSize * MemoryAttributesTable->NumberOfEntries;
+ mUefiMemoryAttributesTable = AllocateCopyPool (MemoryAttributesTableSize, MemoryAttributesTable);
+ ASSERT (mUefiMemoryAttributesTable != NULL);
+ }
+}
+
+/**
+ This function caches the UEFI memory map information.
+**/
+VOID
+GetUefiMemoryMap (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN MapKey;
+ UINT32 DescriptorVersion;
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;
+ UINTN UefiMemoryMapSize;
+
+ DEBUG ((DEBUG_INFO, "GetUefiMemoryMap\n"));
+
+ UefiMemoryMapSize = 0;
+ MemoryMap = NULL;
+ Status = gBS->GetMemoryMap (
+ &UefiMemoryMapSize,
+ MemoryMap,
+ &MapKey,
+ &mUefiDescriptorSize,
+ &DescriptorVersion
+ );
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ do {
+ Status = gBS->AllocatePool (EfiBootServicesData, UefiMemoryMapSize, (VOID **)&MemoryMap);
+ ASSERT (MemoryMap != NULL);
+ if (MemoryMap == NULL) {
+ return;
+ }
+
+ Status = gBS->GetMemoryMap (
+ &UefiMemoryMapSize,
+ MemoryMap,
+ &MapKey,
+ &mUefiDescriptorSize,
+ &DescriptorVersion
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (MemoryMap);
+ MemoryMap = NULL;
+ }
+ } while (Status == EFI_BUFFER_TOO_SMALL);
+
+ if (MemoryMap == NULL) {
+ return;
+ }
+
+ SortMemoryMap (MemoryMap, UefiMemoryMapSize, mUefiDescriptorSize);
+ MergeMemoryMapForNotPresentEntry (MemoryMap, &UefiMemoryMapSize, mUefiDescriptorSize);
+
+ mUefiMemoryMapSize = UefiMemoryMapSize;
+ mUefiMemoryMap = AllocateCopyPool (UefiMemoryMapSize, MemoryMap);
+ ASSERT (mUefiMemoryMap != NULL);
+
+ gBS->FreePool (MemoryMap);
+
+ //
+ // Get additional information from GCD memory map.
+ //
+ GetGcdMemoryMap ();
+
+ //
+ // Get UEFI memory attributes table.
+ //
+ GetUefiMemoryAttributesTable ();
+}
+
+/**
+ This function updates UEFI memory attribute according to UEFI memory map.
+
+**/
+VOID
+UpdateUefiMemMapAttributes (
+ VOID
+ )
+{
+ BOOLEAN WriteProtect;
+ BOOLEAN CetEnabled;
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT64 Limit;
+ UINT64 PreviousAddress;
+ UINTN PageTable;
+ UINT64 Base;
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;
+ UINTN MemoryMapEntryCount;
+ EFI_MEMORY_DESCRIPTOR *Entry;
+
+ DEBUG ((DEBUG_INFO, "UpdateUefiMemMapAttributes Start...\n"));
+
+ WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled);
+
+ PageTable = AsmReadCr3 ();
+ Limit = LShiftU64 (1, mPhysicalAddressBits);
+
+ //
+ // [0, 4k] may be non-present.
+ //
+ PreviousAddress = ((FixedPcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) ? BASE_4KB : 0;
+
+ //
+ // NonMmram shall be non-executable after the SmmReadyToLock event occurs, regardless of whether
+ // RestrictedMemoryAccess is enabled, since all MM drivers located in NonMmram have already been dispatched and executed.
+ //
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
+ Base = mSmmCpuSmramRanges[Index].CpuStart;
+ if (Base > PreviousAddress) {
+ Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Base - PreviousAddress, EFI_MEMORY_XP, TRUE, NULL);
+ ASSERT_RETURN_ERROR (Status);
+ }
+
+ PreviousAddress = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize;
+ }
+
+ if (PreviousAddress < Limit) {
+ Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Limit - PreviousAddress, EFI_MEMORY_XP, TRUE, NULL);
+ ASSERT_RETURN_ERROR (Status);
+ }
+
+ //
+ // Set NonMmram to not-present by excluding "RT, Reserved and NVS" memory type when RestrictedMemoryAccess is enabled.
+ //
+ if (IsRestrictedMemoryAccess ()) {
+ if (mUefiMemoryMap != NULL) {
+ MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize;
+ MemoryMap = mUefiMemoryMap;
+ for (Index = 0; Index < MemoryMapEntryCount; Index++) {
+ if (IsUefiPageNotPresent (MemoryMap)) {
+ Status = ConvertMemoryPageAttributes (
+ PageTable,
+ mPagingMode,
+ MemoryMap->PhysicalStart,
+ EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages),
+ EFI_MEMORY_RP,
+ TRUE,
+ NULL
+ );
+ DEBUG ((
+ DEBUG_INFO,
+ "UefiMemory protection: 0x%lx - 0x%lx %r\n",
+ MemoryMap->PhysicalStart,
+ MemoryMap->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages),
+ Status
+ ));
+ }
+
+ MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize);
+ }
+ }
+
+ //
+ // Do not free mUefiMemoryMap, it will be checked in IsSmmCommBufferForbiddenAddress().
+ //
+
+ //
+ // Set untested NonMmram memory as not present.
+ //
+ if (mGcdMemSpace != NULL) {
+ for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) {
+ Status = ConvertMemoryPageAttributes (
+ PageTable,
+ mPagingMode,
+ mGcdMemSpace[Index].BaseAddress,
+ mGcdMemSpace[Index].Length,
+ EFI_MEMORY_RP,
+ TRUE,
+ NULL
+ );
+ DEBUG ((
+ DEBUG_INFO,
+ "GcdMemory protection: 0x%lx - 0x%lx %r\n",
+ mGcdMemSpace[Index].BaseAddress,
+ mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length,
+ Status
+ ));
+ }
+ }
+
+ //
+ // Do not free mGcdMemSpace, it will be checked in IsSmmCommBufferForbiddenAddress().
+ //
+
+ //
+ // Above logic sets the whole RT memory as present.
+ // Below logic is to set the RT code as not present.
+ //
+ if (mUefiMemoryAttributesTable != NULL) {
+ Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1);
+ for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {
+ if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) {
+ if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
+ Status = ConvertMemoryPageAttributes (
+ PageTable,
+ mPagingMode,
+ Entry->PhysicalStart,
+ EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages),
+ EFI_MEMORY_RP,
+ TRUE,
+ NULL
+ );
+ DEBUG ((
+ DEBUG_INFO,
+ "UefiMemoryAttribute protection: 0x%lx - 0x%lx %r\n",
+ Entry->PhysicalStart,
+ Entry->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages),
+ Status
+ ));
+ }
+ }
+
+ Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);
+ }
+ }
+
+ //
+ // Do not free mUefiMemoryAttributesTable, it will be checked in IsSmmCommBufferForbiddenAddress().
+ //
+ }
+
+ //
+ // Flush TLB
+ //
+ CpuFlushTlb ();
+
+ //
+ // Set execute-disable flag
+ //
+ mXdEnabled = TRUE;
+
+ WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled);
+
+ DEBUG ((DEBUG_INFO, "UpdateUefiMemMapAttributes Done.\n"));
+}
+
+/**
+ Get SmmProfileData.
+
+ @param[in, out] Size Return Size of SmmProfileData.
+
+ @return Address of SmmProfileData
+
+**/
+EFI_PHYSICAL_ADDRESS
+GetSmmProfileData (
+ IN OUT UINT64 *Size
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Base;
+
+ ASSERT (Size != NULL);
+
+ *Size = PcdGet32 (PcdCpuSmmProfileSize);
+
+ Base = 0xFFFFFFFF;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ (UINTN)EFI_SIZE_TO_PAGES (*Size),
+ &Base
+ );
+ ASSERT_EFI_ERROR (Status);
+ ZeroMem ((VOID *)(UINTN)Base, (UINTN)*Size);
+
+ return Base;
+}
+
+/**
+ Return if the Address is the NonMmram logging Address.
+
+ @param[in] Address the address to be checked
+
+ @return TRUE The address is the NonMmram logging Address.
+ @return FALSE The address is not the NonMmram logging Address.
+**/
+BOOLEAN
+IsNonMmramLoggingAddress (
+ IN UINT64 Address
+ )
+{
+ ASSERT (FALSE);
+
+ return TRUE;
+}
+
+/**
+ Return if the Address is forbidden as SMM communication buffer.
+
+ @param[in] Address the address to be checked
+
+ @return TRUE The address is forbidden as SMM communication buffer.
+ @return FALSE The address is allowed as SMM communication buffer.
+**/
+BOOLEAN
+IsSmmCommBufferForbiddenAddress (
+ IN UINT64 Address
+ )
+{
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;
+ UINTN MemoryMapEntryCount;
+ UINTN Index;
+ EFI_MEMORY_DESCRIPTOR *Entry;
+
+ if (!IsRestrictedMemoryAccess ()) {
+ return FALSE;
+ }
+
+ if (mUefiMemoryMap != NULL) {
+ MemoryMap = mUefiMemoryMap;
+ MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize;
+ for (Index = 0; Index < MemoryMapEntryCount; Index++) {
+ if (IsUefiPageNotPresent (MemoryMap)) {
+ if ((Address >= MemoryMap->PhysicalStart) &&
+ (Address < MemoryMap->PhysicalStart + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages)))
+ {
+ return TRUE;
+ }
+ }
+
+ MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize);
+ }
+ }
+
+ if (mGcdMemSpace != NULL) {
+ for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) {
+ if ((Address >= mGcdMemSpace[Index].BaseAddress) &&
+ (Address < mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length))
+ {
+ return TRUE;
+ }
+ }
+ }
+
+ if (mUefiMemoryAttributesTable != NULL) {
+ Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1);
+ for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {
+ if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) {
+ if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
+ if ((Address >= Entry->PhysicalStart) &&
+ (Address < Entry->PhysicalStart + LShiftU64 (Entry->NumberOfPages, EFI_PAGE_SHIFT)))
+ {
+ return TRUE;
+ }
+
+ Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Create extended protection MemoryRegion.
+ Return all MMIO ranges that are reported in GCD service at EndOfDxe.
+
+ The caller is responsible for freeing MemoryRegion via FreePool().
+
+ @param[out] MemoryRegion Returned Non-Mmram Memory regions.
+ @param[out] MemoryRegionCount A pointer to the number of Memory regions.
+**/
+VOID
+CreateExtendedProtectionRange (
+ OUT MM_CPU_MEMORY_REGION **MemoryRegion,
+ OUT UINTN *MemoryRegionCount
+ )
+{
+ UINTN Index;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
+ UINTN NumberOfSpaceDescriptors;
+ UINTN MemoryRegionIndex;
+ UINTN Count;
+
+ MemorySpaceMap = NULL;
+ NumberOfSpaceDescriptors = 0;
+ Count = 0;
+
+ ASSERT (MemoryRegion != NULL && MemoryRegionCount != NULL);
+
+ *MemoryRegion = NULL;
+ *MemoryRegionCount = 0;
+
+ //
+ // Get MMIO ranges from GCD.
+ //
+ gDS->GetMemorySpaceMap (
+ &NumberOfSpaceDescriptors,
+ &MemorySpaceMap
+ );
+ for (Index = 0; Index < NumberOfSpaceDescriptors; Index++) {
+ if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) {
+ if (ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) &&
+ (MemorySpaceMap[Index].Length % SIZE_4KB == 0))
+ {
+ Count++;
+ } else {
+ //
+ // Skip the MMIO range that BaseAddress and Length are not 4k aligned since
+ // the minimum granularity of the page table is 4k
+ //
+ DEBUG ((
+ DEBUG_WARN,
+ "MMIO range [0x%lx, 0x%lx] is skipped since it is not 4k aligned.\n",
+ MemorySpaceMap[Index].BaseAddress,
+ MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length
+ ));
+ }
+ }
+ }
+
+ *MemoryRegionCount = Count;
+
+ *MemoryRegion = (MM_CPU_MEMORY_REGION *)AllocateZeroPool (sizeof (MM_CPU_MEMORY_REGION) * Count);
+ ASSERT (*MemoryRegion != NULL);
+
+ MemoryRegionIndex = 0;
+ for (Index = 0; Index < NumberOfSpaceDescriptors; Index++) {
+ if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&
+ ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) &&
+ (MemorySpaceMap[Index].Length % SIZE_4KB == 0))
+ {
+ (*MemoryRegion)[MemoryRegionIndex].Base = MemorySpaceMap[Index].BaseAddress;
+ (*MemoryRegion)[MemoryRegionIndex].Length = MemorySpaceMap[Index].Length;
+ MemoryRegionIndex++;
+ }
+ }
+
+ return;
+}
+
+/**
+ Create the Non-Mmram Memory Region.
+ Build MemoryRegion to cover [0, 2^PhysicalAddressBits) by excluding all Smram range.
+ The memory attribute is all-allowed (read/write/executable).
+
+ The caller is responsible for freeing MemoryRegion via FreePool().
+
+ @param[in] PhysicalAddressBits The bits of physical address to map.
+ @param[out] MemoryRegion Returned Non-Mmram Memory regions.
+ @param[out] MemoryRegionCount A pointer to the number of Memory regions.
+**/
+VOID
+CreateNonMmramMemMap (
+ IN UINT8 PhysicalAddressBits,
+ OUT MM_CPU_MEMORY_REGION **MemoryRegion,
+ OUT UINTN *MemoryRegionCount
+ )
+{
+ UINT64 MaxLength;
+ UINTN Count;
+ UINTN Index;
+ UINT64 PreviousAddress;
+ UINT64 Base;
+ UINT64 Length;
+
+ ASSERT (MemoryRegion != NULL && MemoryRegionCount != NULL);
+
+ *MemoryRegion = NULL;
+ *MemoryRegionCount = 0;
+
+ MaxLength = LShiftU64 (1, PhysicalAddressBits);
+
+ //
+ // Build MemoryRegion to cover [0, 2^PhysicalAddressBits) by excluding all Smram range
+ //
+ Count = mSmmCpuSmramRangeCount + 1;
+
+ *MemoryRegionCount = Count;
+
+ *MemoryRegion = (MM_CPU_MEMORY_REGION *)AllocateZeroPool (sizeof (MM_CPU_MEMORY_REGION) * Count);
+ ASSERT (*MemoryRegion != NULL);
+
+ PreviousAddress = 0;
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
+ Base = mSmmCpuSmramRanges[Index].CpuStart;
+ Length = mSmmCpuSmramRanges[Index].PhysicalSize;
+
+ ASSERT (MaxLength > Base + Length);
+
+ if (Base > PreviousAddress) {
+ (*MemoryRegion)[Index].Base = PreviousAddress;
+ (*MemoryRegion)[Index].Length = Base - PreviousAddress;
+ (*MemoryRegion)[Index].Attribute = 0;
+ }
+
+ PreviousAddress = Base + Length;
+ }
+
+ //
+ // Set the last remaining range
+ //
+ if (PreviousAddress < MaxLength) {
+ (*MemoryRegion)[Index].Base = PreviousAddress;
+ (*MemoryRegion)[Index].Length = MaxLength - PreviousAddress;
+ }
+}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c
new file mode 100644
index 0000000..dba7db0
--- /dev/null
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapStandaloneMm.c
@@ -0,0 +1,214 @@
+/** @file
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiSmmCpuCommon.h"
+
+/**
+ Get SmmProfileData.
+
+ @param[in, out] Size Return Size of SmmProfileData.
+ 0 means the gMmProfileDataHobGuid does not exist.
+
+ @return Address of SmmProfileData
+
+**/
+EFI_PHYSICAL_ADDRESS
+GetSmmProfileData (
+ IN OUT UINT64 *Size
+ )
+{
+ EFI_PEI_HOB_POINTERS SmmProfileDataHob;
+
+ ASSERT (Size != NULL);
+
+ //
+ // Get Smm Profile Base from Memory Allocation HOB
+ //
+ SmmProfileDataHob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
+ while (SmmProfileDataHob.Raw != NULL) {
+ //
+ // Find gMmProfileDataHobGuid
+ //
+ if (CompareGuid (&SmmProfileDataHob.MemoryAllocation->AllocDescriptor.Name, &gMmProfileDataHobGuid)) {
+ break;
+ }
+
+ SmmProfileDataHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (SmmProfileDataHob));
+ }
+
+ if (SmmProfileDataHob.Raw == NULL) {
+ *Size = 0;
+ return 0;
+ }
+
+ *Size = SmmProfileDataHob.MemoryAllocation->AllocDescriptor.MemoryLength;
+
+ return SmmProfileDataHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress;
+}
+
+/**
+ Return if the Address is the NonMmram logging Address.
+
+ @param[in] Address the address to be checked
+
+ @return TRUE The address is the NonMmram logging Address.
+ @return FALSE The address is not the NonMmram logging Address.
+**/
+BOOLEAN
+IsNonMmramLoggingAddress (
+ IN UINT64 Address
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+ while (Hob.Raw != NULL) {
+ if ((Address >= Hob.ResourceDescriptor->PhysicalStart) && (Address < Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength)) {
+ if ((Hob.ResourceDescriptor->ResourceAttribute & MM_RESOURCE_ATTRIBUTE_LOGGING) != 0) {
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
+ }
+
+ return FALSE;
+}
+
+/**
+ Return if the Address is forbidden as SMM communication buffer.
+
+ @param[in] Address the address to be checked
+
+ @return TRUE The address is forbidden as SMM communication buffer.
+ @return FALSE The address is allowed as SMM communication buffer.
+**/
+BOOLEAN
+IsSmmCommBufferForbiddenAddress (
+ IN UINT64 Address
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+ while (Hob.Raw != NULL) {
+ if ((Address >= Hob.ResourceDescriptor->PhysicalStart) && (Address < Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength)) {
+ return FALSE;
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
+ }
+
+ return TRUE;
+}
+
+/**
+ Build Memory Region from ResourceDescriptor HOBs by excluding Logging attribute range.
+
+ @param[out] MemoryRegion Returned Non-Mmram Memory regions.
+ @param[out] MemoryRegionCount A pointer to the number of Memory regions.
+**/
+VOID
+BuildMemoryMapFromResDescHobs (
+ OUT MM_CPU_MEMORY_REGION **MemoryRegion,
+ OUT UINTN *MemoryRegionCount
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINTN Count;
+ UINTN Index;
+
+ ASSERT (MemoryRegion != NULL && MemoryRegionCount != NULL);
+
+ *MemoryRegion = NULL;
+ *MemoryRegionCount = 0;
+
+ //
+ // Get the count.
+ //
+ Count = 0;
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+ while (Hob.Raw != NULL) {
+ if ((Hob.ResourceDescriptor->ResourceAttribute & MM_RESOURCE_ATTRIBUTE_LOGGING) == 0) {
+ //
+ // Resource HOBs describe all accessible non-smram regions.
+ // Logging attribute range is treated as not present. Not-present ranges are not included in this memory map.
+ //
+ Count++;
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
+ }
+
+ *MemoryRegionCount = Count;
+
+ *MemoryRegion = (MM_CPU_MEMORY_REGION *)AllocateZeroPool (sizeof (MM_CPU_MEMORY_REGION) * Count);
+ ASSERT (*MemoryRegion != NULL);
+
+ Index = 0;
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+ while (Hob.Raw != NULL) {
+ if ((Hob.ResourceDescriptor->ResourceAttribute & MM_RESOURCE_ATTRIBUTE_LOGGING) == 0) {
+ ASSERT (Index < Count);
+ (*MemoryRegion)[Index].Base = Hob.ResourceDescriptor->PhysicalStart;
+ (*MemoryRegion)[Index].Length = Hob.ResourceDescriptor->ResourceLength;
+ (*MemoryRegion)[Index].Attribute = EFI_MEMORY_XP;
+ if (Hob.ResourceDescriptor->ResourceAttribute == EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED) {
+ (*MemoryRegion)[Index].Attribute |= EFI_MEMORY_RO;
+ }
+
+ Index++;
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
+ }
+
+ return;
+}
+
+/**
+ Build extended protection MemoryRegion.
+
+ The caller is responsible for freeing MemoryRegion via FreePool().
+
+ @param[out] MemoryRegion Returned Non-Mmram Memory regions.
+ @param[out] MemoryRegionCount A pointer to the number of Memory regions.
+**/
+VOID
+CreateExtendedProtectionRange (
+ OUT MM_CPU_MEMORY_REGION **MemoryRegion,
+ OUT UINTN *MemoryRegionCount
+ )
+{
+ BuildMemoryMapFromResDescHobs (MemoryRegion, MemoryRegionCount);
+}
+
+/**
+ Create the Non-Mmram Memory Region within the ResourceDescriptor HOBs
+ without Logging attribute.
+
+ The caller is responsible for freeing MemoryRegion via FreePool().
+
+ @param[in] PhysicalAddressBits The bits of physical address to map.
+ @param[out] MemoryRegion Returned Non-Mmram Memory regions.
+ @param[out] MemoryRegionCount A pointer to the number of Memory regions.
+**/
+VOID
+CreateNonMmramMemMap (
+ IN UINT8 PhysicalAddressBits,
+ OUT MM_CPU_MEMORY_REGION **MemoryRegion,
+ OUT UINTN *MemoryRegionCount
+ )
+{
+ BuildMemoryMapFromResDescHobs (MemoryRegion, MemoryRegionCount);
+}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c
new file mode 100644
index 0000000..c6df935
--- /dev/null
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c
@@ -0,0 +1,1538 @@
+/** @file
+Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
+
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiSmmCpuCommon.h"
+
+//
+// SMM CPU Private Data structure that contains SMM Configuration Protocol
+// along its supporting fields.
+//
+SMM_CPU_PRIVATE_DATA mSmmCpuPrivateData = {
+ SMM_CPU_PRIVATE_DATA_SIGNATURE, // Signature
+ NULL, // SmmCpuHandle
+ NULL, // Pointer to ProcessorInfo array
+ NULL, // Pointer to Operation array
+ NULL, // Pointer to CpuSaveStateSize array
+ NULL, // Pointer to CpuSaveState array
+ {
+ { 0 }
+ }, // SmmReservedSmramRegion
+ {
+ SmmStartupThisAp, // SmmCoreEntryContext.SmmStartupThisAp
+ 0, // SmmCoreEntryContext.CurrentlyExecutingCpu
+ 0, // SmmCoreEntryContext.NumberOfCpus
+ NULL, // SmmCoreEntryContext.CpuSaveStateSize
+ NULL // SmmCoreEntryContext.CpuSaveState
+ },
+ NULL, // SmmCoreEntry
+ {
+ mSmmCpuPrivateData.SmmReservedSmramRegion, // SmmConfiguration.SmramReservedRegions
+ RegisterSmmEntry // SmmConfiguration.RegisterSmmEntry
+ },
+ NULL, // pointer to Ap Wrapper Func array
+ { NULL, NULL }, // List_Entry for Tokens.
+};
+
+CPU_HOT_PLUG_DATA mCpuHotPlugData = {
+ CPU_HOT_PLUG_DATA_REVISION_1, // Revision
+ 0, // Array Length of SmBase and APIC ID
+ NULL, // Pointer to APIC ID array
+ NULL, // Pointer to SMBASE array
+ 0, // Reserved
+ 0, // SmrrBase
+ 0 // SmrrSize
+};
+
+//
+// Global pointer used to access mSmmCpuPrivateData from outside and inside SMM
+//
+SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate = &mSmmCpuPrivateData;
+
+///
+/// Handle for the SMM CPU Protocol
+///
+EFI_HANDLE mSmmCpuHandle = NULL;
+
+///
+/// SMM CPU Protocol instance
+///
+EFI_SMM_CPU_PROTOCOL mSmmCpu = {
+ SmmReadSaveState,
+ SmmWriteSaveState
+};
+
+///
+/// SMM Memory Attribute Protocol instance
+///
+EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL mSmmMemoryAttribute = {
+ EdkiiSmmGetMemoryAttributes,
+ EdkiiSmmSetMemoryAttributes,
+ EdkiiSmmClearMemoryAttributes
+};
+
+EFI_CPU_INTERRUPT_HANDLER mExternalVectorTable[EXCEPTION_VECTOR_NUMBER];
+
+volatile BOOLEAN *mSmmInitialized = NULL;
+UINT32 mBspApicId = 0;
+
+//
+// SMM stack information
+//
+UINTN mSmmStackArrayBase;
+UINTN mSmmStackArrayEnd;
+UINTN mSmmStackSize;
+
+UINTN mSmmShadowStackSize;
+BOOLEAN mCetSupported = TRUE;
+
+UINTN mMaxNumberOfCpus = 0;
+UINTN mNumberOfCpus = 0;
+
+//
+// Global used to cache PCD for SMM Code Access Check enable
+//
+BOOLEAN mSmmCodeAccessCheckEnable = FALSE;
+
+//
+// Global used to cache SMM Debug Agent Supported ot not
+//
+BOOLEAN mSmmDebugAgentSupport = FALSE;
+
+//
+// Global copy of the PcdPteMemoryEncryptionAddressOrMask
+//
+UINT64 mAddressEncMask = 0;
+
+//
+// Spin lock used to serialize setting of SMM Code Access Check feature
+//
+SPIN_LOCK *mConfigSmmCodeAccessCheckLock = NULL;
+
+//
+// Saved SMM ranges information
+//
+EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges;
+UINTN mSmmCpuSmramRangeCount;
+
+UINT8 mPhysicalAddressBits;
+
+/**
+ Initialize IDT to setup exception handlers for SMM.
+
+**/
+VOID
+InitializeSmmIdt (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN InterruptState;
+ IA32_DESCRIPTOR DxeIdtr;
+
+ //
+ // There are 32 (not 255) entries in it since only processor
+ // generated exceptions will be handled.
+ //
+ gcSmiIdtr.Limit = (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32) - 1;
+ //
+ // Allocate page aligned IDT, because it might be set as read only.
+ //
+ gcSmiIdtr.Base = (UINTN)AllocateCodePages (EFI_SIZE_TO_PAGES (gcSmiIdtr.Limit + 1));
+ ASSERT (gcSmiIdtr.Base != 0);
+ ZeroMem ((VOID *)gcSmiIdtr.Base, gcSmiIdtr.Limit + 1);
+
+ //
+ // Disable Interrupt and save DXE IDT table
+ //
+ InterruptState = SaveAndDisableInterrupts ();
+ AsmReadIdtr (&DxeIdtr);
+ //
+ // Load SMM temporary IDT table
+ //
+ AsmWriteIdtr (&gcSmiIdtr);
+ //
+ // Setup SMM default exception handlers, SMM IDT table
+ // will be updated and saved in gcSmiIdtr
+ //
+ Status = InitializeCpuExceptionHandlers (NULL);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Restore DXE IDT table and CPU interrupt
+ //
+ AsmWriteIdtr ((IA32_DESCRIPTOR *)&DxeIdtr);
+ SetInterruptState (InterruptState);
+}
+
+/**
+ Search module name by input IP address and output it.
+
+ @param CallerIpAddress Caller instruction pointer.
+
+**/
+VOID
+DumpModuleInfoByIp (
+ IN UINTN CallerIpAddress
+ )
+{
+ UINTN Pe32Data;
+ VOID *PdbPointer;
+
+ //
+ // Find Image Base
+ //
+ Pe32Data = PeCoffSearchImageBase (CallerIpAddress);
+ if (Pe32Data != 0) {
+ DEBUG ((DEBUG_ERROR, "It is invoked from the instruction before IP(0x%p)", (VOID *)CallerIpAddress));
+ PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)Pe32Data);
+ if (PdbPointer != NULL) {
+ DEBUG ((DEBUG_ERROR, " in module (%a)\n", PdbPointer));
+ }
+ }
+}
+
+/**
+ Read information from the CPU save state.
+
+ @param This EFI_SMM_CPU_PROTOCOL instance
+ @param Width The number of bytes to read from the CPU save state.
+ @param Register Specifies the CPU register to read form the save state.
+ @param CpuIndex Specifies the zero-based index of the CPU save state.
+ @param Buffer Upon return, this holds the CPU register value read from the save state.
+
+ @retval EFI_SUCCESS The register was read from Save State
+ @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
+ @retval EFI_INVALID_PARAMETER This or Buffer is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+SmmReadSaveState (
+ IN CONST EFI_SMM_CPU_PROTOCOL *This,
+ IN UINTN Width,
+ IN EFI_SMM_SAVE_STATE_REGISTER Register,
+ IN UINTN CpuIndex,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Retrieve pointer to the specified CPU's SMM Save State buffer
+ //
+ if ((CpuIndex >= gMmst->NumberOfCpus) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // The SpeculationBarrier() call here is to ensure the above check for the
+ // CpuIndex has been completed before the execution of subsequent codes.
+ //
+ SpeculationBarrier ();
+
+ //
+ // Check for special EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID
+ //
+ if (Register == EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID) {
+ //
+ // The pseudo-register only supports the 64-bit size specified by Width.
+ //
+ if (Width != sizeof (UINT64)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If the processor is in SMM at the time the SMI occurred,
+ // the pseudo register value for EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID is returned in Buffer.
+ // Otherwise, EFI_NOT_FOUND is returned.
+ //
+ if (*(mSmmMpSyncData->CpuData[CpuIndex].Present)) {
+ *(UINT64 *)Buffer = gSmmCpuPrivate->ProcessorInfo[CpuIndex].ProcessorId;
+ return EFI_SUCCESS;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ if (!(*(mSmmMpSyncData->CpuData[CpuIndex].Present))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = MmSaveStateReadRegister (CpuIndex, Register, Width, Buffer);
+
+ return Status;
+}
+
+/**
+ Write data to the CPU save state.
+
+ @param This EFI_SMM_CPU_PROTOCOL instance
+ @param Width The number of bytes to read from the CPU save state.
+ @param Register Specifies the CPU register to write to the save state.
+ @param CpuIndex Specifies the zero-based index of the CPU save state
+ @param Buffer Upon entry, this holds the new CPU register value.
+
+ @retval EFI_SUCCESS The register was written from Save State
+ @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
+ @retval EFI_INVALID_PARAMETER ProcessorIndex or Width is not correct
+
+**/
+EFI_STATUS
+EFIAPI
+SmmWriteSaveState (
+ IN CONST EFI_SMM_CPU_PROTOCOL *This,
+ IN UINTN Width,
+ IN EFI_SMM_SAVE_STATE_REGISTER Register,
+ IN UINTN CpuIndex,
+ IN CONST VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Retrieve pointer to the specified CPU's SMM Save State buffer
+ //
+ if ((CpuIndex >= gMmst->NumberOfCpus) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Writes to EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID are ignored
+ //
+ if (Register == EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID) {
+ return EFI_SUCCESS;
+ }
+
+ if (!mSmmMpSyncData->CpuData[CpuIndex].Present) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = MmSaveStateWriteRegister (CpuIndex, Register, Width, Buffer);
+
+ return Status;
+}
+
+/**
+ Initialize SMM environment.
+
+**/
+VOID
+InitializeSmm (
+ VOID
+ )
+{
+ UINT32 ApicId;
+ UINTN Index;
+ BOOLEAN IsBsp;
+
+ ApicId = GetApicId ();
+
+ IsBsp = (BOOLEAN)(mBspApicId == ApicId);
+
+ ASSERT (mNumberOfCpus <= mMaxNumberOfCpus);
+
+ for (Index = 0; Index < mNumberOfCpus; Index++) {
+ if (ApicId == (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId) {
+ PERF_CODE (
+ MpPerfBegin (Index, SMM_MP_PERF_PROCEDURE_ID (InitializeSmm));
+ );
+ //
+ // Initialize SMM specific features on the currently executing CPU
+ //
+ SmmCpuFeaturesInitializeProcessor (
+ Index,
+ IsBsp,
+ gSmmCpuPrivate->ProcessorInfo,
+ &mCpuHotPlugData
+ );
+
+ if (!mSmmS3Flag) {
+ //
+ // Check XD and BTS features on each processor on normal boot
+ //
+ CheckFeatureSupported (Index);
+
+ if (mIsStandaloneMm) {
+ AcquireSpinLock (mConfigSmmCodeAccessCheckLock);
+
+ //
+ // Standalone MM does not allow call out to DXE at anytime.
+ // Code Access check can be enabled in the first SMI.
+ // While SMM needs to defer the enabling to EndOfDxe.
+ //
+ // Enable SMM Code Access Check feature.
+ //
+ ConfigSmmCodeAccessCheckOnCurrentProcessor (&Index);
+ }
+ } else if (IsBsp) {
+ //
+ // BSP rebase is already done above.
+ // Initialize private data during S3 resume
+ //
+ InitializeMpSyncData ();
+ }
+
+ PERF_CODE (
+ MpPerfEnd (Index, SMM_MP_PERF_PROCEDURE_ID (InitializeSmm));
+ );
+
+ return;
+ }
+ }
+
+ ASSERT (FALSE);
+}
+
+/**
+ Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init.
+
+**/
+VOID
+ExecuteFirstSmiInit (
+ VOID
+ )
+{
+ UINTN Index;
+
+ PERF_FUNCTION_BEGIN ();
+
+ if (mSmmInitialized == NULL) {
+ mSmmInitialized = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) * mMaxNumberOfCpus);
+ }
+
+ ASSERT (mSmmInitialized != NULL);
+ if (mSmmInitialized == NULL) {
+ PERF_FUNCTION_END ();
+ return;
+ }
+
+ //
+ // Reset the mSmmInitialized to false.
+ //
+ ZeroMem ((VOID *)mSmmInitialized, sizeof (BOOLEAN) * mMaxNumberOfCpus);
+
+ //
+ // Initialize the lock used to serialize the MSR programming in BSP and all APs
+ //
+ InitializeSpinLock (mConfigSmmCodeAccessCheckLock);
+
+ //
+ // Get the BSP ApicId.
+ //
+ mBspApicId = GetApicId ();
+
+ //
+ // Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) for SMM init
+ //
+ SendSmiIpi (mBspApicId);
+ SendSmiIpiAllExcludingSelf ();
+
+ //
+ // Wait for all processors to finish its 1st SMI
+ //
+ for (Index = 0; Index < mNumberOfCpus; Index++) {
+ while (!(BOOLEAN)mSmmInitialized[Index]) {
+ }
+ }
+
+ PERF_FUNCTION_END ();
+}
+
+/**
+ Function to compare 2 SMM_BASE_HOB_DATA pointer based on ProcessorIndex.
+
+ @param[in] Buffer1 pointer to SMM_BASE_HOB_DATA poiner to compare
+ @param[in] Buffer2 pointer to second SMM_BASE_HOB_DATA pointer to compare
+
+ @retval 0 Buffer1 equal to Buffer2
+ @retval <0 Buffer1 is less than Buffer2
+ @retval >0 Buffer1 is greater than Buffer2
+**/
+INTN
+EFIAPI
+SmBaseHobCompare (
+ IN CONST VOID *Buffer1,
+ IN CONST VOID *Buffer2
+ )
+{
+ if ((*(SMM_BASE_HOB_DATA **)Buffer1)->ProcessorIndex > (*(SMM_BASE_HOB_DATA **)Buffer2)->ProcessorIndex) {
+ return 1;
+ } else if ((*(SMM_BASE_HOB_DATA **)Buffer1)->ProcessorIndex < (*(SMM_BASE_HOB_DATA **)Buffer2)->ProcessorIndex) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ Extract SmBase for all CPU from SmmBase HOB.
+
+ @param[in] MaxNumberOfCpus Max NumberOfCpus.
+
+ @param[out] AllocatedSmBaseBuffer Pointer to SmBase Buffer allocated
+ by this function. Only set if the
+ function returns EFI_SUCCESS.
+
+ @retval EFI_SUCCESS SmBase Buffer output successfully.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+ @retval EFI_NOT_FOUND gSmmBaseHobGuid was never created.
+**/
+STATIC
+EFI_STATUS
+GetSmBase (
+ IN UINTN MaxNumberOfCpus,
+ OUT UINTN **AllocatedSmBaseBuffer
+ )
+{
+ UINTN HobCount;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ SMM_BASE_HOB_DATA *SmmBaseHobData;
+ UINTN NumberOfProcessors;
+ SMM_BASE_HOB_DATA **SmBaseHobs;
+ UINTN *SmBaseBuffer;
+ UINTN HobIndex;
+ UINTN SortBuffer;
+ UINTN ProcessorIndex;
+ UINT64 PrevProcessorIndex;
+ EFI_HOB_GUID_TYPE *FirstSmmBaseGuidHob;
+
+ SmmBaseHobData = NULL;
+ HobIndex = 0;
+ ProcessorIndex = 0;
+ HobCount = 0;
+ NumberOfProcessors = 0;
+
+ FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);
+ if (FirstSmmBaseGuidHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidHob = FirstSmmBaseGuidHob;
+ while (GuidHob != NULL) {
+ HobCount++;
+ SmmBaseHobData = GET_GUID_HOB_DATA (GuidHob);
+ NumberOfProcessors += SmmBaseHobData->NumberOfProcessors;
+
+ if (NumberOfProcessors >= MaxNumberOfCpus) {
+ break;
+ }
+
+ GuidHob = GetNextGuidHob (&gSmmBaseHobGuid, GET_NEXT_HOB (GuidHob));
+ }
+
+ ASSERT (NumberOfProcessors == MaxNumberOfCpus);
+ if (NumberOfProcessors != MaxNumberOfCpus) {
+ CpuDeadLoop ();
+ }
+
+ SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) * HobCount);
+ if (SmBaseHobs == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Record each SmmBaseHob pointer in the SmBaseHobs.
+ // The FirstSmmBaseGuidHob is to speed up this while-loop
+ // without needing to look for SmBaseHob from beginning.
+ //
+ GuidHob = FirstSmmBaseGuidHob;
+ while (HobIndex < HobCount) {
+ SmBaseHobs[HobIndex++] = GET_GUID_HOB_DATA (GuidHob);
+ GuidHob = GetNextGuidHob (&gSmmBaseHobGuid, GET_NEXT_HOB (GuidHob));
+ }
+
+ SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) * (MaxNumberOfCpus));
+ ASSERT (SmBaseBuffer != NULL);
+ if (SmBaseBuffer == NULL) {
+ FreePool (SmBaseHobs);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *), (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
+ PrevProcessorIndex = 0;
+ for (HobIndex = 0; HobIndex < HobCount; HobIndex++) {
+ //
+ // Make sure no overlap and no gap in the CPU range covered by each HOB
+ //
+ ASSERT (SmBaseHobs[HobIndex]->ProcessorIndex == PrevProcessorIndex);
+
+ //
+ // Cache each SmBase in order.
+ //
+ for (ProcessorIndex = 0; ProcessorIndex < SmBaseHobs[HobIndex]->NumberOfProcessors; ProcessorIndex++) {
+ SmBaseBuffer[PrevProcessorIndex + ProcessorIndex] = (UINTN)SmBaseHobs[HobIndex]->SmBase[ProcessorIndex];
+ }
+
+ PrevProcessorIndex += SmBaseHobs[HobIndex]->NumberOfProcessors;
+ }
+
+ FreePool (SmBaseHobs);
+ *AllocatedSmBaseBuffer = SmBaseBuffer;
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on ProcessorIndex.
+
+ @param[in] Buffer1 pointer to MP_INFORMATION2_HOB_DATA poiner to compare
+ @param[in] Buffer2 pointer to second MP_INFORMATION2_HOB_DATA pointer to compare
+
+ @retval 0 Buffer1 equal to Buffer2
+ @retval <0 Buffer1 is less than Buffer2
+ @retval >0 Buffer1 is greater than Buffer2
+**/
+INTN
+EFIAPI
+MpInformation2HobCompare (
+ IN CONST VOID *Buffer1,
+ IN CONST VOID *Buffer2
+ )
+{
+ if ((*(MP_INFORMATION2_HOB_DATA **)Buffer1)->ProcessorIndex > (*(MP_INFORMATION2_HOB_DATA **)Buffer2)->ProcessorIndex) {
+ return 1;
+ } else if ((*(MP_INFORMATION2_HOB_DATA **)Buffer1)->ProcessorIndex < (*(MP_INFORMATION2_HOB_DATA **)Buffer2)->ProcessorIndex) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from MpInformation2 HOB.
+
+ @param[out] NumberOfCpus Pointer to NumberOfCpus.
+ @param[out] MaxNumberOfCpus Pointer to MaxNumberOfCpus.
+
+ @retval ProcessorInfo Pointer to EFI_PROCESSOR_INFORMATION buffer.
+**/
+EFI_PROCESSOR_INFORMATION *
+GetMpInformation (
+ OUT UINTN *NumberOfCpus,
+ OUT UINTN *MaxNumberOfCpus
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ EFI_HOB_GUID_TYPE *FirstMpInfo2Hob;
+ MP_INFORMATION2_HOB_DATA *MpInformation2HobData;
+ UINTN HobCount;
+ UINTN HobIndex;
+ MP_INFORMATION2_HOB_DATA **MpInfo2Hobs;
+ UINTN SortBuffer;
+ UINTN ProcessorIndex;
+ UINT64 PrevProcessorIndex;
+ MP_INFORMATION2_ENTRY *MpInformation2Entry;
+ EFI_PROCESSOR_INFORMATION *ProcessorInfo;
+
+ GuidHob = NULL;
+ MpInformation2HobData = NULL;
+ FirstMpInfo2Hob = NULL;
+ MpInfo2Hobs = NULL;
+ HobIndex = 0;
+ HobCount = 0;
+
+ FirstMpInfo2Hob = GetFirstGuidHob (&gMpInformation2HobGuid);
+
+ if (mIsStandaloneMm) {
+ ASSERT (FirstMpInfo2Hob != NULL);
+ } else {
+ if (FirstMpInfo2Hob == NULL) {
+ DEBUG ((DEBUG_INFO, "%a: [INFO] gMpInformation2HobGuid HOB not found.\n", __func__));
+ return GetMpInformationFromMpServices (NumberOfCpus, MaxNumberOfCpus);
+ }
+ }
+
+ GuidHob = FirstMpInfo2Hob;
+ while (GuidHob != NULL) {
+ MpInformation2HobData = GET_GUID_HOB_DATA (GuidHob);
+
+ //
+ // This is the last MpInformationHob in the HOB list.
+ //
+ if (MpInformation2HobData->NumberOfProcessors == 0) {
+ ASSERT (HobCount != 0);
+ break;
+ }
+
+ HobCount++;
+ *NumberOfCpus += MpInformation2HobData->NumberOfProcessors;
+ GuidHob = GetNextGuidHob (&gMpInformation2HobGuid, GET_NEXT_HOB (GuidHob));
+ }
+
+ *MaxNumberOfCpus = *NumberOfCpus;
+
+ if (!mIsStandaloneMm) {
+ ASSERT (*NumberOfCpus <= GetSupportedMaxLogicalProcessorNumber ());
+
+ //
+ // If support CPU hot plug, we need to allocate resources for possibly hot-added processors
+ //
+ if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
+ *MaxNumberOfCpus = GetSupportedMaxLogicalProcessorNumber ();
+ }
+ }
+
+ MpInfo2Hobs = AllocatePool (sizeof (MP_INFORMATION2_HOB_DATA *) * HobCount);
+ ASSERT (MpInfo2Hobs != NULL);
+ if (MpInfo2Hobs == NULL) {
+ return NULL;
+ }
+
+ //
+ // Record each MpInformation2Hob pointer in the MpInfo2Hobs.
+ // The FirstMpInfo2Hob is to speed up this while-loop without
+ // needing to look for MpInfo2Hob from beginning.
+ //
+ GuidHob = FirstMpInfo2Hob;
+ while (HobIndex < HobCount) {
+ MpInfo2Hobs[HobIndex++] = GET_GUID_HOB_DATA (GuidHob);
+ GuidHob = GetNextGuidHob (&gMpInformation2HobGuid, GET_NEXT_HOB (GuidHob));
+ }
+
+ ProcessorInfo = (EFI_PROCESSOR_INFORMATION *)AllocatePool (sizeof (EFI_PROCESSOR_INFORMATION) * (*MaxNumberOfCpus));
+ ASSERT (ProcessorInfo != NULL);
+ if (ProcessorInfo == NULL) {
+ FreePool (MpInfo2Hobs);
+ return NULL;
+ }
+
+ QuickSort (MpInfo2Hobs, HobCount, sizeof (MP_INFORMATION2_HOB_DATA *), (BASE_SORT_COMPARE)MpInformation2HobCompare, &SortBuffer);
+ PrevProcessorIndex = 0;
+ for (HobIndex = 0; HobIndex < HobCount; HobIndex++) {
+ //
+ // Make sure no overlap and no gap in the CPU range covered by each HOB
+ //
+ ASSERT (MpInfo2Hobs[HobIndex]->ProcessorIndex == PrevProcessorIndex);
+
+ //
+ // Cache each EFI_PROCESSOR_INFORMATION in order.
+ //
+ for (ProcessorIndex = 0; ProcessorIndex < MpInfo2Hobs[HobIndex]->NumberOfProcessors; ProcessorIndex++) {
+ MpInformation2Entry = GET_MP_INFORMATION_ENTRY (MpInfo2Hobs[HobIndex], ProcessorIndex);
+ CopyMem (
+ &ProcessorInfo[PrevProcessorIndex + ProcessorIndex],
+ &MpInformation2Entry->ProcessorInfo,
+ sizeof (EFI_PROCESSOR_INFORMATION)
+ );
+ }
+
+ PrevProcessorIndex += MpInfo2Hobs[HobIndex]->NumberOfProcessors;
+ }
+
+ FreePool (MpInfo2Hobs);
+ return ProcessorInfo;
+}
+
+/**
+ The module Entry Point of the CPU SMM driver.
+
+ @retval EFI_SUCCESS The common entry point is executed successfully.
+ @retval Other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+PiSmmCpuEntryCommon (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN TileCodeSize;
+ UINTN TileDataSize;
+ UINTN TileSize;
+ UINT8 *Stacks;
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+ CPUID_EXTENDED_CPU_SIG_EDX ExtendedRegEdx;
+ UINTN FamilyId;
+ UINTN ModelId;
+ UINT32 Cr3;
+
+ PERF_FUNCTION_BEGIN ();
+
+ //
+ // Initialize address fixup
+ //
+ PiSmmCpuSmiEntryFixupAddress ();
+
+ //
+ // Initialize Debug Agent to support source level debug in SMM code
+ //
+ InitializeDebugAgent (DEBUG_AGENT_INIT_SMM, &mSmmDebugAgentSupport, NULL);
+
+ //
+ // Report the start of CPU SMM initialization.
+ //
+ REPORT_STATUS_CODE (
+ EFI_PROGRESS_CODE,
+ EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT
+ );
+
+ //
+ // Find out SMRR Base and SMRR Size
+ //
+ FindSmramInfo (&mCpuHotPlugData.SmrrBase, &mCpuHotPlugData.SmrrSize);
+
+ //
+ // Retrieve NumberOfProcessors, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from MpInformation2 HOB.
+ //
+ gSmmCpuPrivate->ProcessorInfo = GetMpInformation (&mNumberOfCpus, &mMaxNumberOfCpus);
+ ASSERT (gSmmCpuPrivate->ProcessorInfo != NULL);
+
+ //
+ // If support CPU hot plug, PcdCpuSmmEnableBspElection should be set to TRUE.
+ // A constant BSP index makes no sense because it may be hot removed.
+ //
+ DEBUG_CODE_BEGIN ();
+ if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
+ ASSERT (FeaturePcdGet (PcdCpuSmmEnableBspElection));
+ }
+
+ DEBUG_CODE_END ();
+
+ //
+ // Save the PcdCpuSmmCodeAccessCheckEnable value into a global variable.
+ //
+ mSmmCodeAccessCheckEnable = PcdGetBool (PcdCpuSmmCodeAccessCheckEnable);
+ DEBUG ((DEBUG_INFO, "PcdCpuSmmCodeAccessCheckEnable = %d\n", mSmmCodeAccessCheckEnable));
+
+ gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus = mMaxNumberOfCpus;
+
+ PERF_CODE (
+ InitializeMpPerf (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus);
+ );
+
+ //
+ // The CPU save state and code for the SMI entry point are tiled within an SMRAM
+ // allocated buffer. The minimum size of this buffer for a uniprocessor system
+ // is 32 KB, because the entry point is SMBASE + 32KB, and CPU save state area
+ // just below SMBASE + 64KB. If more than one CPU is present in the platform,
+ // then the SMI entry point and the CPU save state areas can be tiles to minimize
+ // the total amount SMRAM required for all the CPUs. The tile size can be computed
+ // by adding the // CPU save state size, any extra CPU specific context, and
+ // the size of code that must be placed at the SMI entry point to transfer
+ // control to a C function in the native SMM execution mode. This size is
+ // rounded up to the nearest power of 2 to give the tile size for a each CPU.
+ // The total amount of memory required is the maximum number of CPUs that
+ // platform supports times the tile size. The picture below shows the tiling,
+ // where m is the number of tiles that fit in 32KB.
+ //
+ // +-----------------------------+ <-- 2^n offset from Base of allocated buffer
+ // | CPU m+1 Save State |
+ // +-----------------------------+
+ // | CPU m+1 Extra Data |
+ // +-----------------------------+
+ // | Padding |
+ // +-----------------------------+
+ // | CPU 2m SMI Entry |
+ // +#############################+ <-- Base of allocated buffer + 64 KB
+ // | CPU m-1 Save State |
+ // +-----------------------------+
+ // | CPU m-1 Extra Data |
+ // +-----------------------------+
+ // | Padding |
+ // +-----------------------------+
+ // | CPU 2m-1 SMI Entry |
+ // +=============================+ <-- 2^n offset from Base of allocated buffer
+ // | . . . . . . . . . . . . |
+ // +=============================+ <-- 2^n offset from Base of allocated buffer
+ // | CPU 2 Save State |
+ // +-----------------------------+
+ // | CPU 2 Extra Data |
+ // +-----------------------------+
+ // | Padding |
+ // +-----------------------------+
+ // | CPU m+1 SMI Entry |
+ // +=============================+ <-- Base of allocated buffer + 32 KB
+ // | CPU 1 Save State |
+ // +-----------------------------+
+ // | CPU 1 Extra Data |
+ // +-----------------------------+
+ // | Padding |
+ // +-----------------------------+
+ // | CPU m SMI Entry |
+ // +#############################+ <-- Base of allocated buffer + 32 KB == CPU 0 SMBASE + 64 KB
+ // | CPU 0 Save State |
+ // +-----------------------------+
+ // | CPU 0 Extra Data |
+ // +-----------------------------+
+ // | Padding |
+ // +-----------------------------+
+ // | CPU m-1 SMI Entry |
+ // +=============================+ <-- 2^n offset from Base of allocated buffer
+ // | . . . . . . . . . . . . |
+ // +=============================+ <-- 2^n offset from Base of allocated buffer
+ // | Padding |
+ // +-----------------------------+
+ // | CPU 1 SMI Entry |
+ // +=============================+ <-- 2^n offset from Base of allocated buffer
+ // | Padding |
+ // +-----------------------------+
+ // | CPU 0 SMI Entry |
+ // +#############################+ <-- Base of allocated buffer == CPU 0 SMBASE + 32 KB
+ //
+
+ //
+ // Retrieve CPU Family
+ //
+ AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL);
+ FamilyId = (RegEax >> 8) & 0xf;
+ ModelId = (RegEax >> 4) & 0xf;
+ if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
+ ModelId = ModelId | ((RegEax >> 12) & 0xf0);
+ }
+
+ RegEdx = 0;
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
+ AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
+ }
+
+ //
+ // Determine the mode of the CPU at the time an SMI occurs
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ // Volume 3C, Section 34.4.1.1
+ //
+ mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT;
+ if ((RegEdx & BIT29) != 0) {
+ mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;
+ }
+
+ if (FamilyId == 0x06) {
+ if ((ModelId == 0x17) || (ModelId == 0x0f) || (ModelId == 0x1c)) {
+ mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "PcdControlFlowEnforcementPropertyMask = %d\n", PcdGet32 (PcdControlFlowEnforcementPropertyMask)));
+ if (PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) {
+ AsmCpuid (CPUID_SIGNATURE, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS) {
+ AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, NULL, NULL, &RegEcx, &RegEdx);
+ DEBUG ((DEBUG_INFO, "CPUID[7/0] ECX - 0x%08x\n", RegEcx));
+ DEBUG ((DEBUG_INFO, " CET_SS - 0x%08x\n", RegEcx & CPUID_CET_SS));
+ DEBUG ((DEBUG_INFO, " CET_IBT - 0x%08x\n", RegEdx & CPUID_CET_IBT));
+ if ((RegEcx & CPUID_CET_SS) == 0) {
+ mCetSupported = FALSE;
+ PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1);
+ }
+
+ if (mCetSupported) {
+ AsmCpuidEx (CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF, NULL, &RegEbx, &RegEcx, NULL);
+ DEBUG ((DEBUG_INFO, "CPUID[D/1] EBX - 0x%08x, ECX - 0x%08x\n", RegEbx, RegEcx));
+ AsmCpuidEx (CPUID_EXTENDED_STATE, 11, &RegEax, NULL, &RegEcx, NULL);
+ DEBUG ((DEBUG_INFO, "CPUID[D/11] EAX - 0x%08x, ECX - 0x%08x\n", RegEax, RegEcx));
+ AsmCpuidEx (CPUID_EXTENDED_STATE, 12, &RegEax, NULL, &RegEcx, NULL);
+ DEBUG ((DEBUG_INFO, "CPUID[D/12] EAX - 0x%08x, ECX - 0x%08x\n", RegEax, RegEcx));
+ }
+ } else {
+ mCetSupported = FALSE;
+ PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1);
+ }
+ } else {
+ mCetSupported = FALSE;
+ PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1);
+ }
+
+ //
+ // Check XD supported or not.
+ //
+ RegEax = 0;
+ ExtendedRegEdx.Uint32 = 0;
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+ if (RegEax <= CPUID_EXTENDED_FUNCTION) {
+ //
+ // Extended CPUID functions are not supported on this processor.
+ //
+ mXdSupported = FALSE;
+ PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1);
+ }
+
+ AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &ExtendedRegEdx.Uint32);
+ if (ExtendedRegEdx.Bits.NX == 0) {
+ //
+ // Execute Disable Bit feature is not supported on this processor.
+ //
+ mXdSupported = FALSE;
+ PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1);
+ }
+
+ if (StandardSignatureIsAuthenticAMD ()) {
+ //
+ // AMD processors do not support MSR_IA32_MISC_ENABLE
+ //
+ PatchInstructionX86 (gPatchMsrIa32MiscEnableSupported, FALSE, 1);
+ }
+
+ //
+ // Compute tile size of buffer required to hold the CPU SMRAM Save State Map, extra CPU
+ // specific context start starts at SMBASE + SMM_PSD_OFFSET, and the SMI entry point.
+ // This size is rounded up to nearest power of 2.
+ //
+ TileCodeSize = GetSmiHandlerSize ();
+ TileCodeSize = ALIGN_VALUE (TileCodeSize, SIZE_4KB);
+ TileDataSize = (SMRAM_SAVE_STATE_MAP_OFFSET - SMM_PSD_OFFSET) + sizeof (SMRAM_SAVE_STATE_MAP);
+ TileDataSize = ALIGN_VALUE (TileDataSize, SIZE_4KB);
+ TileSize = TileDataSize + TileCodeSize - 1;
+ TileSize = 2 * GetPowerOfTwo32 ((UINT32)TileSize);
+ DEBUG ((DEBUG_INFO, "SMRAM TileSize = 0x%08x (0x%08x, 0x%08x)\n", TileSize, TileCodeSize, TileDataSize));
+
+ //
+ // If the TileSize is larger than space available for the SMI Handler of
+ // CPU[i], the extra CPU specific context of CPU[i+1], and the SMRAM Save
+ // State Map of CPU[i+1], then ASSERT(). If this ASSERT() is triggered, then
+ // the SMI Handler size must be reduced or the size of the extra CPU specific
+ // context must be reduced.
+ //
+ ASSERT (TileSize <= (SMRAM_SAVE_STATE_MAP_OFFSET + sizeof (SMRAM_SAVE_STATE_MAP) - SMM_HANDLER_OFFSET));
+
+ //
+ // Check whether the Required TileSize is enough.
+ //
+ if (TileSize > SIZE_8KB) {
+ DEBUG ((DEBUG_ERROR, "The Range of Smbase in SMRAM is not enough -- Required TileSize = 0x%08x, Actual TileSize = 0x%08x\n", TileSize, SIZE_8KB));
+ FreePool (gSmmCpuPrivate->ProcessorInfo);
+ CpuDeadLoop ();
+ return RETURN_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // Retrieve the allocated SmmBase from gSmmBaseHobGuid. If found,
+ // means the SmBase relocation has been done.
+ //
+ mCpuHotPlugData.SmBase = NULL;
+ Status = GetSmBase (mMaxNumberOfCpus, &mCpuHotPlugData.SmBase);
+ ASSERT (!EFI_ERROR (Status));
+ if (EFI_ERROR (Status)) {
+ CpuDeadLoop ();
+ }
+
+ //
+ // ASSERT SmBase has been relocated.
+ //
+ ASSERT (mCpuHotPlugData.SmBase != NULL);
+
+ //
+ // Allocate buffer for pointers to array in SMM_CPU_PRIVATE_DATA.
+ //
+ gSmmCpuPrivate->Operation = (SMM_CPU_OPERATION *)AllocatePool (sizeof (SMM_CPU_OPERATION) * mMaxNumberOfCpus);
+ ASSERT (gSmmCpuPrivate->Operation != NULL);
+
+ gSmmCpuPrivate->CpuSaveStateSize = (UINTN *)AllocatePool (sizeof (UINTN) * mMaxNumberOfCpus);
+ ASSERT (gSmmCpuPrivate->CpuSaveStateSize != NULL);
+
+ gSmmCpuPrivate->CpuSaveState = (VOID **)AllocatePool (sizeof (VOID *) * mMaxNumberOfCpus);
+ ASSERT (gSmmCpuPrivate->CpuSaveState != NULL);
+
+ mSmmCpuPrivateData.SmmCoreEntryContext.CpuSaveStateSize = gSmmCpuPrivate->CpuSaveStateSize;
+ mSmmCpuPrivateData.SmmCoreEntryContext.CpuSaveState = gSmmCpuPrivate->CpuSaveState;
+
+ //
+ // Allocate buffer for pointers to array in CPU_HOT_PLUG_DATA.
+ //
+ mCpuHotPlugData.ApicId = (UINT64 *)AllocatePool (sizeof (UINT64) * mMaxNumberOfCpus);
+ ASSERT (mCpuHotPlugData.ApicId != NULL);
+ mCpuHotPlugData.ArrayLength = (UINT32)mMaxNumberOfCpus;
+
+ //
+ // Retrieve APIC ID of each enabled processor from the MP Services protocol.
+ // Also compute the SMBASE address, CPU Save State address, and CPU Save state
+ // size for each CPU in the platform
+ //
+ for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
+ gSmmCpuPrivate->CpuSaveStateSize[Index] = sizeof (SMRAM_SAVE_STATE_MAP);
+ gSmmCpuPrivate->CpuSaveState[Index] = (VOID *)(mCpuHotPlugData.SmBase[Index] + SMRAM_SAVE_STATE_MAP_OFFSET);
+ gSmmCpuPrivate->Operation[Index] = SmmCpuNone;
+
+ if (Index < mNumberOfCpus) {
+ mCpuHotPlugData.ApicId[Index] = gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId;
+
+ DEBUG ((
+ DEBUG_INFO,
+ "CPU[%03x] APIC ID=%04x SMBASE=%08x SaveState=%08x Size=%08x\n",
+ Index,
+ (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId,
+ mCpuHotPlugData.SmBase[Index],
+ gSmmCpuPrivate->CpuSaveState[Index],
+ gSmmCpuPrivate->CpuSaveStateSize[Index]
+ ));
+ } else {
+ gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId = INVALID_APIC_ID;
+ mCpuHotPlugData.ApicId[Index] = INVALID_APIC_ID;
+ }
+ }
+
+ //
+ // Allocate SMI stacks for all processors.
+ //
+ mSmmStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize)));
+ if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
+ //
+ // SMM Stack Guard Enabled
+ // 2 more pages is allocated for each processor, one is guard page and the other is known good stack.
+ //
+ // +--------------------------------------------------+-----+--------------------------------------------------+
+ // | Known Good Stack | Guard Page | SMM Stack | ... | Known Good Stack | Guard Page | SMM Stack |
+ // +--------------------------------------------------+-----+--------------------------------------------------+
+ // | 4K | 4K PcdCpuSmmStackSize| | 4K | 4K PcdCpuSmmStackSize|
+ // |<---------------- mSmmStackSize ----------------->| |<---------------- mSmmStackSize ----------------->|
+ // | | | |
+ // |<------------------ Processor 0 ----------------->| |<------------------ Processor n ----------------->|
+ //
+ mSmmStackSize += EFI_PAGES_TO_SIZE (2);
+ }
+
+ mSmmShadowStackSize = 0;
+ if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {
+ mSmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize)));
+
+ if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
+ //
+ // SMM Stack Guard Enabled
+ // Append Shadow Stack after normal stack
+ // 2 more pages is allocated for each processor, one is guard page and the other is known good shadow stack.
+ //
+ // |= Stacks
+ // +--------------------------------------------------+---------------------------------------------------------------+
+ // | Known Good Stack | Guard Page | SMM Stack | Known Good Shadow Stack | Guard Page | SMM Shadow Stack |
+ // +--------------------------------------------------+---------------------------------------------------------------+
+ // | 4K | 4K |PcdCpuSmmStackSize| 4K | 4K |PcdCpuSmmShadowStackSize|
+ // |<---------------- mSmmStackSize ----------------->|<--------------------- mSmmShadowStackSize ------------------->|
+ // | |
+ // |<-------------------------------------------- Processor N ------------------------------------------------------->|
+ //
+ mSmmShadowStackSize += EFI_PAGES_TO_SIZE (2);
+ } else {
+ //
+ // SMM Stack Guard Disabled (Known Good Stack is still required for potential stack switch.)
+ // Append Shadow Stack after normal stack with 1 more page as known good shadow stack.
+ // 1 more pages is allocated for each processor, it is known good stack.
+ //
+ //
+ // |= Stacks
+ // +-------------------------------------+--------------------------------------------------+
+ // | Known Good Stack | SMM Stack | Known Good Shadow Stack | SMM Shadow Stack |
+ // +-------------------------------------+--------------------------------------------------+
+ // | 4K |PcdCpuSmmStackSize| 4K |PcdCpuSmmShadowStackSize|
+ // |<---------- mSmmStackSize ---------->|<--------------- mSmmShadowStackSize ------------>|
+ // | |
+ // |<-------------------------------- Processor N ----------------------------------------->|
+ //
+ mSmmShadowStackSize += EFI_PAGES_TO_SIZE (1);
+ mSmmStackSize += EFI_PAGES_TO_SIZE (1);
+ }
+ }
+
+ Stacks = (UINT8 *)AllocatePages (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (EFI_SIZE_TO_PAGES (mSmmStackSize + mSmmShadowStackSize)));
+ ASSERT (Stacks != NULL);
+ mSmmStackArrayBase = (UINTN)Stacks;
+ mSmmStackArrayEnd = mSmmStackArrayBase + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (mSmmStackSize + mSmmShadowStackSize) - 1;
+
+ DEBUG ((DEBUG_INFO, "Stacks - 0x%x\n", Stacks));
+ DEBUG ((DEBUG_INFO, "mSmmStackSize - 0x%x\n", mSmmStackSize));
+ DEBUG ((DEBUG_INFO, "PcdCpuSmmStackGuard - 0x%x\n", FeaturePcdGet (PcdCpuSmmStackGuard)));
+ if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {
+ DEBUG ((DEBUG_INFO, "mSmmShadowStackSize - 0x%x\n", mSmmShadowStackSize));
+ }
+
+ //
+ // Initialize IDT
+ //
+ InitializeSmmIdt ();
+
+ //
+ // SMM Time initialization
+ //
+ InitializeSmmTimer ();
+
+ //
+ // Initialize mSmmProfileEnabled
+ //
+ mSmmProfileEnabled = IsSmmProfileEnabled ();
+
+ //
+ // Initialize MP globals
+ //
+ Cr3 = InitializeMpServiceData (Stacks, mSmmStackSize, mSmmShadowStackSize);
+
+ if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {
+ for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {
+ SetShadowStack (
+ Cr3,
+ (EFI_PHYSICAL_ADDRESS)(UINTN)Stacks + mSmmStackSize + (mSmmStackSize + mSmmShadowStackSize) * Index,
+ mSmmShadowStackSize
+ );
+ if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
+ ConvertMemoryPageAttributes (
+ Cr3,
+ mPagingMode,
+ (EFI_PHYSICAL_ADDRESS)(UINTN)Stacks + mSmmStackSize + EFI_PAGES_TO_SIZE (1) + (mSmmStackSize + mSmmShadowStackSize) * Index,
+ EFI_PAGES_TO_SIZE (1),
+ EFI_MEMORY_RP,
+ TRUE,
+ NULL
+ );
+ }
+ }
+ }
+
+ //
+ // For relocated SMBASE, some MSRs & CSRs are still required to be configured in SMM Mode for SMM Initialization.
+ // Those MSRs & CSRs must be configured before normal SMI sources happen.
+ // So, here is to issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init.
+ //
+ ExecuteFirstSmiInit ();
+
+ //
+ // Call hook for BSP to perform extra actions in normal mode after all
+ // SMM base addresses have been relocated on all CPUs
+ //
+ SmmCpuFeaturesSmmRelocationComplete ();
+
+ DEBUG ((DEBUG_INFO, "mXdSupported - 0x%x\n", mXdSupported));
+
+ //
+ // Fill in SMM Reserved Regions
+ //
+ gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedStart = 0;
+ gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedSize = 0;
+
+ //
+ // Install the SMM CPU Protocol into SMM protocol database
+ //
+ Status = gMmst->MmInstallProtocolInterface (
+ &mSmmCpuHandle,
+ &gEfiSmmCpuProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mSmmCpu
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install the SMM Memory Attribute Protocol into SMM protocol database
+ //
+ Status = gMmst->MmInstallProtocolInterface (
+ &mSmmCpuHandle,
+ &gEdkiiSmmMemoryAttributeProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mSmmMemoryAttribute
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize global buffer for MM MP.
+ //
+ InitializeDataForMmMp ();
+
+ //
+ // Initialize Package First Thread Index Info.
+ //
+ InitPackageFirstThreadIndexInfo ();
+
+ //
+ // Install the SMM Mp Protocol into SMM protocol database
+ //
+ Status = gMmst->MmInstallProtocolInterface (
+ &mSmmCpuHandle,
+ &gEfiMmMpProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mSmmMp
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize SMM CPU Services Support
+ //
+ Status = InitializeSmmCpuServices (mSmmCpuHandle);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize SMM Profile feature
+ //
+ InitSmmProfile (Cr3);
+
+ GetAcpiS3EnableFlag ();
+ InitSmmS3ResumeState ();
+
+ DEBUG ((DEBUG_INFO, "SMM CPU Module exit from SMRAM with EFI_SUCCESS\n"));
+
+ PERF_FUNCTION_END ();
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to compare 2 EFI_SMRAM_DESCRIPTOR based on CpuStart.
+
+ @param[in] Buffer1 pointer to Device Path poiner to compare
+ @param[in] Buffer2 pointer to second DevicePath pointer to compare
+
+ @retval 0 Buffer1 equal to Buffer2
+ @retval <0 Buffer1 is less than Buffer2
+ @retval >0 Buffer1 is greater than Buffer2
+**/
+INTN
+EFIAPI
+CpuSmramRangeCompare (
+ IN CONST VOID *Buffer1,
+ IN CONST VOID *Buffer2
+ )
+{
+ if (((EFI_SMRAM_DESCRIPTOR *)Buffer1)->CpuStart > ((EFI_SMRAM_DESCRIPTOR *)Buffer2)->CpuStart) {
+ return 1;
+ } else if (((EFI_SMRAM_DESCRIPTOR *)Buffer1)->CpuStart < ((EFI_SMRAM_DESCRIPTOR *)Buffer2)->CpuStart) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ Find out SMRAM information including SMRR base and SMRR size.
+
+ @param SmrrBase SMRR base
+ @param SmrrSize SMRR size
+
+**/
+VOID
+FindSmramInfo (
+ OUT UINT32 *SmrrBase,
+ OUT UINT32 *SmrrSize
+ )
+{
+ VOID *GuidHob;
+ EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock;
+ EFI_SMRAM_DESCRIPTOR *CurrentSmramRange;
+ UINTN Index;
+ UINT64 MaxSize;
+ BOOLEAN Found;
+ EFI_SMRAM_DESCRIPTOR SmramDescriptor;
+
+ ASSERT (SmrrBase != NULL && SmrrSize != NULL);
+
+ //
+ // Get SMRAM information
+ //
+ GuidHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);
+ ASSERT (GuidHob != NULL);
+ DescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)GET_GUID_HOB_DATA (GuidHob);
+ mSmmCpuSmramRangeCount = DescriptorBlock->NumberOfSmmReservedRegions;
+ mSmmCpuSmramRanges = DescriptorBlock->Descriptor;
+
+ //
+ // Sort the mSmmCpuSmramRanges
+ //
+ QuickSort (mSmmCpuSmramRanges, mSmmCpuSmramRangeCount, sizeof (EFI_SMRAM_DESCRIPTOR), (BASE_SORT_COMPARE)CpuSmramRangeCompare, &SmramDescriptor);
+
+ //
+ // Find the largest SMRAM range between 1MB and 4GB that is at least 256K - 4K in size
+ //
+ CurrentSmramRange = NULL;
+ for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < mSmmCpuSmramRangeCount; Index++) {
+ //
+ // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization
+ //
+ if ((mSmmCpuSmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
+ continue;
+ }
+
+ if (mSmmCpuSmramRanges[Index].CpuStart >= BASE_1MB) {
+ if ((mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize) <= SMRR_MAX_ADDRESS) {
+ if (mSmmCpuSmramRanges[Index].PhysicalSize >= MaxSize) {
+ MaxSize = mSmmCpuSmramRanges[Index].PhysicalSize;
+ CurrentSmramRange = &mSmmCpuSmramRanges[Index];
+ }
+ }
+ }
+ }
+
+ ASSERT (CurrentSmramRange != NULL);
+
+ *SmrrBase = (UINT32)CurrentSmramRange->CpuStart;
+ *SmrrSize = (UINT32)CurrentSmramRange->PhysicalSize;
+
+ do {
+ Found = FALSE;
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
+ if ((mSmmCpuSmramRanges[Index].CpuStart < *SmrrBase) &&
+ (*SmrrBase == (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize)))
+ {
+ *SmrrBase = (UINT32)mSmmCpuSmramRanges[Index].CpuStart;
+ *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize);
+ Found = TRUE;
+ } else if (((*SmrrBase + *SmrrSize) == mSmmCpuSmramRanges[Index].CpuStart) && (mSmmCpuSmramRanges[Index].PhysicalSize > 0)) {
+ *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize);
+ Found = TRUE;
+ }
+ }
+ } while (Found);
+
+ DEBUG ((DEBUG_INFO, "%a: SMRR Base = 0x%x, SMRR Size = 0x%x\n", __func__, *SmrrBase, *SmrrSize));
+}
+
+/**
+Configure SMM Code Access Check feature on an AP.
+SMM Feature Control MSR will be locked after configuration.
+
+@param[in,out] Buffer Pointer to private data buffer.
+**/
+VOID
+EFIAPI
+ConfigSmmCodeAccessCheckOnCurrentProcessor (
+ IN OUT VOID *Buffer
+ )
+{
+ UINTN CpuIndex;
+ UINT64 SmmFeatureControlMsr;
+ UINT64 NewSmmFeatureControlMsr;
+
+ //
+ // Retrieve the CPU Index from the context passed in
+ //
+ CpuIndex = *(UINTN *)Buffer;
+
+ //
+ // Get the current SMM Feature Control MSR value
+ //
+ SmmFeatureControlMsr = SmmCpuFeaturesGetSmmRegister (CpuIndex, SmmRegFeatureControl);
+
+ //
+ // Compute the new SMM Feature Control MSR value
+ //
+ NewSmmFeatureControlMsr = SmmFeatureControlMsr;
+ if (mSmmCodeAccessCheckEnable) {
+ NewSmmFeatureControlMsr |= SMM_CODE_CHK_EN_BIT;
+ if (FeaturePcdGet (PcdCpuSmmFeatureControlMsrLock)) {
+ NewSmmFeatureControlMsr |= SMM_FEATURE_CONTROL_LOCK_BIT;
+ }
+ }
+
+ //
+ // Only set the SMM Feature Control MSR value if the new value is different than the current value
+ //
+ if (NewSmmFeatureControlMsr != SmmFeatureControlMsr) {
+ SmmCpuFeaturesSetSmmRegister (CpuIndex, SmmRegFeatureControl, NewSmmFeatureControlMsr);
+ }
+
+ //
+ // Release the spin lock user to serialize the updates to the SMM Feature Control MSR
+ //
+ ReleaseSpinLock (mConfigSmmCodeAccessCheckLock);
+}
+
+/**
+Configure SMM Code Access Check feature for all processors.
+SMM Feature Control MSR will be locked after configuration.
+**/
+VOID
+ConfigSmmCodeAccessCheck (
+ VOID
+ )
+{
+ UINTN Index;
+ EFI_STATUS Status;
+
+ PERF_FUNCTION_BEGIN ();
+
+ //
+ // Check to see if the Feature Control MSR is supported on this CPU
+ //
+ Index = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu;
+
+ //
+ // Acquire Config SMM Code Access Check spin lock. The BSP will release the
+ // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor().
+ //
+ AcquireSpinLock (mConfigSmmCodeAccessCheckLock);
+
+ //
+ // Enable SMM Code Access Check feature on the BSP.
+ //
+ ConfigSmmCodeAccessCheckOnCurrentProcessor (&Index);
+
+ //
+ // Enable SMM Code Access Check feature for the APs.
+ //
+ for (Index = 0; Index < gMmst->NumberOfCpus; Index++) {
+ if (Index != gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) {
+ if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID) {
+ //
+ // If this processor does not exist
+ //
+ continue;
+ }
+
+ //
+ // Acquire Config SMM Code Access Check spin lock. The AP will release the
+ // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor().
+ //
+ AcquireSpinLock (mConfigSmmCodeAccessCheckLock);
+
+ //
+ // Call SmmStartupThisAp() to enable SMM Code Access Check on an AP.
+ //
+ Status = gMmst->MmStartupThisAp (ConfigSmmCodeAccessCheckOnCurrentProcessor, Index, &Index);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Wait for the AP to release the Config SMM Code Access Check spin lock.
+ //
+ while (!AcquireSpinLockOrFail (mConfigSmmCodeAccessCheckLock)) {
+ CpuPause ();
+ }
+
+ //
+ // Release the Config SMM Code Access Check spin lock.
+ //
+ ReleaseSpinLock (mConfigSmmCodeAccessCheckLock);
+ }
+ }
+
+ PERF_FUNCTION_END ();
+}
+
+/**
+ Allocate pages for code.
+
+ @param[in] Pages Number of pages to be allocated.
+
+ @return Allocated memory.
+**/
+VOID *
+AllocateCodePages (
+ IN UINTN Pages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Memory;
+
+ if (Pages == 0) {
+ return NULL;
+ }
+
+ Status = gMmst->MmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, Pages, &Memory);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ return (VOID *)(UINTN)Memory;
+}
+
+/**
+ Perform the pre tasks.
+
+**/
+VOID
+PerformPreTasks (
+ VOID
+ )
+{
+ RestoreSmmConfigurationInS3 ();
+}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h
index 8409891..bc08f03 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h
@@ -16,17 +16,21 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Protocol/SmmConfiguration.h>
#include <Protocol/SmmCpu.h>
-#include <Protocol/SmmAccess2.h>
#include <Protocol/SmmReadyToLock.h>
#include <Protocol/SmmCpuService.h>
#include <Protocol/SmmMemoryAttribute.h>
#include <Protocol/MmMp.h>
+#include <Protocol/SmmVariable.h>
#include <Guid/AcpiS3Context.h>
#include <Guid/MemoryAttributesTable.h>
#include <Guid/PiSmmMemoryAttributesTable.h>
+#include <Guid/SmramMemoryReserve.h>
#include <Guid/SmmBaseHob.h>
#include <Guid/MpInformation2.h>
+#include <Guid/MmProfileData.h>
+#include <Guid/MmAcpiS3Enable.h>
+#include <Guid/MmCpuSyncConfig.h>
#include <Library/BaseLib.h>
#include <Library/IoLib.h>
@@ -37,10 +41,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/PcdLib.h>
#include <Library/MtrrLib.h>
#include <Library/SmmCpuPlatformHookLib.h>
-#include <Library/SmmServicesTableLib.h>
+#include <Library/MmServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/UefiLib.h>
#include <Library/HobLib.h>
@@ -251,6 +253,8 @@ typedef struct {
LIST_ENTRY *FirstFreeToken;
} SMM_CPU_PRIVATE_DATA;
+extern const BOOLEAN mIsStandaloneMm;
+
extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate;
extern CPU_HOT_PLUG_DATA mCpuHotPlugData;
extern UINTN mMaxNumberOfCpus;
@@ -266,6 +270,8 @@ extern UINTN mSmmShadowStackSize;
///
extern UINT8 mSmmSaveStateRegisterLma;
+extern BOOLEAN mAcpiS3Enable;
+
#define PAGE_TABLE_POOL_ALIGNMENT BASE_128KB
#define PAGE_TABLE_POOL_UNIT_SIZE BASE_128KB
#define PAGE_TABLE_POOL_UNIT_PAGES EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE)
@@ -393,28 +399,22 @@ typedef struct {
EFI_STATUS *Status;
} SMM_CPU_DATA_BLOCK;
-typedef enum {
- SmmCpuSyncModeTradition,
- SmmCpuSyncModeRelaxedAp,
- SmmCpuSyncModeMax
-} SMM_CPU_SYNC_MODE;
-
typedef struct {
//
// Pointer to an array. The array should be located immediately after this structure
// so that UC cache-ability can be set together.
//
- SMM_CPU_DATA_BLOCK *CpuData;
- volatile UINT32 BspIndex;
- volatile BOOLEAN *InsideSmm;
- volatile BOOLEAN *AllCpusInSync;
- volatile SMM_CPU_SYNC_MODE EffectiveSyncMode;
- volatile BOOLEAN SwitchBsp;
- volatile BOOLEAN *CandidateBsp;
- volatile BOOLEAN AllApArrivedWithException;
- EFI_AP_PROCEDURE StartupProcedure;
- VOID *StartupProcArgs;
- SMM_CPU_SYNC_CONTEXT *SyncContext;
+ SMM_CPU_DATA_BLOCK *CpuData;
+ volatile UINT32 BspIndex;
+ volatile BOOLEAN *InsideSmm;
+ volatile BOOLEAN *AllCpusInSync;
+ volatile MM_CPU_SYNC_MODE EffectiveSyncMode;
+ volatile BOOLEAN SwitchBsp;
+ volatile BOOLEAN *CandidateBsp;
+ volatile BOOLEAN AllApArrivedWithException;
+ EFI_AP_PROCEDURE StartupProcedure;
+ VOID *StartupProcArgs;
+ SMM_CPU_SYNC_CONTEXT *SyncContext;
} SMM_DISPATCHER_MP_SYNC_DATA;
#define SMM_PSD_OFFSET 0xfb00
@@ -465,6 +465,7 @@ extern EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges;
extern UINTN mSmmCpuSmramRangeCount;
extern UINT8 mPhysicalAddressBits;
extern BOOLEAN mSmmDebugAgentSupport;
+extern BOOLEAN mSmmCodeAccessCheckEnable;
//
// Copy of the PcdPteMemoryEncryptionAddressOrMask
@@ -474,6 +475,21 @@ extern UINT64 mAddressEncMask;
extern UINT64 mTimeoutTicker;
extern UINT64 mTimeoutTicker2;
+typedef struct {
+ ///
+ /// Address of the first byte in the memory region.
+ ///
+ EFI_PHYSICAL_ADDRESS Base;
+ ///
+ /// Length in bytes of the memory region.
+ ///
+ UINT64 Length;
+ ///
+ /// Attributes of the memory region
+ ///
+ UINT64 Attribute;
+} MM_CPU_MEMORY_REGION;
+
/**
Create 4G PageTable in SMRAM.
@@ -756,6 +772,24 @@ SmmClearMemoryAttributes (
);
/**
+ Retrieves a pointer to the system configuration table from the SMM System Table
+ based on a specified GUID.
+
+ @param[in] TableGuid The pointer to table's GUID type.
+ @param[out] Table The pointer to the table associated with TableGuid in the EFI System Table.
+
+ @retval EFI_SUCCESS A configuration table matching TableGuid was found.
+ @retval EFI_NOT_FOUND A configuration table matching TableGuid could not be found.
+
+**/
+EFI_STATUS
+EFIAPI
+SmmGetSystemConfigurationTable (
+ IN EFI_GUID *TableGuid,
+ OUT VOID **Table
+ );
+
+/**
Initialize MP synchronization data.
**/
@@ -795,6 +829,18 @@ SmiPFHandler (
);
/**
+ Check SmmProfile is enabled or not.
+
+ @return TRUE SmmProfile is enabled.
+ FALSE SmmProfile is not enabled.
+
+**/
+BOOLEAN
+IsSmmProfileEnabled (
+ VOID
+ );
+
+/**
Perform the remaining tasks.
**/
@@ -824,6 +870,18 @@ InitMsrSpinLockByIndex (
);
/**
+Configure SMM Code Access Check feature on an AP.
+SMM Feature Control MSR will be locked after configuration.
+
+@param[in,out] Buffer Pointer to private data buffer.
+**/
+VOID
+EFIAPI
+ConfigSmmCodeAccessCheckOnCurrentProcessor (
+ IN OUT VOID *Buffer
+ );
+
+/**
Configure SMM Code Access Check feature for all processors.
SMM Feature Control MSR will be locked after configuration.
**/
@@ -895,18 +953,39 @@ DumpModuleInfoByIp (
/**
This function sets memory attribute according to MemoryAttributesTable.
+
+ @param MemoryAttributesTable A pointer to the buffer of SmmMemoryAttributesTable.
+
**/
VOID
SetMemMapAttributes (
- VOID
+ EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable
);
/**
- This function sets UEFI memory attribute according to UEFI memory map.
+ Get SmmProfileData.
+
+ @param[in, out] Size Return Size of SmmProfileData.
+
+ @return Address of SmmProfileData
+
**/
-VOID
-SetUefiMemMapAttributes (
- VOID
+EFI_PHYSICAL_ADDRESS
+GetSmmProfileData (
+ IN OUT UINT64 *Size
+ );
+
+/**
+ Return if the Address is the NonMmram logging Address.
+
+ @param[in] Address the address to be checked
+
+ @return TRUE The address is the NonMmram logging Address.
+ @return FALSE The address is not the NonMmram logging Address.
+**/
+BOOLEAN
+IsNonMmramLoggingAddress (
+ IN UINT64 Address
);
/**
@@ -923,6 +1002,47 @@ IsSmmCommBufferForbiddenAddress (
);
/**
+ Build extended protection MemoryRegion.
+
+ The caller is responsible for freeing MemoryRegion via FreePool().
+
+ @param[out] MemoryRegion Returned Non-Mmram Memory regions.
+ @param[out] MemoryRegionCount A pointer to the number of Memory regions.
+
+**/
+VOID
+CreateExtendedProtectionRange (
+ OUT MM_CPU_MEMORY_REGION **MemoryRegion,
+ OUT UINTN *MemoryRegionCount
+ );
+
+/**
+ Create the Non-Mmram Memory Region.
+
+ The caller is responsible for freeing MemoryRegion via FreePool().
+
+ @param[in] PhysicalAddressBits The bits of physical address to map.
+ @param[out] MemoryRegion Returned Non-Mmram Memory regions.
+ @param[out] MemoryRegionCount A pointer to the number of Memory regions.
+
+**/
+VOID
+CreateNonMmramMemMap (
+ IN UINT8 PhysicalAddressBits,
+ OUT MM_CPU_MEMORY_REGION **MemoryRegion,
+ OUT UINTN *MemoryRegionCount
+ );
+
+/**
+ This function updates UEFI memory attribute according to UEFI memory map.
+
+**/
+VOID
+UpdateUefiMemMapAttributes (
+ VOID
+ );
+
+/**
This function caches the UEFI memory map information.
**/
VOID
@@ -1045,12 +1165,10 @@ extern BOOLEAN mSmmS3Flag;
/**
Initialize SMM S3 resume state structure used during S3 Resume.
- @param[in] Cr3 The base address of the page tables to use in SMM.
-
**/
VOID
InitSmmS3ResumeState (
- IN UINT32 Cr3
+ VOID
);
/**
@@ -1063,6 +1181,22 @@ RestoreSmmConfigurationInS3 (
);
/**
+ Get SmmCpuSyncConfig data: RelaxedMode, SyncTimeout, SyncTimeout2.
+
+ @param[in,out] RelaxedMode It indicates if Relaxed CPU synchronization method or
+ traditional CPU synchronization method is used when processing an SMI.
+ @param[in,out] SyncTimeout It indicates the 1st BSP/AP synchronization timeout value in SMM.
+ @param[in,out] SyncTimeout2 It indicates the 2nd BSP/AP synchronization timeout value in SMM.
+
+ **/
+VOID
+GetSmmCpuSyncConfigData (
+ IN OUT BOOLEAN *RelaxedMode, OPTIONAL
+ IN OUT UINT64 *SyncTimeout, OPTIONAL
+ IN OUT UINT64 *SyncTimeout2 OPTIONAL
+ );
+
+/**
Get ACPI S3 enable flag.
**/
@@ -1492,4 +1626,41 @@ SmmWriteProtectReadOnlyPage (
} \
} while (FALSE)
+/**
+ Get the maximum number of logical processors supported by the system.
+
+ @retval The maximum number of logical processors supported by the system
+ is indicated by the return value.
+**/
+UINTN
+GetSupportedMaxLogicalProcessorNumber (
+ VOID
+ );
+
+/**
+ Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from gEfiMpServiceProtocolGuid.
+
+ @param[out] NumberOfCpus Pointer to NumberOfCpus.
+ @param[out] MaxNumberOfCpus Pointer to MaxNumberOfCpus.
+
+ @retval ProcessorInfo Pointer to EFI_PROCESSOR_INFORMATION buffer.
+**/
+EFI_PROCESSOR_INFORMATION *
+GetMpInformationFromMpServices (
+ OUT UINTN *NumberOfCpus,
+ OUT UINTN *MaxNumberOfCpus
+ );
+
+/**
+ The common Entry Point of the SMM CPU driver.
+
+ @retval EFI_SUCCESS The common entry point is executed successfully.
+ @retval Other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+PiSmmCpuEntryCommon (
+ VOID
+ );
+
#endif
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
index 20a1a9c..0ecdd2d 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -9,427 +9,137 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
+#include <Library/UefiBootServicesTableLib.h>
//
-// SMM CPU Private Data structure that contains SMM Configuration Protocol
-// along its supporting fields.
+// TRUE to indicate it's the MM_STANDALONE MM CPU driver.
+// FALSE to indicate it's the DXE_SMM_DRIVER SMM CPU driver.
//
-SMM_CPU_PRIVATE_DATA mSmmCpuPrivateData = {
- SMM_CPU_PRIVATE_DATA_SIGNATURE, // Signature
- NULL, // SmmCpuHandle
- NULL, // Pointer to ProcessorInfo array
- NULL, // Pointer to Operation array
- NULL, // Pointer to CpuSaveStateSize array
- NULL, // Pointer to CpuSaveState array
- {
- { 0 }
- }, // SmmReservedSmramRegion
- {
- SmmStartupThisAp, // SmmCoreEntryContext.SmmStartupThisAp
- 0, // SmmCoreEntryContext.CurrentlyExecutingCpu
- 0, // SmmCoreEntryContext.NumberOfCpus
- NULL, // SmmCoreEntryContext.CpuSaveStateSize
- NULL // SmmCoreEntryContext.CpuSaveState
- },
- NULL, // SmmCoreEntry
- {
- mSmmCpuPrivateData.SmmReservedSmramRegion, // SmmConfiguration.SmramReservedRegions
- RegisterSmmEntry // SmmConfiguration.RegisterSmmEntry
- },
- NULL, // pointer to Ap Wrapper Func array
- { NULL, NULL }, // List_Entry for Tokens.
-};
-
-CPU_HOT_PLUG_DATA mCpuHotPlugData = {
- CPU_HOT_PLUG_DATA_REVISION_1, // Revision
- 0, // Array Length of SmBase and APIC ID
- NULL, // Pointer to APIC ID array
- NULL, // Pointer to SMBASE array
- 0, // Reserved
- 0, // SmrrBase
- 0 // SmrrSize
-};
-
-//
-// Global pointer used to access mSmmCpuPrivateData from outside and inside SMM
-//
-SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate = &mSmmCpuPrivateData;
-
-///
-/// Handle for the SMM CPU Protocol
-///
-EFI_HANDLE mSmmCpuHandle = NULL;
-
-///
-/// SMM CPU Protocol instance
-///
-EFI_SMM_CPU_PROTOCOL mSmmCpu = {
- SmmReadSaveState,
- SmmWriteSaveState
-};
-
-///
-/// SMM Memory Attribute Protocol instance
-///
-EDKII_SMM_MEMORY_ATTRIBUTE_PROTOCOL mSmmMemoryAttribute = {
- EdkiiSmmGetMemoryAttributes,
- EdkiiSmmSetMemoryAttributes,
- EdkiiSmmClearMemoryAttributes
-};
-
-EFI_CPU_INTERRUPT_HANDLER mExternalVectorTable[EXCEPTION_VECTOR_NUMBER];
-
-volatile BOOLEAN *mSmmInitialized = NULL;
-UINT32 mBspApicId = 0;
-
-//
-// SMM stack information
-//
-UINTN mSmmStackArrayBase;
-UINTN mSmmStackArrayEnd;
-UINTN mSmmStackSize;
-
-UINTN mSmmShadowStackSize;
-BOOLEAN mCetSupported = TRUE;
-
-UINTN mMaxNumberOfCpus = 0;
-UINTN mNumberOfCpus = 0;
+const BOOLEAN mIsStandaloneMm = FALSE;
//
// SMM ready to lock flag
//
BOOLEAN mSmmReadyToLock = FALSE;
-//
-// Global used to cache PCD for SMM Code Access Check enable
-//
-BOOLEAN mSmmCodeAccessCheckEnable = FALSE;
-
-//
-// Global used to cache SMM Debug Agent Supported ot not
-//
-BOOLEAN mSmmDebugAgentSupport = FALSE;
-
-//
-// Global copy of the PcdPteMemoryEncryptionAddressOrMask
-//
-UINT64 mAddressEncMask = 0;
-
-//
-// Spin lock used to serialize setting of SMM Code Access Check feature
-//
-SPIN_LOCK *mConfigSmmCodeAccessCheckLock = NULL;
-
-//
-// Saved SMM ranges information
-//
-EFI_SMRAM_DESCRIPTOR *mSmmCpuSmramRanges;
-UINTN mSmmCpuSmramRangeCount;
-
-UINT8 mPhysicalAddressBits;
-
/**
- Initialize IDT to setup exception handlers for SMM.
+ Check SmmProfile is enabled or not.
+
+ @return TRUE SmmProfile is enabled.
+ FALSE SmmProfile is not enabled.
**/
-VOID
-InitializeSmmIdt (
+BOOLEAN
+IsSmmProfileEnabled (
VOID
)
{
- EFI_STATUS Status;
- BOOLEAN InterruptState;
- IA32_DESCRIPTOR DxeIdtr;
-
- //
- // There are 32 (not 255) entries in it since only processor
- // generated exceptions will be handled.
- //
- gcSmiIdtr.Limit = (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32) - 1;
- //
- // Allocate page aligned IDT, because it might be set as read only.
- //
- gcSmiIdtr.Base = (UINTN)AllocateCodePages (EFI_SIZE_TO_PAGES (gcSmiIdtr.Limit + 1));
- ASSERT (gcSmiIdtr.Base != 0);
- ZeroMem ((VOID *)gcSmiIdtr.Base, gcSmiIdtr.Limit + 1);
-
- //
- // Disable Interrupt and save DXE IDT table
- //
- InterruptState = SaveAndDisableInterrupts ();
- AsmReadIdtr (&DxeIdtr);
- //
- // Load SMM temporary IDT table
- //
- AsmWriteIdtr (&gcSmiIdtr);
- //
- // Setup SMM default exception handlers, SMM IDT table
- // will be updated and saved in gcSmiIdtr
- //
- Status = InitializeCpuExceptionHandlers (NULL);
- ASSERT_EFI_ERROR (Status);
- //
- // Restore DXE IDT table and CPU interrupt
- //
- AsmWriteIdtr ((IA32_DESCRIPTOR *)&DxeIdtr);
- SetInterruptState (InterruptState);
+ return FeaturePcdGet (PcdCpuSmmProfileEnable);
}
/**
- Search module name by input IP address and output it.
-
- @param CallerIpAddress Caller instruction pointer.
+ Perform the remaining tasks.
**/
VOID
-DumpModuleInfoByIp (
- IN UINTN CallerIpAddress
- )
-{
- UINTN Pe32Data;
- VOID *PdbPointer;
-
- //
- // Find Image Base
- //
- Pe32Data = PeCoffSearchImageBase (CallerIpAddress);
- if (Pe32Data != 0) {
- DEBUG ((DEBUG_ERROR, "It is invoked from the instruction before IP(0x%p)", (VOID *)CallerIpAddress));
- PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)Pe32Data);
- if (PdbPointer != NULL) {
- DEBUG ((DEBUG_ERROR, " in module (%a)\n", PdbPointer));
- }
- }
-}
-
-/**
- Read information from the CPU save state.
-
- @param This EFI_SMM_CPU_PROTOCOL instance
- @param Width The number of bytes to read from the CPU save state.
- @param Register Specifies the CPU register to read form the save state.
- @param CpuIndex Specifies the zero-based index of the CPU save state.
- @param Buffer Upon return, this holds the CPU register value read from the save state.
-
- @retval EFI_SUCCESS The register was read from Save State
- @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
- @retval EFI_INVALID_PARAMETER This or Buffer is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-SmmReadSaveState (
- IN CONST EFI_SMM_CPU_PROTOCOL *This,
- IN UINTN Width,
- IN EFI_SMM_SAVE_STATE_REGISTER Register,
- IN UINTN CpuIndex,
- OUT VOID *Buffer
+PerformRemainingTasks (
+ VOID
)
{
- EFI_STATUS Status;
+ EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
- //
- // Retrieve pointer to the specified CPU's SMM Save State buffer
- //
- if ((CpuIndex >= gSmst->NumberOfCpus) || (Buffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
+ if (mSmmReadyToLock) {
+ PERF_FUNCTION_BEGIN ();
- //
- // The SpeculationBarrier() call here is to ensure the above check for the
- // CpuIndex has been completed before the execution of subsequent codes.
- //
- SpeculationBarrier ();
+ //
+ // Start SMM Profile feature
+ //
+ if (mSmmProfileEnabled) {
+ SmmProfileStart ();
+ }
- //
- // Check for special EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID
- //
- if (Register == EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID) {
//
- // The pseudo-register only supports the 64-bit size specified by Width.
+ // Check if all Aps enter SMM. In Relaxed-AP Sync Mode, BSP will not wait for
+ // all Aps arrive. However,PerformRemainingTasks() needs to wait all Aps arrive before calling
+ // SetMemMapAttributes() and ConfigSmmCodeAccessCheck() when mSmmReadyToLock
+ // is true. In SetMemMapAttributes(), SmmSetMemoryAttributesEx() will call
+ // FlushTlbForAll() that need to start up the aps. So it need to let all
+ // aps arrive. Same as SetMemMapAttributes(), ConfigSmmCodeAccessCheck()
+ // also will start up the aps.
//
- if (Width != sizeof (UINT64)) {
- return EFI_INVALID_PARAMETER;
+ if (EFI_ERROR (SmmCpuRendezvous (NULL, TRUE))) {
+ DEBUG ((DEBUG_ERROR, "PerformRemainingTasks: fail to wait for all AP check in SMM!\n"));
}
//
- // If the processor is in SMM at the time the SMI occurred,
- // the pseudo register value for EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID is returned in Buffer.
- // Otherwise, EFI_NOT_FOUND is returned.
+ // Update Page Table for outside SMRAM.
//
- if (*(mSmmMpSyncData->CpuData[CpuIndex].Present)) {
- *(UINT64 *)Buffer = gSmmCpuPrivate->ProcessorInfo[CpuIndex].ProcessorId;
- return EFI_SUCCESS;
+ if (mSmmProfileEnabled) {
+ SmmProfileUpdateMemoryAttributes ();
} else {
- return EFI_NOT_FOUND;
+ UpdateUefiMemMapAttributes ();
}
- }
-
- if (!(*(mSmmMpSyncData->CpuData[CpuIndex].Present))) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = MmSaveStateReadRegister (CpuIndex, Register, Width, Buffer);
-
- return Status;
-}
-/**
- Write data to the CPU save state.
-
- @param This EFI_SMM_CPU_PROTOCOL instance
- @param Width The number of bytes to read from the CPU save state.
- @param Register Specifies the CPU register to write to the save state.
- @param CpuIndex Specifies the zero-based index of the CPU save state
- @param Buffer Upon entry, this holds the new CPU register value.
-
- @retval EFI_SUCCESS The register was written from Save State
- @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
- @retval EFI_INVALID_PARAMETER ProcessorIndex or Width is not correct
-
-**/
-EFI_STATUS
-EFIAPI
-SmmWriteSaveState (
- IN CONST EFI_SMM_CPU_PROTOCOL *This,
- IN UINTN Width,
- IN EFI_SMM_SAVE_STATE_REGISTER Register,
- IN UINTN CpuIndex,
- IN CONST VOID *Buffer
- )
-{
- EFI_STATUS Status;
-
- //
- // Retrieve pointer to the specified CPU's SMM Save State buffer
- //
- if ((CpuIndex >= gSmst->NumberOfCpus) || (Buffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
+ //
+ // gEdkiiPiSmmMemoryAttributesTableGuid should have been published at EndOfDxe by SmmCore
+ // Note: gEdkiiPiSmmMemoryAttributesTableGuid is not always installed since it depends on
+ // the memory protection attribute setting in MM Core.
+ //
+ SmmGetSystemConfigurationTable (&gEdkiiPiSmmMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
- //
- // Writes to EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID are ignored
- //
- if (Register == EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID) {
- return EFI_SUCCESS;
- }
+ //
+ // Set critical region attribute in page table according to the MemoryAttributesTable
+ //
+ if (MemoryAttributesTable != NULL) {
+ SetMemMapAttributes (MemoryAttributesTable);
+ }
- if (!mSmmMpSyncData->CpuData[CpuIndex].Present) {
- return EFI_INVALID_PARAMETER;
- }
+ //
+ // Set page table itself to be read-only
+ //
+ SetPageTableAttributes ();
- Status = MmSaveStateWriteRegister (CpuIndex, Register, Width, Buffer);
+ //
+ // Configure SMM Code Access Check feature if available.
+ //
+ ConfigSmmCodeAccessCheck ();
- return Status;
-}
+ //
+ // Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side
+ // as the implementation is provided by platform.
+ //
+ PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0);
+ SmmCpuFeaturesCompleteSmmReadyToLock ();
+ PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0);
-/**
- Initialize SMM environment.
+ //
+ // Clean SMM ready to lock flag
+ //
+ mSmmReadyToLock = FALSE;
-**/
-VOID
-InitializeSmm (
- VOID
- )
-{
- UINT32 ApicId;
- UINTN Index;
- BOOLEAN IsBsp;
-
- ApicId = GetApicId ();
-
- IsBsp = (BOOLEAN)(mBspApicId == ApicId);
-
- ASSERT (mNumberOfCpus <= mMaxNumberOfCpus);
-
- for (Index = 0; Index < mNumberOfCpus; Index++) {
- if (ApicId == (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId) {
- PERF_CODE (
- MpPerfBegin (Index, SMM_MP_PERF_PROCEDURE_ID (InitializeSmm));
- );
- //
- // Initialize SMM specific features on the currently executing CPU
- //
- SmmCpuFeaturesInitializeProcessor (
- Index,
- IsBsp,
- gSmmCpuPrivate->ProcessorInfo,
- &mCpuHotPlugData
- );
-
- if (!mSmmS3Flag) {
- //
- // Check XD and BTS features on each processor on normal boot
- //
- CheckFeatureSupported ();
- } else if (IsBsp) {
- //
- // BSP rebase is already done above.
- // Initialize private data during S3 resume
- //
- InitializeMpSyncData ();
- }
-
- PERF_CODE (
- MpPerfEnd (Index, SMM_MP_PERF_PROCEDURE_ID (InitializeSmm));
- );
-
- return;
- }
+ PERF_FUNCTION_END ();
}
-
- ASSERT (FALSE);
}
/**
- Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init.
+ To get system port address of the SMI Command Port in FADT table.
**/
VOID
-ExecuteFirstSmiInit (
+GetSmiCommandPort (
VOID
)
{
- UINTN Index;
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
- PERF_FUNCTION_BEGIN ();
-
- if (mSmmInitialized == NULL) {
- mSmmInitialized = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) * mMaxNumberOfCpus);
- }
-
- ASSERT (mSmmInitialized != NULL);
- if (mSmmInitialized == NULL) {
- PERF_FUNCTION_END ();
- return;
- }
-
- //
- // Reset the mSmmInitialized to false.
- //
- ZeroMem ((VOID *)mSmmInitialized, sizeof (BOOLEAN) * mMaxNumberOfCpus);
-
- //
- // Get the BSP ApicId.
- //
- mBspApicId = GetApicId ();
+ Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)EfiLocateFirstAcpiTable (
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
+ );
+ ASSERT (Fadt != NULL);
- //
- // Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) for SMM init
- //
- SendSmiIpi (mBspApicId);
- SendSmiIpiAllExcludingSelf ();
-
- //
- // Wait for all processors to finish its 1st SMI
- //
- for (Index = 0; Index < mNumberOfCpus; Index++) {
- while (!(BOOLEAN)mSmmInitialized[Index]) {
- }
- }
-
- PERF_FUNCTION_END ();
+ mSmiCommandPort = Fadt->SmiCmd;
+ DEBUG ((DEBUG_INFO, "mSmiCommandPort = %x\n", mSmiCommandPort));
}
/**
@@ -458,6 +168,21 @@ SmmReadyToLockEventNotify (
GetUefiMemoryMap ();
//
+ // Skip SMM profile initialization if feature is disabled
+ //
+ if (mSmmProfileEnabled) {
+ //
+ // Get Software SMI from FADT
+ //
+ GetSmiCommandPort ();
+
+ //
+ // Initialize protected memory range for patching page table later.
+ //
+ InitProtectedMemRange ();
+ }
+
+ //
// Set SMM ready to lock flag and return
//
mSmmReadyToLock = TRUE;
@@ -465,162 +190,58 @@ SmmReadyToLockEventNotify (
}
/**
- Function to compare 2 SMM_BASE_HOB_DATA pointer based on ProcessorIndex.
+ Get SmmCpuSyncConfig data: RelaxedMode, SyncTimeout, SyncTimeout2.
- @param[in] Buffer1 pointer to SMM_BASE_HOB_DATA poiner to compare
- @param[in] Buffer2 pointer to second SMM_BASE_HOB_DATA pointer to compare
+ @param[in,out] RelaxedMode It indicates if Relaxed CPU synchronization method or
+ traditional CPU synchronization method is used when processing an SMI.
+ @param[in,out] SyncTimeout It indicates the 1st BSP/AP synchronization timeout value in SMM.
+ @param[in,out] SyncTimeout2 It indicates the 2nd BSP/AP synchronization timeout value in SMM.
- @retval 0 Buffer1 equal to Buffer2
- @retval <0 Buffer1 is less than Buffer2
- @retval >0 Buffer1 is greater than Buffer2
-**/
-INTN
-EFIAPI
-SmBaseHobCompare (
- IN CONST VOID *Buffer1,
- IN CONST VOID *Buffer2
+ **/
+VOID
+GetSmmCpuSyncConfigData (
+ IN OUT BOOLEAN *RelaxedMode, OPTIONAL
+ IN OUT UINT64 *SyncTimeout, OPTIONAL
+ IN OUT UINT64 *SyncTimeout2 OPTIONAL
)
{
- if ((*(SMM_BASE_HOB_DATA **)Buffer1)->ProcessorIndex > (*(SMM_BASE_HOB_DATA **)Buffer2)->ProcessorIndex) {
- return 1;
- } else if ((*(SMM_BASE_HOB_DATA **)Buffer1)->ProcessorIndex < (*(SMM_BASE_HOB_DATA **)Buffer2)->ProcessorIndex) {
- return -1;
+ if (RelaxedMode != NULL) {
+ *RelaxedMode = (BOOLEAN)(PcdGet8 (PcdCpuSmmSyncMode) == MmCpuSyncModeRelaxedAp);
+ }
+
+ if (SyncTimeout != NULL) {
+ *SyncTimeout = PcdGet64 (PcdCpuSmmApSyncTimeout);
}
- return 0;
+ if (SyncTimeout2 != NULL) {
+ *SyncTimeout2 = PcdGet64 (PcdCpuSmmApSyncTimeout2);
+ }
}
/**
- Extract SmBase for all CPU from SmmBase HOB.
-
- @param[in] MaxNumberOfCpus Max NumberOfCpus.
+ Get ACPI S3 enable flag.
- @param[out] AllocatedSmBaseBuffer Pointer to SmBase Buffer allocated
- by this function. Only set if the
- function returns EFI_SUCCESS.
-
- @retval EFI_SUCCESS SmBase Buffer output successfully.
- @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
- @retval EFI_NOT_FOUND gSmmBaseHobGuid was never created.
**/
-STATIC
-EFI_STATUS
-GetSmBase (
- IN UINTN MaxNumberOfCpus,
- OUT UINTN **AllocatedSmBaseBuffer
+VOID
+GetAcpiS3EnableFlag (
+ VOID
)
{
- UINTN HobCount;
- EFI_HOB_GUID_TYPE *GuidHob;
- SMM_BASE_HOB_DATA *SmmBaseHobData;
- UINTN NumberOfProcessors;
- SMM_BASE_HOB_DATA **SmBaseHobs;
- UINTN *SmBaseBuffer;
- UINTN HobIndex;
- UINTN SortBuffer;
- UINTN ProcessorIndex;
- UINT64 PrevProcessorIndex;
- EFI_HOB_GUID_TYPE *FirstSmmBaseGuidHob;
-
- SmmBaseHobData = NULL;
- HobIndex = 0;
- ProcessorIndex = 0;
- HobCount = 0;
- NumberOfProcessors = 0;
-
- FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);
- if (FirstSmmBaseGuidHob == NULL) {
- return EFI_NOT_FOUND;
- }
-
- GuidHob = FirstSmmBaseGuidHob;
- while (GuidHob != NULL) {
- HobCount++;
- SmmBaseHobData = GET_GUID_HOB_DATA (GuidHob);
- NumberOfProcessors += SmmBaseHobData->NumberOfProcessors;
-
- if (NumberOfProcessors >= MaxNumberOfCpus) {
- break;
- }
-
- GuidHob = GetNextGuidHob (&gSmmBaseHobGuid, GET_NEXT_HOB (GuidHob));
- }
-
- ASSERT (NumberOfProcessors == MaxNumberOfCpus);
- if (NumberOfProcessors != MaxNumberOfCpus) {
- CpuDeadLoop ();
- }
-
- SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) * HobCount);
- if (SmBaseHobs == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Record each SmmBaseHob pointer in the SmBaseHobs.
- // The FirstSmmBaseGuidHob is to speed up this while-loop
- // without needing to look for SmBaseHob from beginning.
- //
- GuidHob = FirstSmmBaseGuidHob;
- while (HobIndex < HobCount) {
- SmBaseHobs[HobIndex++] = GET_GUID_HOB_DATA (GuidHob);
- GuidHob = GetNextGuidHob (&gSmmBaseHobGuid, GET_NEXT_HOB (GuidHob));
- }
-
- SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) * (MaxNumberOfCpus));
- ASSERT (SmBaseBuffer != NULL);
- if (SmBaseBuffer == NULL) {
- FreePool (SmBaseHobs);
- return EFI_OUT_OF_RESOURCES;
- }
-
- QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *), (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
- PrevProcessorIndex = 0;
- for (HobIndex = 0; HobIndex < HobCount; HobIndex++) {
- //
- // Make sure no overlap and no gap in the CPU range covered by each HOB
- //
- ASSERT (SmBaseHobs[HobIndex]->ProcessorIndex == PrevProcessorIndex);
-
- //
- // Cache each SmBase in order.
- //
- for (ProcessorIndex = 0; ProcessorIndex < SmBaseHobs[HobIndex]->NumberOfProcessors; ProcessorIndex++) {
- SmBaseBuffer[PrevProcessorIndex + ProcessorIndex] = (UINTN)SmBaseHobs[HobIndex]->SmBase[ProcessorIndex];
- }
-
- PrevProcessorIndex += SmBaseHobs[HobIndex]->NumberOfProcessors;
- }
-
- FreePool (SmBaseHobs);
- *AllocatedSmBaseBuffer = SmBaseBuffer;
- return EFI_SUCCESS;
+ mAcpiS3Enable = PcdGetBool (PcdAcpiS3Enable);
}
/**
- Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on ProcessorIndex.
+ Get the maximum number of logical processors supported by the system.
- @param[in] Buffer1 pointer to MP_INFORMATION2_HOB_DATA poiner to compare
- @param[in] Buffer2 pointer to second MP_INFORMATION2_HOB_DATA pointer to compare
-
- @retval 0 Buffer1 equal to Buffer2
- @retval <0 Buffer1 is less than Buffer2
- @retval >0 Buffer1 is greater than Buffer2
+ @retval The maximum number of logical processors supported by the system
+ is indicated by the return value.
**/
-INTN
-EFIAPI
-MpInformation2HobCompare (
- IN CONST VOID *Buffer1,
- IN CONST VOID *Buffer2
+UINTN
+GetSupportedMaxLogicalProcessorNumber (
+ VOID
)
{
- if ((*(MP_INFORMATION2_HOB_DATA **)Buffer1)->ProcessorIndex > (*(MP_INFORMATION2_HOB_DATA **)Buffer2)->ProcessorIndex) {
- return 1;
- } else if ((*(MP_INFORMATION2_HOB_DATA **)Buffer1)->ProcessorIndex < (*(MP_INFORMATION2_HOB_DATA **)Buffer2)->ProcessorIndex) {
- return -1;
- }
-
- return 0;
+ return PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
}
/**
@@ -667,7 +288,7 @@ GetMpInformationFromMpServices (
return NULL;
}
- ASSERT (NumberOfProcessors <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ ASSERT (NumberOfProcessors <= GetSupportedMaxLogicalProcessorNumber ());
/// Allocate buffer for processor information
ProcessorInfo = AllocateZeroPool (sizeof (EFI_PROCESSOR_INFORMATION) * NumberOfProcessors);
@@ -689,12 +310,12 @@ GetMpInformationFromMpServices (
*NumberOfCpus = NumberOfEnabledProcessors;
- ASSERT (*NumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ ASSERT (*NumberOfCpus <= GetSupportedMaxLogicalProcessorNumber ());
//
// If support CPU hot plug, we need to allocate resources for possibly hot-added processors
//
if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
- *MaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
+ *MaxNumberOfCpus = GetSupportedMaxLogicalProcessorNumber ();
} else {
*MaxNumberOfCpus = *NumberOfCpus;
}
@@ -703,124 +324,6 @@ GetMpInformationFromMpServices (
}
/**
- Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from MpInformation2 HOB.
-
- @param[out] NumberOfCpus Pointer to NumberOfCpus.
- @param[out] MaxNumberOfCpus Pointer to MaxNumberOfCpus.
-
- @retval ProcessorInfo Pointer to EFI_PROCESSOR_INFORMATION buffer.
-**/
-EFI_PROCESSOR_INFORMATION *
-GetMpInformation (
- OUT UINTN *NumberOfCpus,
- OUT UINTN *MaxNumberOfCpus
- )
-{
- EFI_HOB_GUID_TYPE *GuidHob;
- EFI_HOB_GUID_TYPE *FirstMpInfo2Hob;
- MP_INFORMATION2_HOB_DATA *MpInformation2HobData;
- UINTN HobCount;
- UINTN HobIndex;
- MP_INFORMATION2_HOB_DATA **MpInfo2Hobs;
- UINTN SortBuffer;
- UINTN ProcessorIndex;
- UINT64 PrevProcessorIndex;
- MP_INFORMATION2_ENTRY *MpInformation2Entry;
- EFI_PROCESSOR_INFORMATION *ProcessorInfo;
-
- GuidHob = NULL;
- MpInformation2HobData = NULL;
- FirstMpInfo2Hob = NULL;
- MpInfo2Hobs = NULL;
- HobIndex = 0;
- HobCount = 0;
-
- FirstMpInfo2Hob = GetFirstGuidHob (&gMpInformation2HobGuid);
- if (FirstMpInfo2Hob == NULL) {
- DEBUG ((DEBUG_INFO, "%a: [INFO] gMpInformation2HobGuid HOB not found.\n", __func__));
- return GetMpInformationFromMpServices (NumberOfCpus, MaxNumberOfCpus);
- }
-
- GuidHob = FirstMpInfo2Hob;
- while (GuidHob != NULL) {
- MpInformation2HobData = GET_GUID_HOB_DATA (GuidHob);
-
- //
- // This is the last MpInformationHob in the HOB list.
- //
- if (MpInformation2HobData->NumberOfProcessors == 0) {
- ASSERT (HobCount != 0);
- break;
- }
-
- HobCount++;
- *NumberOfCpus += MpInformation2HobData->NumberOfProcessors;
- GuidHob = GetNextGuidHob (&gMpInformation2HobGuid, GET_NEXT_HOB (GuidHob));
- }
-
- ASSERT (*NumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
-
- //
- // If support CPU hot plug, we need to allocate resources for possibly hot-added processors
- //
- if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
- *MaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
- } else {
- *MaxNumberOfCpus = *NumberOfCpus;
- }
-
- MpInfo2Hobs = AllocatePool (sizeof (MP_INFORMATION2_HOB_DATA *) * HobCount);
- ASSERT (MpInfo2Hobs != NULL);
- if (MpInfo2Hobs == NULL) {
- return NULL;
- }
-
- //
- // Record each MpInformation2Hob pointer in the MpInfo2Hobs.
- // The FirstMpInfo2Hob is to speed up this while-loop without
- // needing to look for MpInfo2Hob from beginning.
- //
- GuidHob = FirstMpInfo2Hob;
- while (HobIndex < HobCount) {
- MpInfo2Hobs[HobIndex++] = GET_GUID_HOB_DATA (GuidHob);
- GuidHob = GetNextGuidHob (&gMpInformation2HobGuid, GET_NEXT_HOB (GuidHob));
- }
-
- ProcessorInfo = (EFI_PROCESSOR_INFORMATION *)AllocatePool (sizeof (EFI_PROCESSOR_INFORMATION) * (*MaxNumberOfCpus));
- ASSERT (ProcessorInfo != NULL);
- if (ProcessorInfo == NULL) {
- FreePool (MpInfo2Hobs);
- return NULL;
- }
-
- QuickSort (MpInfo2Hobs, HobCount, sizeof (MP_INFORMATION2_HOB_DATA *), (BASE_SORT_COMPARE)MpInformation2HobCompare, &SortBuffer);
- PrevProcessorIndex = 0;
- for (HobIndex = 0; HobIndex < HobCount; HobIndex++) {
- //
- // Make sure no overlap and no gap in the CPU range covered by each HOB
- //
- ASSERT (MpInfo2Hobs[HobIndex]->ProcessorIndex == PrevProcessorIndex);
-
- //
- // Cache each EFI_PROCESSOR_INFORMATION in order.
- //
- for (ProcessorIndex = 0; ProcessorIndex < MpInfo2Hobs[HobIndex]->NumberOfProcessors; ProcessorIndex++) {
- MpInformation2Entry = GET_MP_INFORMATION_ENTRY (MpInfo2Hobs[HobIndex], ProcessorIndex);
- CopyMem (
- &ProcessorInfo[PrevProcessorIndex + ProcessorIndex],
- &MpInformation2Entry->ProcessorInfo,
- sizeof (EFI_PROCESSOR_INFORMATION)
- );
- }
-
- PrevProcessorIndex += MpInfo2Hobs[HobIndex]->NumberOfProcessors;
- }
-
- FreePool (MpInfo2Hobs);
- return ProcessorInfo;
-}
-
-/**
The module Entry Point of the CPU SMM driver.
@param ImageHandle The firmware allocated handle for the EFI image.
@@ -838,67 +341,7 @@ PiCpuSmmEntry (
)
{
EFI_STATUS Status;
- UINTN Index;
- UINTN TileCodeSize;
- UINTN TileDataSize;
- UINTN TileSize;
- UINT8 *Stacks;
VOID *Registration;
- UINT32 RegEax;
- UINT32 RegEbx;
- UINT32 RegEcx;
- UINT32 RegEdx;
- UINTN FamilyId;
- UINTN ModelId;
- UINT32 Cr3;
-
- PERF_FUNCTION_BEGIN ();
-
- //
- // Initialize address fixup
- //
- PiSmmCpuSmiEntryFixupAddress ();
-
- //
- // Initialize Debug Agent to support source level debug in SMM code
- //
- InitializeDebugAgent (DEBUG_AGENT_INIT_SMM, &mSmmDebugAgentSupport, NULL);
-
- //
- // Report the start of CPU SMM initialization.
- //
- REPORT_STATUS_CODE (
- EFI_PROGRESS_CODE,
- EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT
- );
-
- //
- // Find out SMRR Base and SMRR Size
- //
- FindSmramInfo (&mCpuHotPlugData.SmrrBase, &mCpuHotPlugData.SmrrSize);
-
- //
- // Retrive NumberOfProcessors, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from MpInformation2 HOB.
- //
- gSmmCpuPrivate->ProcessorInfo = GetMpInformation (&mNumberOfCpus, &mMaxNumberOfCpus);
- ASSERT (gSmmCpuPrivate->ProcessorInfo != NULL);
-
- //
- // If support CPU hot plug, PcdCpuSmmEnableBspElection should be set to TRUE.
- // A constant BSP index makes no sense because it may be hot removed.
- //
- DEBUG_CODE_BEGIN ();
- if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
- ASSERT (FeaturePcdGet (PcdCpuSmmEnableBspElection));
- }
-
- DEBUG_CODE_END ();
-
- //
- // Save the PcdCpuSmmCodeAccessCheckEnable value into a global variable.
- //
- mSmmCodeAccessCheckEnable = PcdGetBool (PcdCpuSmmCodeAccessCheckEnable);
- DEBUG ((DEBUG_INFO, "PcdCpuSmmCodeAccessCheckEnable = %d\n", mSmmCodeAccessCheckEnable));
//
// Save the PcdPteMemoryEncryptionAddressOrMask value into a global variable.
@@ -907,371 +350,9 @@ PiCpuSmmEntry (
mAddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
DEBUG ((DEBUG_INFO, "mAddressEncMask = 0x%lx\n", mAddressEncMask));
- gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus = mMaxNumberOfCpus;
-
- PERF_CODE (
- InitializeMpPerf (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus);
- );
-
- //
- // The CPU save state and code for the SMI entry point are tiled within an SMRAM
- // allocated buffer. The minimum size of this buffer for a uniprocessor system
- // is 32 KB, because the entry point is SMBASE + 32KB, and CPU save state area
- // just below SMBASE + 64KB. If more than one CPU is present in the platform,
- // then the SMI entry point and the CPU save state areas can be tiles to minimize
- // the total amount SMRAM required for all the CPUs. The tile size can be computed
- // by adding the // CPU save state size, any extra CPU specific context, and
- // the size of code that must be placed at the SMI entry point to transfer
- // control to a C function in the native SMM execution mode. This size is
- // rounded up to the nearest power of 2 to give the tile size for a each CPU.
- // The total amount of memory required is the maximum number of CPUs that
- // platform supports times the tile size. The picture below shows the tiling,
- // where m is the number of tiles that fit in 32KB.
- //
- // +-----------------------------+ <-- 2^n offset from Base of allocated buffer
- // | CPU m+1 Save State |
- // +-----------------------------+
- // | CPU m+1 Extra Data |
- // +-----------------------------+
- // | Padding |
- // +-----------------------------+
- // | CPU 2m SMI Entry |
- // +#############################+ <-- Base of allocated buffer + 64 KB
- // | CPU m-1 Save State |
- // +-----------------------------+
- // | CPU m-1 Extra Data |
- // +-----------------------------+
- // | Padding |
- // +-----------------------------+
- // | CPU 2m-1 SMI Entry |
- // +=============================+ <-- 2^n offset from Base of allocated buffer
- // | . . . . . . . . . . . . |
- // +=============================+ <-- 2^n offset from Base of allocated buffer
- // | CPU 2 Save State |
- // +-----------------------------+
- // | CPU 2 Extra Data |
- // +-----------------------------+
- // | Padding |
- // +-----------------------------+
- // | CPU m+1 SMI Entry |
- // +=============================+ <-- Base of allocated buffer + 32 KB
- // | CPU 1 Save State |
- // +-----------------------------+
- // | CPU 1 Extra Data |
- // +-----------------------------+
- // | Padding |
- // +-----------------------------+
- // | CPU m SMI Entry |
- // +#############################+ <-- Base of allocated buffer + 32 KB == CPU 0 SMBASE + 64 KB
- // | CPU 0 Save State |
- // +-----------------------------+
- // | CPU 0 Extra Data |
- // +-----------------------------+
- // | Padding |
- // +-----------------------------+
- // | CPU m-1 SMI Entry |
- // +=============================+ <-- 2^n offset from Base of allocated buffer
- // | . . . . . . . . . . . . |
- // +=============================+ <-- 2^n offset from Base of allocated buffer
- // | Padding |
- // +-----------------------------+
- // | CPU 1 SMI Entry |
- // +=============================+ <-- 2^n offset from Base of allocated buffer
- // | Padding |
- // +-----------------------------+
- // | CPU 0 SMI Entry |
- // +#############################+ <-- Base of allocated buffer == CPU 0 SMBASE + 32 KB
- //
-
- //
- // Retrieve CPU Family
- //
- AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL);
- FamilyId = (RegEax >> 8) & 0xf;
- ModelId = (RegEax >> 4) & 0xf;
- if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
- ModelId = ModelId | ((RegEax >> 12) & 0xf0);
- }
-
- RegEdx = 0;
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
- if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
- AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
- }
-
- //
- // Determine the mode of the CPU at the time an SMI occurs
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 34.4.1.1
- //
- mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT;
- if ((RegEdx & BIT29) != 0) {
- mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;
- }
-
- if (FamilyId == 0x06) {
- if ((ModelId == 0x17) || (ModelId == 0x0f) || (ModelId == 0x1c)) {
- mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;
- }
- }
-
- DEBUG ((DEBUG_INFO, "PcdControlFlowEnforcementPropertyMask = %d\n", PcdGet32 (PcdControlFlowEnforcementPropertyMask)));
- if (PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) {
- AsmCpuid (CPUID_SIGNATURE, &RegEax, NULL, NULL, NULL);
- if (RegEax >= CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS) {
- AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, NULL, NULL, &RegEcx, &RegEdx);
- DEBUG ((DEBUG_INFO, "CPUID[7/0] ECX - 0x%08x\n", RegEcx));
- DEBUG ((DEBUG_INFO, " CET_SS - 0x%08x\n", RegEcx & CPUID_CET_SS));
- DEBUG ((DEBUG_INFO, " CET_IBT - 0x%08x\n", RegEdx & CPUID_CET_IBT));
- if ((RegEcx & CPUID_CET_SS) == 0) {
- mCetSupported = FALSE;
- PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1);
- }
-
- if (mCetSupported) {
- AsmCpuidEx (CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF, NULL, &RegEbx, &RegEcx, NULL);
- DEBUG ((DEBUG_INFO, "CPUID[D/1] EBX - 0x%08x, ECX - 0x%08x\n", RegEbx, RegEcx));
- AsmCpuidEx (CPUID_EXTENDED_STATE, 11, &RegEax, NULL, &RegEcx, NULL);
- DEBUG ((DEBUG_INFO, "CPUID[D/11] EAX - 0x%08x, ECX - 0x%08x\n", RegEax, RegEcx));
- AsmCpuidEx (CPUID_EXTENDED_STATE, 12, &RegEax, NULL, &RegEcx, NULL);
- DEBUG ((DEBUG_INFO, "CPUID[D/12] EAX - 0x%08x, ECX - 0x%08x\n", RegEax, RegEcx));
- }
- } else {
- mCetSupported = FALSE;
- PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1);
- }
- } else {
- mCetSupported = FALSE;
- PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1);
- }
-
- //
- // Compute tile size of buffer required to hold the CPU SMRAM Save State Map, extra CPU
- // specific context start starts at SMBASE + SMM_PSD_OFFSET, and the SMI entry point.
- // This size is rounded up to nearest power of 2.
- //
- TileCodeSize = GetSmiHandlerSize ();
- TileCodeSize = ALIGN_VALUE (TileCodeSize, SIZE_4KB);
- TileDataSize = (SMRAM_SAVE_STATE_MAP_OFFSET - SMM_PSD_OFFSET) + sizeof (SMRAM_SAVE_STATE_MAP);
- TileDataSize = ALIGN_VALUE (TileDataSize, SIZE_4KB);
- TileSize = TileDataSize + TileCodeSize - 1;
- TileSize = 2 * GetPowerOfTwo32 ((UINT32)TileSize);
- DEBUG ((DEBUG_INFO, "SMRAM TileSize = 0x%08x (0x%08x, 0x%08x)\n", TileSize, TileCodeSize, TileDataSize));
-
- //
- // If the TileSize is larger than space available for the SMI Handler of
- // CPU[i], the extra CPU specific context of CPU[i+1], and the SMRAM Save
- // State Map of CPU[i+1], then ASSERT(). If this ASSERT() is triggered, then
- // the SMI Handler size must be reduced or the size of the extra CPU specific
- // context must be reduced.
- //
- ASSERT (TileSize <= (SMRAM_SAVE_STATE_MAP_OFFSET + sizeof (SMRAM_SAVE_STATE_MAP) - SMM_HANDLER_OFFSET));
+ Status = PiSmmCpuEntryCommon ();
- //
- // Check whether the Required TileSize is enough.
- //
- if (TileSize > SIZE_8KB) {
- DEBUG ((DEBUG_ERROR, "The Range of Smbase in SMRAM is not enough -- Required TileSize = 0x%08x, Actual TileSize = 0x%08x\n", TileSize, SIZE_8KB));
- FreePool (gSmmCpuPrivate->ProcessorInfo);
- CpuDeadLoop ();
- return RETURN_BUFFER_TOO_SMALL;
- }
-
- //
- // Retrieve the allocated SmmBase from gSmmBaseHobGuid. If found,
- // means the SmBase relocation has been done.
- //
- mCpuHotPlugData.SmBase = NULL;
- Status = GetSmBase (mMaxNumberOfCpus, &mCpuHotPlugData.SmBase);
- ASSERT (!EFI_ERROR (Status));
- if (EFI_ERROR (Status)) {
- CpuDeadLoop ();
- }
-
- //
- // ASSERT SmBase has been relocated.
- //
- ASSERT (mCpuHotPlugData.SmBase != NULL);
-
- //
- // Allocate buffer for pointers to array in SMM_CPU_PRIVATE_DATA.
- //
- gSmmCpuPrivate->Operation = (SMM_CPU_OPERATION *)AllocatePool (sizeof (SMM_CPU_OPERATION) * mMaxNumberOfCpus);
- ASSERT (gSmmCpuPrivate->Operation != NULL);
-
- gSmmCpuPrivate->CpuSaveStateSize = (UINTN *)AllocatePool (sizeof (UINTN) * mMaxNumberOfCpus);
- ASSERT (gSmmCpuPrivate->CpuSaveStateSize != NULL);
-
- gSmmCpuPrivate->CpuSaveState = (VOID **)AllocatePool (sizeof (VOID *) * mMaxNumberOfCpus);
- ASSERT (gSmmCpuPrivate->CpuSaveState != NULL);
-
- mSmmCpuPrivateData.SmmCoreEntryContext.CpuSaveStateSize = gSmmCpuPrivate->CpuSaveStateSize;
- mSmmCpuPrivateData.SmmCoreEntryContext.CpuSaveState = gSmmCpuPrivate->CpuSaveState;
-
- //
- // Allocate buffer for pointers to array in CPU_HOT_PLUG_DATA.
- //
- mCpuHotPlugData.ApicId = (UINT64 *)AllocatePool (sizeof (UINT64) * mMaxNumberOfCpus);
- ASSERT (mCpuHotPlugData.ApicId != NULL);
- mCpuHotPlugData.ArrayLength = (UINT32)mMaxNumberOfCpus;
-
- //
- // Retrieve APIC ID of each enabled processor from the MP Services protocol.
- // Also compute the SMBASE address, CPU Save State address, and CPU Save state
- // size for each CPU in the platform
- //
- for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
- gSmmCpuPrivate->CpuSaveStateSize[Index] = sizeof (SMRAM_SAVE_STATE_MAP);
- gSmmCpuPrivate->CpuSaveState[Index] = (VOID *)(mCpuHotPlugData.SmBase[Index] + SMRAM_SAVE_STATE_MAP_OFFSET);
- gSmmCpuPrivate->Operation[Index] = SmmCpuNone;
-
- if (Index < mNumberOfCpus) {
- mCpuHotPlugData.ApicId[Index] = gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId;
-
- DEBUG ((
- DEBUG_INFO,
- "CPU[%03x] APIC ID=%04x SMBASE=%08x SaveState=%08x Size=%08x\n",
- Index,
- (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId,
- mCpuHotPlugData.SmBase[Index],
- gSmmCpuPrivate->CpuSaveState[Index],
- gSmmCpuPrivate->CpuSaveStateSize[Index]
- ));
- } else {
- gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId = INVALID_APIC_ID;
- mCpuHotPlugData.ApicId[Index] = INVALID_APIC_ID;
- }
- }
-
- //
- // Allocate SMI stacks for all processors.
- //
- mSmmStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize)));
- if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
- //
- // SMM Stack Guard Enabled
- // 2 more pages is allocated for each processor, one is guard page and the other is known good stack.
- //
- // +--------------------------------------------------+-----+--------------------------------------------------+
- // | Known Good Stack | Guard Page | SMM Stack | ... | Known Good Stack | Guard Page | SMM Stack |
- // +--------------------------------------------------+-----+--------------------------------------------------+
- // | 4K | 4K PcdCpuSmmStackSize| | 4K | 4K PcdCpuSmmStackSize|
- // |<---------------- mSmmStackSize ----------------->| |<---------------- mSmmStackSize ----------------->|
- // | | | |
- // |<------------------ Processor 0 ----------------->| |<------------------ Processor n ----------------->|
- //
- mSmmStackSize += EFI_PAGES_TO_SIZE (2);
- }
-
- mSmmShadowStackSize = 0;
- if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {
- mSmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize)));
-
- if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
- //
- // SMM Stack Guard Enabled
- // Append Shadow Stack after normal stack
- // 2 more pages is allocated for each processor, one is guard page and the other is known good shadow stack.
- //
- // |= Stacks
- // +--------------------------------------------------+---------------------------------------------------------------+
- // | Known Good Stack | Guard Page | SMM Stack | Known Good Shadow Stack | Guard Page | SMM Shadow Stack |
- // +--------------------------------------------------+---------------------------------------------------------------+
- // | 4K | 4K |PcdCpuSmmStackSize| 4K | 4K |PcdCpuSmmShadowStackSize|
- // |<---------------- mSmmStackSize ----------------->|<--------------------- mSmmShadowStackSize ------------------->|
- // | |
- // |<-------------------------------------------- Processor N ------------------------------------------------------->|
- //
- mSmmShadowStackSize += EFI_PAGES_TO_SIZE (2);
- } else {
- //
- // SMM Stack Guard Disabled (Known Good Stack is still required for potential stack switch.)
- // Append Shadow Stack after normal stack with 1 more page as known good shadow stack.
- // 1 more pages is allocated for each processor, it is known good stack.
- //
- //
- // |= Stacks
- // +-------------------------------------+--------------------------------------------------+
- // | Known Good Stack | SMM Stack | Known Good Shadow Stack | SMM Shadow Stack |
- // +-------------------------------------+--------------------------------------------------+
- // | 4K |PcdCpuSmmStackSize| 4K |PcdCpuSmmShadowStackSize|
- // |<---------- mSmmStackSize ---------->|<--------------- mSmmShadowStackSize ------------>|
- // | |
- // |<-------------------------------- Processor N ----------------------------------------->|
- //
- mSmmShadowStackSize += EFI_PAGES_TO_SIZE (1);
- mSmmStackSize += EFI_PAGES_TO_SIZE (1);
- }
- }
-
- Stacks = (UINT8 *)AllocatePages (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (EFI_SIZE_TO_PAGES (mSmmStackSize + mSmmShadowStackSize)));
- ASSERT (Stacks != NULL);
- mSmmStackArrayBase = (UINTN)Stacks;
- mSmmStackArrayEnd = mSmmStackArrayBase + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (mSmmStackSize + mSmmShadowStackSize) - 1;
-
- DEBUG ((DEBUG_INFO, "Stacks - 0x%x\n", Stacks));
- DEBUG ((DEBUG_INFO, "mSmmStackSize - 0x%x\n", mSmmStackSize));
- DEBUG ((DEBUG_INFO, "PcdCpuSmmStackGuard - 0x%x\n", FeaturePcdGet (PcdCpuSmmStackGuard)));
- if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {
- DEBUG ((DEBUG_INFO, "mSmmShadowStackSize - 0x%x\n", mSmmShadowStackSize));
- }
-
- //
- // Initialize IDT
- //
- InitializeSmmIdt ();
-
- //
- // SMM Time initialization
- //
- InitializeSmmTimer ();
-
- //
- // Initialize MP globals
- //
- Cr3 = InitializeMpServiceData (Stacks, mSmmStackSize, mSmmShadowStackSize);
-
- if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {
- for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {
- SetShadowStack (
- Cr3,
- (EFI_PHYSICAL_ADDRESS)(UINTN)Stacks + mSmmStackSize + (mSmmStackSize + mSmmShadowStackSize) * Index,
- mSmmShadowStackSize
- );
- if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
- ConvertMemoryPageAttributes (
- Cr3,
- mPagingMode,
- (EFI_PHYSICAL_ADDRESS)(UINTN)Stacks + mSmmStackSize + EFI_PAGES_TO_SIZE (1) + (mSmmStackSize + mSmmShadowStackSize) * Index,
- EFI_PAGES_TO_SIZE (1),
- EFI_MEMORY_RP,
- TRUE,
- NULL
- );
- }
- }
- }
-
- //
- // For relocated SMBASE, some MSRs & CSRs are still required to be configured in SMM Mode for SMM Initialization.
- // Those MSRs & CSRs must be configured before normal SMI sources happen.
- // So, here is to issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init.
- //
- ExecuteFirstSmiInit ();
-
- //
- // Call hook for BSP to perform extra actions in normal mode after all
- // SMM base addresses have been relocated on all CPUs
- //
- SmmCpuFeaturesSmmRelocationComplete ();
-
- DEBUG ((DEBUG_INFO, "mXdSupported - 0x%x\n", mXdSupported));
-
- //
- // Fill in SMM Reserved Regions
- //
- gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedStart = 0;
- gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedSize = 0;
+ ASSERT_EFI_ERROR (Status);
//
// Install the SMM Configuration Protocol onto a new handle on the handle database.
@@ -1287,49 +368,6 @@ PiCpuSmmEntry (
ASSERT_EFI_ERROR (Status);
//
- // Install the SMM CPU Protocol into SMM protocol database
- //
- Status = gSmst->SmmInstallProtocolInterface (
- &mSmmCpuHandle,
- &gEfiSmmCpuProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mSmmCpu
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Install the SMM Memory Attribute Protocol into SMM protocol database
- //
- Status = gSmst->SmmInstallProtocolInterface (
- &mSmmCpuHandle,
- &gEdkiiSmmMemoryAttributeProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mSmmMemoryAttribute
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Initialize global buffer for MM MP.
- //
- InitializeDataForMmMp ();
-
- //
- // Initialize Package First Thread Index Info.
- //
- InitPackageFirstThreadIndexInfo ();
-
- //
- // Install the SMM Mp Protocol into SMM protocol database
- //
- Status = gSmst->SmmInstallProtocolInterface (
- &mSmmCpuHandle,
- &gEfiMmMpProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mSmmMp
- );
- ASSERT_EFI_ERROR (Status);
-
- //
// Expose address of CPU Hot Plug Data structure if CPU hot plug is supported.
//
if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
@@ -1338,408 +376,14 @@ PiCpuSmmEntry (
}
//
- // Initialize SMM CPU Services Support
- //
- Status = InitializeSmmCpuServices (mSmmCpuHandle);
- ASSERT_EFI_ERROR (Status);
-
- //
- // register SMM Ready To Lock Protocol notification
+ // Register SMM Ready To Lock Protocol notification
//
- Status = gSmst->SmmRegisterProtocolNotify (
+ Status = gMmst->MmRegisterProtocolNotify (
&gEfiSmmReadyToLockProtocolGuid,
SmmReadyToLockEventNotify,
&Registration
);
ASSERT_EFI_ERROR (Status);
- //
- // Initialize SMM Profile feature
- //
- InitSmmProfile (Cr3);
-
- GetAcpiS3EnableFlag ();
- InitSmmS3ResumeState (Cr3);
-
- DEBUG ((DEBUG_INFO, "SMM CPU Module exit from SMRAM with EFI_SUCCESS\n"));
-
- PERF_FUNCTION_END ();
- return EFI_SUCCESS;
-}
-
-/**
- Function to compare 2 EFI_SMRAM_DESCRIPTOR based on CpuStart.
-
- @param[in] Buffer1 pointer to Device Path poiner to compare
- @param[in] Buffer2 pointer to second DevicePath pointer to compare
-
- @retval 0 Buffer1 equal to Buffer2
- @retval <0 Buffer1 is less than Buffer2
- @retval >0 Buffer1 is greater than Buffer2
-**/
-INTN
-EFIAPI
-CpuSmramRangeCompare (
- IN CONST VOID *Buffer1,
- IN CONST VOID *Buffer2
- )
-{
- if (((EFI_SMRAM_DESCRIPTOR *)Buffer1)->CpuStart > ((EFI_SMRAM_DESCRIPTOR *)Buffer2)->CpuStart) {
- return 1;
- } else if (((EFI_SMRAM_DESCRIPTOR *)Buffer1)->CpuStart < ((EFI_SMRAM_DESCRIPTOR *)Buffer2)->CpuStart) {
- return -1;
- }
-
- return 0;
-}
-
-/**
-
- Find out SMRAM information including SMRR base and SMRR size.
-
- @param SmrrBase SMRR base
- @param SmrrSize SMRR size
-
-**/
-VOID
-FindSmramInfo (
- OUT UINT32 *SmrrBase,
- OUT UINT32 *SmrrSize
- )
-{
- EFI_STATUS Status;
- UINTN Size;
- EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
- EFI_SMRAM_DESCRIPTOR *CurrentSmramRange;
- UINTN Index;
- UINT64 MaxSize;
- BOOLEAN Found;
- EFI_SMRAM_DESCRIPTOR SmramDescriptor;
-
- //
- // Get SMM Access Protocol
- //
- Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Get SMRAM information
- //
- Size = 0;
- Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);
- ASSERT (Status == EFI_BUFFER_TOO_SMALL);
-
- mSmmCpuSmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size);
- ASSERT (mSmmCpuSmramRanges != NULL);
-
- Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmmCpuSmramRanges);
- ASSERT_EFI_ERROR (Status);
-
- mSmmCpuSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
-
- //
- // Sort the mSmmCpuSmramRanges
- //
- QuickSort (mSmmCpuSmramRanges, mSmmCpuSmramRangeCount, sizeof (EFI_SMRAM_DESCRIPTOR), (BASE_SORT_COMPARE)CpuSmramRangeCompare, &SmramDescriptor);
-
- //
- // Find the largest SMRAM range between 1MB and 4GB that is at least 256K - 4K in size
- //
- CurrentSmramRange = NULL;
- for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < mSmmCpuSmramRangeCount; Index++) {
- //
- // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization
- //
- if ((mSmmCpuSmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
- continue;
- }
-
- if (mSmmCpuSmramRanges[Index].CpuStart >= BASE_1MB) {
- if ((mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize) <= SMRR_MAX_ADDRESS) {
- if (mSmmCpuSmramRanges[Index].PhysicalSize >= MaxSize) {
- MaxSize = mSmmCpuSmramRanges[Index].PhysicalSize;
- CurrentSmramRange = &mSmmCpuSmramRanges[Index];
- }
- }
- }
- }
-
- ASSERT (CurrentSmramRange != NULL);
-
- *SmrrBase = (UINT32)CurrentSmramRange->CpuStart;
- *SmrrSize = (UINT32)CurrentSmramRange->PhysicalSize;
-
- do {
- Found = FALSE;
- for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
- if ((mSmmCpuSmramRanges[Index].CpuStart < *SmrrBase) &&
- (*SmrrBase == (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize)))
- {
- *SmrrBase = (UINT32)mSmmCpuSmramRanges[Index].CpuStart;
- *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize);
- Found = TRUE;
- } else if (((*SmrrBase + *SmrrSize) == mSmmCpuSmramRanges[Index].CpuStart) && (mSmmCpuSmramRanges[Index].PhysicalSize > 0)) {
- *SmrrSize = (UINT32)(*SmrrSize + mSmmCpuSmramRanges[Index].PhysicalSize);
- Found = TRUE;
- }
- }
- } while (Found);
-
- DEBUG ((DEBUG_INFO, "SMRR Base: 0x%x, SMRR Size: 0x%x\n", *SmrrBase, *SmrrSize));
-}
-
-/**
-Configure SMM Code Access Check feature on an AP.
-SMM Feature Control MSR will be locked after configuration.
-
-@param[in,out] Buffer Pointer to private data buffer.
-**/
-VOID
-EFIAPI
-ConfigSmmCodeAccessCheckOnCurrentProcessor (
- IN OUT VOID *Buffer
- )
-{
- UINTN CpuIndex;
- UINT64 SmmFeatureControlMsr;
- UINT64 NewSmmFeatureControlMsr;
-
- //
- // Retrieve the CPU Index from the context passed in
- //
- CpuIndex = *(UINTN *)Buffer;
-
- //
- // Get the current SMM Feature Control MSR value
- //
- SmmFeatureControlMsr = SmmCpuFeaturesGetSmmRegister (CpuIndex, SmmRegFeatureControl);
-
- //
- // Compute the new SMM Feature Control MSR value
- //
- NewSmmFeatureControlMsr = SmmFeatureControlMsr;
- if (mSmmCodeAccessCheckEnable) {
- NewSmmFeatureControlMsr |= SMM_CODE_CHK_EN_BIT;
- if (FeaturePcdGet (PcdCpuSmmFeatureControlMsrLock)) {
- NewSmmFeatureControlMsr |= SMM_FEATURE_CONTROL_LOCK_BIT;
- }
- }
-
- //
- // Only set the SMM Feature Control MSR value if the new value is different than the current value
- //
- if (NewSmmFeatureControlMsr != SmmFeatureControlMsr) {
- SmmCpuFeaturesSetSmmRegister (CpuIndex, SmmRegFeatureControl, NewSmmFeatureControlMsr);
- }
-
- //
- // Release the spin lock user to serialize the updates to the SMM Feature Control MSR
- //
- ReleaseSpinLock (mConfigSmmCodeAccessCheckLock);
-}
-
-/**
-Configure SMM Code Access Check feature for all processors.
-SMM Feature Control MSR will be locked after configuration.
-**/
-VOID
-ConfigSmmCodeAccessCheck (
- VOID
- )
-{
- UINTN Index;
- EFI_STATUS Status;
-
- PERF_FUNCTION_BEGIN ();
-
- //
- // Check to see if the Feature Control MSR is supported on this CPU
- //
- Index = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu;
- if (!SmmCpuFeaturesIsSmmRegisterSupported (Index, SmmRegFeatureControl)) {
- mSmmCodeAccessCheckEnable = FALSE;
- PERF_FUNCTION_END ();
- return;
- }
-
- //
- // Check to see if the CPU supports the SMM Code Access Check feature
- // Do not access this MSR unless the CPU supports the SmmRegFeatureControl
- //
- if ((AsmReadMsr64 (EFI_MSR_SMM_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) == 0) {
- mSmmCodeAccessCheckEnable = FALSE;
- PERF_FUNCTION_END ();
- return;
- }
-
- //
- // Initialize the lock used to serialize the MSR programming in BSP and all APs
- //
- InitializeSpinLock (mConfigSmmCodeAccessCheckLock);
-
- //
- // Acquire Config SMM Code Access Check spin lock. The BSP will release the
- // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor().
- //
- AcquireSpinLock (mConfigSmmCodeAccessCheckLock);
-
- //
- // Enable SMM Code Access Check feature on the BSP.
- //
- ConfigSmmCodeAccessCheckOnCurrentProcessor (&Index);
-
- //
- // Enable SMM Code Access Check feature for the APs.
- //
- for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
- if (Index != gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) {
- if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID) {
- //
- // If this processor does not exist
- //
- continue;
- }
-
- //
- // Acquire Config SMM Code Access Check spin lock. The AP will release the
- // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor().
- //
- AcquireSpinLock (mConfigSmmCodeAccessCheckLock);
-
- //
- // Call SmmStartupThisAp() to enable SMM Code Access Check on an AP.
- //
- Status = gSmst->SmmStartupThisAp (ConfigSmmCodeAccessCheckOnCurrentProcessor, Index, &Index);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Wait for the AP to release the Config SMM Code Access Check spin lock.
- //
- while (!AcquireSpinLockOrFail (mConfigSmmCodeAccessCheckLock)) {
- CpuPause ();
- }
-
- //
- // Release the Config SMM Code Access Check spin lock.
- //
- ReleaseSpinLock (mConfigSmmCodeAccessCheckLock);
- }
- }
-
- PERF_FUNCTION_END ();
-}
-
-/**
- Allocate pages for code.
-
- @param[in] Pages Number of pages to be allocated.
-
- @return Allocated memory.
-**/
-VOID *
-AllocateCodePages (
- IN UINTN Pages
- )
-{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS Memory;
-
- if (Pages == 0) {
- return NULL;
- }
-
- Status = gSmst->SmmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, Pages, &Memory);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- return (VOID *)(UINTN)Memory;
-}
-
-/**
- Perform the remaining tasks.
-
-**/
-VOID
-PerformRemainingTasks (
- VOID
- )
-{
- if (mSmmReadyToLock) {
- PERF_FUNCTION_BEGIN ();
-
- //
- // Check if all Aps enter SMM. In Relaxed-AP Sync Mode, BSP will not wait for
- // all Aps arrive. However,PerformRemainingTasks() needs to wait all Aps arrive before calling
- // SetMemMapAttributes() and ConfigSmmCodeAccessCheck() when mSmmReadyToLock
- // is true. In SetMemMapAttributes(), SmmSetMemoryAttributesEx() will call
- // FlushTlbForAll() that need to start up the aps. So it need to let all
- // aps arrive. Same as SetMemMapAttributes(), ConfigSmmCodeAccessCheck()
- // also will start up the aps.
- //
- if (EFI_ERROR (SmmCpuRendezvous (NULL, TRUE))) {
- DEBUG ((DEBUG_ERROR, "PerformRemainingTasks: fail to wait for all AP check in SMM!\n"));
- }
-
- //
- // Start SMM Profile feature
- //
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- SmmProfileStart ();
- }
-
- //
- // Create a mix of 2MB and 4KB page table. Update some memory ranges absent and execute-disable.
- //
- InitPaging ();
-
- //
- // Mark critical region to be read-only in page table
- //
- SetMemMapAttributes ();
-
- if (IsRestrictedMemoryAccess ()) {
- //
- // For outside SMRAM, we only map SMM communication buffer or MMIO.
- //
- SetUefiMemMapAttributes ();
-
- //
- // Set page table itself to be read-only
- //
- SetPageTableAttributes ();
- }
-
- //
- // Configure SMM Code Access Check feature if available.
- //
- ConfigSmmCodeAccessCheck ();
-
- //
- // Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side
- // as the implementation is provided by platform.
- //
- PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0);
- SmmCpuFeaturesCompleteSmmReadyToLock ();
- PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0);
-
- //
- // Clean SMM ready to lock flag
- //
- mSmmReadyToLock = FALSE;
-
- PERF_FUNCTION_END ();
- }
-}
-
-/**
- Perform the pre tasks.
-
-**/
-VOID
-PerformPreTasks (
- VOID
- )
-{
- RestoreSmmConfigurationInS3 ();
+ return Status;
}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
index 3c4518d..8c4be7e 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
@@ -30,7 +30,8 @@
[Sources]
PiSmmCpuDxeSmm.c
- PiSmmCpuDxeSmm.h
+ PiSmmCpuCommon.c
+ PiSmmCpuCommon.h
MpService.c
SyncTimer.c
CpuS3.c
@@ -45,6 +46,7 @@
SmmMp.c
SmmMpPerf.h
SmmMpPerf.c
+ NonMmramMapDxeSmm.c
[Sources.Ia32]
Ia32/PageTbl.c
@@ -54,6 +56,7 @@
Ia32/SmiEntry.nasm
Ia32/SmiException.nasm
Ia32/Cet.nasm
+ Ia32/SmmFuncsArchDxeSmm.c
[Sources.X64]
X64/PageTbl.c
@@ -63,6 +66,7 @@
X64/SmiEntry.nasm
X64/SmiException.nasm
X64/Cet.nasm
+ X64/SmmFuncsArchDxeSmm.c
[Packages]
MdePkg/MdePkg.dec
@@ -80,7 +84,7 @@
MtrrLib
IoLib
TimerLib
- SmmServicesTableLib
+ MmServicesTableLib
MemoryAllocationLib
DebugAgentLib
HobLib
@@ -100,7 +104,6 @@
SmmCpuSyncLib
[Protocols]
- gEfiSmmAccess2ProtocolGuid ## CONSUMES
gEfiSmmConfigurationProtocolGuid ## PRODUCES
gEfiSmmCpuProtocolGuid ## PRODUCES
gEfiSmmReadyToLockProtocolGuid ## NOTIFY
@@ -109,6 +112,7 @@
gEfiMmMpProtocolGuid ## PRODUCES
gEdkiiSmmCpuRendezvousProtocolGuid ## PRODUCES
gEfiMpServiceProtocolGuid ## CONSUMES
+ gEfiSmmVariableProtocolGuid ## CONSUMES
[Guids]
gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is used for S3 boot.
@@ -116,6 +120,7 @@
gEfiMemoryAttributesTableGuid ## CONSUMES ## SystemTable
gSmmBaseHobGuid ## CONSUMES
gMpInformation2HobGuid ## CONSUMES # Assume the HOB must has been created
+ gEfiSmmSmramMemoryGuid
[FeaturePcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug ## CONSUMES
@@ -130,16 +135,15 @@
gUefiCpuPkgTokenSpaceGuid.PcdSmmApPerfLogEnable ## CONSUMES
[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2 ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout2 ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## SOMETIMES_PRODUCES
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmShadowStackSize ## SOMETIMES_CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitOnS3Resume ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c
new file mode 100644
index 0000000..6f59b49
--- /dev/null
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.c
@@ -0,0 +1,270 @@
+/** @file
+Agent Module to load other modules to deploy MM Entry Vector for X86 CPU.
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiSmmCpuCommon.h"
+
+//
+// TRUE to indicate it's the MM_STANDALONE MM CPU driver.
+// FALSE to indicate it's the DXE_SMM_DRIVER SMM CPU driver.
+//
+const BOOLEAN mIsStandaloneMm = TRUE;
+
+//
+// RemainingTasks Done flag
+//
+BOOLEAN mRemainingTasksDone = FALSE;
+
+/**
+ Check SmmProfile is enabled or not.
+
+ @return TRUE SmmProfile is enabled.
+ FALSE SmmProfile is not enabled.
+
+**/
+BOOLEAN
+IsSmmProfileEnabled (
+ VOID
+ )
+{
+ UINT64 SmmProfileSize;
+
+ GetSmmProfileData (&SmmProfileSize);
+ if (SmmProfileSize == 0) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Perform the remaining tasks.
+
+**/
+VOID
+PerformRemainingTasks (
+ VOID
+ )
+{
+ EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
+
+ if (!mRemainingTasksDone) {
+ PERF_FUNCTION_BEGIN ();
+
+ //
+ // gEdkiiPiSmmMemoryAttributesTableGuid should have been published after SmmCore dispatched all MM drivers (MmDriverDispatchHandler).
+ // Note: gEdkiiPiSmmMemoryAttributesTableGuid is not always installed since it depends on
+ // the memory protection attribute setting in MM Core.
+ //
+ SmmGetSystemConfigurationTable (&gEdkiiPiSmmMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
+
+ //
+ // Set critical region attribute in page table according to the MemoryAttributesTable
+ //
+ if (MemoryAttributesTable != NULL) {
+ SetMemMapAttributes (MemoryAttributesTable);
+ }
+
+ //
+ // Set page table itself to be read-only
+ //
+ SetPageTableAttributes ();
+
+ //
+ // Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side
+ // as the implementation is provided by platform.
+ //
+ PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0);
+ SmmCpuFeaturesCompleteSmmReadyToLock ();
+ PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0);
+
+ //
+ // Mark RemainingTasks Done flag to TRUE
+ //
+ mRemainingTasksDone = TRUE;
+
+ PERF_FUNCTION_END ();
+ }
+}
+
+/**
+ To get system port address of the SMI Command Port.
+
+**/
+VOID
+GetSmiCommandPort (
+ VOID
+ )
+{
+ mSmiCommandPort = 0xB2;
+ DEBUG ((DEBUG_INFO, "mSmiCommandPort = %x\n", mSmiCommandPort));
+}
+
+/**
+ Get SmmCpuSyncConfig data: RelaxedMode, SyncTimeout, SyncTimeout2.
+
+ @param[in,out] RelaxedMode It indicates if Relaxed CPU synchronization method or
+ traditional CPU synchronization method is used when processing an SMI.
+ @param[in,out] SyncTimeout It indicates the 1st BSP/AP synchronization timeout value in SMM.
+ @param[in,out] SyncTimeout2 It indicates the 2nd BSP/AP synchronization timeout value in SMM.
+
+ **/
+VOID
+GetSmmCpuSyncConfigData (
+ IN OUT BOOLEAN *RelaxedMode, OPTIONAL
+ IN OUT UINT64 *SyncTimeout, OPTIONAL
+ IN OUT UINT64 *SyncTimeout2 OPTIONAL
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ MM_CPU_SYNC_CONFIG *MmCpuSyncConfigHob;
+
+ MmCpuSyncConfigHob = NULL;
+
+ //
+ // Get MM_CPU_SYNC_CONFIG for Standalone MM init.
+ //
+ GuidHob = GetFirstGuidHob (&gMmCpuSyncConfigHobGuid);
+ ASSERT (GuidHob != NULL);
+ if (GuidHob != NULL) {
+ MmCpuSyncConfigHob = GET_GUID_HOB_DATA (GuidHob);
+ }
+
+ if (MmCpuSyncConfigHob != NULL) {
+ if (RelaxedMode != NULL) {
+ *RelaxedMode = ((MmCpuSyncConfigHob->RelaxedApMode == MmCpuSyncModeRelaxedAp) ? TRUE : FALSE);
+ }
+
+ if (SyncTimeout != NULL) {
+ *SyncTimeout = MmCpuSyncConfigHob->Timeout;
+ }
+
+ if (SyncTimeout2 != NULL) {
+ *SyncTimeout2 = MmCpuSyncConfigHob->Timeout2;
+ }
+ }
+}
+
+/**
+ Get ACPI S3 enable flag.
+
+**/
+VOID
+GetAcpiS3EnableFlag (
+ VOID
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ MM_ACPI_S3_ENABLE *MmAcpiS3EnableHob;
+
+ MmAcpiS3EnableHob = NULL;
+
+ //
+ // Get MM_ACPI_S3_ENABLE for Standalone MM init.
+ //
+ GuidHob = GetFirstGuidHob (&gMmAcpiS3EnableHobGuid);
+ ASSERT (GuidHob != NULL);
+ if (GuidHob != NULL) {
+ MmAcpiS3EnableHob = GET_GUID_HOB_DATA (GuidHob);
+ }
+
+ if (MmAcpiS3EnableHob != NULL) {
+ mAcpiS3Enable = MmAcpiS3EnableHob->AcpiS3Enable;
+ }
+}
+
+/**
+ Get the maximum number of logical processors supported by the system.
+
+ @retval The maximum number of logical processors supported by the system
+ is indicated by the return value.
+**/
+UINTN
+GetSupportedMaxLogicalProcessorNumber (
+ VOID
+ )
+{
+ ASSERT (FALSE);
+
+ return 0;
+}
+
+/**
+ Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION.
+
+ @param[out] NumberOfCpus Pointer to NumberOfCpus.
+ @param[out] MaxNumberOfCpus Pointer to MaxNumberOfCpus.
+
+ @retval ProcessorInfo Pointer to EFI_PROCESSOR_INFORMATION buffer.
+**/
+EFI_PROCESSOR_INFORMATION *
+GetMpInformationFromMpServices (
+ OUT UINTN *NumberOfCpus,
+ OUT UINTN *MaxNumberOfCpus
+ )
+{
+ ASSERT (FALSE);
+
+ return NULL;
+}
+
+/**
+ The module Entry Point of the CPU StandaloneMm driver.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the MM System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval Other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+PiCpuStandaloneMmEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PiSmmCpuEntryCommon ();
+
+ ASSERT_EFI_ERROR (Status);
+
+ if (mSmmProfileEnabled) {
+ //
+ // Get Software SMI
+ //
+ GetSmiCommandPort ();
+
+ //
+ // Initialize protected memory range for patching page table later.
+ //
+ InitProtectedMemRange ();
+
+ //
+ // Start SMM Profile feature
+ //
+ SmmProfileStart ();
+ }
+
+ //
+ // Install the SMM Configuration Protocol onto a new handle on the handle database.
+ // The entire SMM Configuration Protocol is allocated from SMRAM, so only a pointer
+ // to an SMRAM address will be present in the handle database
+ //
+ Status = gMmst->MmInstallProtocolInterface (
+ &gSmmCpuPrivate->SmmCpuHandle,
+ &gEfiSmmConfigurationProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gSmmCpuPrivate->SmmConfiguration
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf
new file mode 100644
index 0000000..d0ae5e7
--- /dev/null
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf
@@ -0,0 +1,133 @@
+## @file
+# PiSmmCpuStandaloneMm driver.
+# This Standalone MM driver performs SMM initialization, deploy SMM Entry Vector,
+# provides CPU specific services in SMM.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PiSmmCpuStandaloneMm
+ FILE_GUID = d88f894b-9287-4706-8b28-f716ae4d35c7
+ MODULE_TYPE = MM_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ ENTRY_POINT = PiCpuStandaloneMmEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = X64
+#
+
+[Sources]
+ PiSmmCpuStandaloneMm.c
+ PiSmmCpuCommon.c
+ PiSmmCpuCommon.h
+ MpService.c
+ SyncTimer.c
+ CpuS3.c
+ CpuService.c
+ CpuService.h
+ SmmProfile.c
+ SmmProfile.h
+ SmmProfileInternal.h
+ SmramSaveState.c
+ SmmCpuMemoryManagement.c
+ SmmMp.h
+ SmmMp.c
+ SmmMpPerf.h
+ SmmMpPerf.c
+ NonMmramMapStandaloneMm.c
+
+[Sources.X64]
+ X64/PageTbl.c
+ X64/SmmFuncsArch.c
+ X64/SmmProfileArch.c
+ X64/SmmProfileArch.h
+ X64/SmiEntry.nasm
+ X64/SmiException.nasm
+ X64/Cet.nasm
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ StandaloneMmDriverEntryPoint
+ PcdLib
+ DebugLib
+ BaseLib
+ SynchronizationLib
+ BaseMemoryLib
+ MtrrLib
+ IoLib
+ TimerLib
+ MmServicesTableLib
+ MemoryAllocationLib
+ DebugAgentLib
+ HobLib
+ PciLib
+ LocalApicLib
+ SmmCpuPlatformHookLib
+ CpuExceptionHandlerLib
+ CpuLib
+ ReportStatusCodeLib
+ SmmCpuFeaturesLib
+ PeCoffGetEntryPointLib
+ PerformanceLib
+ CpuPageTableLib
+ MmSaveStateLib
+ SmmCpuSyncLib
+
+[Protocols]
+ gEfiSmmConfigurationProtocolGuid ## PRODUCES
+ gEfiSmmCpuProtocolGuid ## PRODUCES
+ gEfiSmmReadyToLockProtocolGuid ## NOTIFY
+ gEfiSmmCpuServiceProtocolGuid ## PRODUCES
+ gEdkiiSmmMemoryAttributeProtocolGuid ## PRODUCES
+ gEfiMmMpProtocolGuid ## PRODUCES
+ gEdkiiSmmCpuRendezvousProtocolGuid ## PRODUCES
+ gEfiSmmVariableProtocolGuid ## CONSUMES
+
+[Guids]
+ gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is used for S3 boot.
+ gEdkiiPiSmmMemoryAttributesTableGuid ## CONSUMES ## SystemTable
+ gSmmBaseHobGuid ## CONSUMES
+ gMpInformation2HobGuid ## CONSUMES # Assume the HOB must has been created
+ gEfiSmmSmramMemoryGuid
+ gMmProfileDataHobGuid
+ gMmAcpiS3EnableHobGuid
+ gMmCpuSyncConfigHobGuid
+
+[FeaturePcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugSupport ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileRingBuffer ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmFeatureControlMsrLock ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdSmmApPerfLogEnable ## CONSUMES
+
+[Pcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmShadowStackSize ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask ## CONSUMES
+
+[FixedPcd]
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmMpTokenCountPerChunk ## CONSUMES
+
+[Depex]
+ TRUE
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
index b8c356b..9c2fe16 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
@@ -1,30 +1,11 @@
/** @file
-Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
-
-//
-// attributes for reserved memory before it is promoted to system memory
-//
-#define EFI_MEMORY_PRESENT 0x0100000000000000ULL
-#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL
-#define EFI_MEMORY_TESTED 0x0400000000000000ULL
-
-#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
- ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
-
-EFI_MEMORY_DESCRIPTOR *mUefiMemoryMap;
-UINTN mUefiMemoryMapSize;
-UINTN mUefiDescriptorSize;
-
-EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mGcdMemSpace = NULL;
-UINTN mGcdMemNumberOfDesc = 0;
-
-EFI_MEMORY_ATTRIBUTES_TABLE *mUefiMemoryAttributesTable = NULL;
+#include "PiSmmCpuCommon.h"
BOOLEAN mIsShadowStack = FALSE;
BOOLEAN m5LevelPagingNeeded = FALSE;
@@ -774,9 +755,9 @@ SmmGetSystemConfigurationTable (
ASSERT (Table != NULL);
*Table = NULL;
- for (Index = 0; Index < gSmst->NumberOfTableEntries; Index++) {
- if (CompareGuid (TableGuid, &(gSmst->SmmConfigurationTable[Index].VendorGuid))) {
- *Table = gSmst->SmmConfigurationTable[Index].VendorTable;
+ for (Index = 0; Index < gMmst->NumberOfTableEntries; Index++) {
+ if (CompareGuid (TableGuid, &(gMmst->MmConfigurationTable[Index].VendorGuid))) {
+ *Table = gMmst->MmConfigurationTable[Index].VendorTable;
return EFI_SUCCESS;
}
}
@@ -1012,31 +993,29 @@ SetMemMapWithNonPresentRange (
/**
This function sets memory attribute according to MemoryAttributesTable.
+
+ @param MemoryAttributesTable A pointer to the buffer of SmmMemoryAttributesTable.
+
**/
VOID
SetMemMapAttributes (
- VOID
+ EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable
)
{
- EFI_MEMORY_DESCRIPTOR *MemoryMap;
- EFI_MEMORY_DESCRIPTOR *MemoryMapStart;
- UINTN MemoryMapEntryCount;
- UINTN DescriptorSize;
- UINTN Index;
- EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
- UINTN PageTable;
- EFI_STATUS Status;
- IA32_MAP_ENTRY *Map;
- UINTN Count;
- UINT64 MemoryAttribute;
- BOOLEAN WriteProtect;
- BOOLEAN CetEnabled;
-
- SmmGetSystemConfigurationTable (&gEdkiiPiSmmMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
- if (MemoryAttributesTable == NULL) {
- DEBUG ((DEBUG_INFO, "MemoryAttributesTable - NULL\n"));
- return;
- }
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;
+ EFI_MEMORY_DESCRIPTOR *MemoryMapStart;
+ UINTN MemoryMapEntryCount;
+ UINTN DescriptorSize;
+ UINTN Index;
+ UINTN PageTable;
+ EFI_STATUS Status;
+ IA32_MAP_ENTRY *Map;
+ UINTN Count;
+ UINT64 MemoryAttribute;
+ BOOLEAN WriteProtect;
+ BOOLEAN CetEnabled;
+
+ ASSERT (MemoryAttributesTable != NULL);
PERF_FUNCTION_BEGIN ();
@@ -1119,464 +1098,6 @@ SetMemMapAttributes (
}
/**
- Sort memory map entries based upon PhysicalStart, from low to high.
-
- @param MemoryMap A pointer to the buffer in which firmware places
- the current memory map.
- @param MemoryMapSize Size, in bytes, of the MemoryMap buffer.
- @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-**/
-STATIC
-VOID
-SortMemoryMap (
- IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
- IN UINTN MemoryMapSize,
- IN UINTN DescriptorSize
- )
-{
- EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
- EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry;
- EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
- EFI_MEMORY_DESCRIPTOR TempMemoryMap;
-
- MemoryMapEntry = MemoryMap;
- NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
- MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
- while (MemoryMapEntry < MemoryMapEnd) {
- while (NextMemoryMapEntry < MemoryMapEnd) {
- if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {
- CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
- CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
- CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR));
- }
-
- NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
- }
-
- MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
- NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
- }
-}
-
-/**
- Return if a UEFI memory page should be marked as not present in SMM page table.
- If the memory map entries type is
- EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory,
- EfiUnusableMemory, EfiACPIReclaimMemory, return TRUE.
- Or return FALSE.
-
- @param[in] MemoryMap A pointer to the memory descriptor.
-
- @return TRUE The memory described will be marked as not present in SMM page table.
- @return FALSE The memory described will not be marked as not present in SMM page table.
-**/
-BOOLEAN
-IsUefiPageNotPresent (
- IN EFI_MEMORY_DESCRIPTOR *MemoryMap
- )
-{
- switch (MemoryMap->Type) {
- case EfiLoaderCode:
- case EfiLoaderData:
- case EfiBootServicesCode:
- case EfiBootServicesData:
- case EfiConventionalMemory:
- case EfiUnusableMemory:
- case EfiACPIReclaimMemory:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-/**
- Merge continuous memory map entries whose type is
- EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory,
- EfiUnusableMemory, EfiACPIReclaimMemory, because the memory described by
- these entries will be set as NOT present in SMM page table.
-
- @param[in, out] MemoryMap A pointer to the buffer in which firmware places
- the current memory map.
- @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the
- MemoryMap buffer. On input, this is the size of
- the current memory map. On output,
- it is the size of new memory map after merge.
- @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
-**/
-STATIC
-VOID
-MergeMemoryMapForNotPresentEntry (
- IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
- IN OUT UINTN *MemoryMapSize,
- IN UINTN DescriptorSize
- )
-{
- EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
- EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
- UINT64 MemoryBlockLength;
- EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry;
- EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry;
-
- MemoryMapEntry = MemoryMap;
- NewMemoryMapEntry = MemoryMap;
- MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize);
- while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
- CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
- NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
-
- do {
- MemoryBlockLength = (UINT64)(EFI_PAGES_TO_SIZE ((UINTN)MemoryMapEntry->NumberOfPages));
- if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&
- IsUefiPageNotPresent (MemoryMapEntry) && IsUefiPageNotPresent (NextMemoryMapEntry) &&
- ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart))
- {
- MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
- if (NewMemoryMapEntry != MemoryMapEntry) {
- NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;
- }
-
- NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
- continue;
- } else {
- MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
- break;
- }
- } while (TRUE);
-
- MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
- NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);
- }
-
- *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap;
-
- return;
-}
-
-/**
- This function caches the GCD memory map information.
-**/
-VOID
-GetGcdMemoryMap (
- VOID
- )
-{
- UINTN NumberOfDescriptors;
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemSpaceMap;
- EFI_STATUS Status;
- UINTN Index;
-
- Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap);
- if (EFI_ERROR (Status)) {
- return;
- }
-
- mGcdMemNumberOfDesc = 0;
- for (Index = 0; Index < NumberOfDescriptors; Index++) {
- if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) &&
- ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
- (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
- )
- {
- mGcdMemNumberOfDesc++;
- }
- }
-
- mGcdMemSpace = AllocateZeroPool (mGcdMemNumberOfDesc * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR));
- ASSERT (mGcdMemSpace != NULL);
- if (mGcdMemSpace == NULL) {
- mGcdMemNumberOfDesc = 0;
- gBS->FreePool (MemSpaceMap);
- return;
- }
-
- mGcdMemNumberOfDesc = 0;
- for (Index = 0; Index < NumberOfDescriptors; Index++) {
- if ((MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) &&
- ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
- (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
- )
- {
- CopyMem (
- &mGcdMemSpace[mGcdMemNumberOfDesc],
- &MemSpaceMap[Index],
- sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR)
- );
- mGcdMemNumberOfDesc++;
- }
- }
-
- gBS->FreePool (MemSpaceMap);
-}
-
-/**
- Get UEFI MemoryAttributesTable.
-**/
-VOID
-GetUefiMemoryAttributesTable (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
- UINTN MemoryAttributesTableSize;
-
- Status = EfiGetSystemConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
- if (!EFI_ERROR (Status) && (MemoryAttributesTable != NULL)) {
- MemoryAttributesTableSize = sizeof (EFI_MEMORY_ATTRIBUTES_TABLE) + MemoryAttributesTable->DescriptorSize * MemoryAttributesTable->NumberOfEntries;
- mUefiMemoryAttributesTable = AllocateCopyPool (MemoryAttributesTableSize, MemoryAttributesTable);
- ASSERT (mUefiMemoryAttributesTable != NULL);
- }
-}
-
-/**
- This function caches the UEFI memory map information.
-**/
-VOID
-GetUefiMemoryMap (
- VOID
- )
-{
- EFI_STATUS Status;
- UINTN MapKey;
- UINT32 DescriptorVersion;
- EFI_MEMORY_DESCRIPTOR *MemoryMap;
- UINTN UefiMemoryMapSize;
-
- DEBUG ((DEBUG_INFO, "GetUefiMemoryMap\n"));
-
- UefiMemoryMapSize = 0;
- MemoryMap = NULL;
- Status = gBS->GetMemoryMap (
- &UefiMemoryMapSize,
- MemoryMap,
- &MapKey,
- &mUefiDescriptorSize,
- &DescriptorVersion
- );
- ASSERT (Status == EFI_BUFFER_TOO_SMALL);
-
- do {
- Status = gBS->AllocatePool (EfiBootServicesData, UefiMemoryMapSize, (VOID **)&MemoryMap);
- ASSERT (MemoryMap != NULL);
- if (MemoryMap == NULL) {
- return;
- }
-
- Status = gBS->GetMemoryMap (
- &UefiMemoryMapSize,
- MemoryMap,
- &MapKey,
- &mUefiDescriptorSize,
- &DescriptorVersion
- );
- if (EFI_ERROR (Status)) {
- gBS->FreePool (MemoryMap);
- MemoryMap = NULL;
- }
- } while (Status == EFI_BUFFER_TOO_SMALL);
-
- if (MemoryMap == NULL) {
- return;
- }
-
- SortMemoryMap (MemoryMap, UefiMemoryMapSize, mUefiDescriptorSize);
- MergeMemoryMapForNotPresentEntry (MemoryMap, &UefiMemoryMapSize, mUefiDescriptorSize);
-
- mUefiMemoryMapSize = UefiMemoryMapSize;
- mUefiMemoryMap = AllocateCopyPool (UefiMemoryMapSize, MemoryMap);
- ASSERT (mUefiMemoryMap != NULL);
-
- gBS->FreePool (MemoryMap);
-
- //
- // Get additional information from GCD memory map.
- //
- GetGcdMemoryMap ();
-
- //
- // Get UEFI memory attributes table.
- //
- GetUefiMemoryAttributesTable ();
-}
-
-/**
- This function sets UEFI memory attribute according to UEFI memory map.
-
- The normal memory region is marked as not present, such as
- EfiLoaderCode/Data, EfiBootServicesCode/Data, EfiConventionalMemory,
- EfiUnusableMemory, EfiACPIReclaimMemory.
-**/
-VOID
-SetUefiMemMapAttributes (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_MEMORY_DESCRIPTOR *MemoryMap;
- UINTN MemoryMapEntryCount;
- UINTN Index;
- EFI_MEMORY_DESCRIPTOR *Entry;
- BOOLEAN WriteProtect;
- BOOLEAN CetEnabled;
-
- PERF_FUNCTION_BEGIN ();
-
- DEBUG ((DEBUG_INFO, "SetUefiMemMapAttributes\n"));
-
- WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled);
-
- if (mUefiMemoryMap != NULL) {
- MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize;
- MemoryMap = mUefiMemoryMap;
- for (Index = 0; Index < MemoryMapEntryCount; Index++) {
- if (IsUefiPageNotPresent (MemoryMap)) {
- Status = SmmSetMemoryAttributes (
- MemoryMap->PhysicalStart,
- EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages),
- EFI_MEMORY_RP
- );
- DEBUG ((
- DEBUG_INFO,
- "UefiMemory protection: 0x%lx - 0x%lx %r\n",
- MemoryMap->PhysicalStart,
- MemoryMap->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages),
- Status
- ));
- }
-
- MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize);
- }
- }
-
- //
- // Do not free mUefiMemoryMap, it will be checked in IsSmmCommBufferForbiddenAddress().
- //
-
- //
- // Set untested memory as not present.
- //
- if (mGcdMemSpace != NULL) {
- for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) {
- Status = SmmSetMemoryAttributes (
- mGcdMemSpace[Index].BaseAddress,
- mGcdMemSpace[Index].Length,
- EFI_MEMORY_RP
- );
- DEBUG ((
- DEBUG_INFO,
- "GcdMemory protection: 0x%lx - 0x%lx %r\n",
- mGcdMemSpace[Index].BaseAddress,
- mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length,
- Status
- ));
- }
- }
-
- //
- // Do not free mGcdMemSpace, it will be checked in IsSmmCommBufferForbiddenAddress().
- //
-
- //
- // Set UEFI runtime memory with EFI_MEMORY_RO as not present.
- //
- if (mUefiMemoryAttributesTable != NULL) {
- Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1);
- for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {
- if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) {
- if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
- Status = SmmSetMemoryAttributes (
- Entry->PhysicalStart,
- EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages),
- EFI_MEMORY_RP
- );
- DEBUG ((
- DEBUG_INFO,
- "UefiMemoryAttribute protection: 0x%lx - 0x%lx %r\n",
- Entry->PhysicalStart,
- Entry->PhysicalStart + (UINT64)EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages),
- Status
- ));
- }
- }
-
- Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);
- }
- }
-
- WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled);
-
- //
- // Do not free mUefiMemoryAttributesTable, it will be checked in IsSmmCommBufferForbiddenAddress().
- //
-
- PERF_FUNCTION_END ();
-}
-
-/**
- Return if the Address is forbidden as SMM communication buffer.
-
- @param[in] Address the address to be checked
-
- @return TRUE The address is forbidden as SMM communication buffer.
- @return FALSE The address is allowed as SMM communication buffer.
-**/
-BOOLEAN
-IsSmmCommBufferForbiddenAddress (
- IN UINT64 Address
- )
-{
- EFI_MEMORY_DESCRIPTOR *MemoryMap;
- UINTN MemoryMapEntryCount;
- UINTN Index;
- EFI_MEMORY_DESCRIPTOR *Entry;
-
- if (mUefiMemoryMap != NULL) {
- MemoryMap = mUefiMemoryMap;
- MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize;
- for (Index = 0; Index < MemoryMapEntryCount; Index++) {
- if (IsUefiPageNotPresent (MemoryMap)) {
- if ((Address >= MemoryMap->PhysicalStart) &&
- (Address < MemoryMap->PhysicalStart + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages)))
- {
- return TRUE;
- }
- }
-
- MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize);
- }
- }
-
- if (mGcdMemSpace != NULL) {
- for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) {
- if ((Address >= mGcdMemSpace[Index].BaseAddress) &&
- (Address < mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length))
- {
- return TRUE;
- }
- }
- }
-
- if (mUefiMemoryAttributesTable != NULL) {
- Entry = (EFI_MEMORY_DESCRIPTOR *)(mUefiMemoryAttributesTable + 1);
- for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {
- if ((Entry->Type == EfiRuntimeServicesCode) || (Entry->Type == EfiRuntimeServicesData)) {
- if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
- if ((Address >= Entry->PhysicalStart) &&
- (Address < Entry->PhysicalStart + LShiftU64 (Entry->NumberOfPages, EFI_PAGE_SHIFT)))
- {
- return TRUE;
- }
-
- Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);
- }
- }
- }
- }
-
- return FALSE;
-}
-
-/**
This function set given attributes of the memory region specified by
BaseAddress and Length.
@@ -1653,30 +1174,25 @@ EdkiiSmmClearMemoryAttributes (
@param[in] PagingMode The paging mode.
@param[in] LinearAddress The start of the linear address range.
@param[in] Length The length of the linear address range.
+ @param[in] MapAttribute The MapAttribute of the linear address range
+ @param[in] MapMask The MapMask used for attribute. The corresponding field in Attribute is ignored if that in MapMask is 0.
**/
VOID
GenPageTable (
- IN OUT UINTN *PageTable,
- IN PAGING_MODE PagingMode,
- IN UINT64 LinearAddress,
- IN UINT64 Length
+ IN OUT UINTN *PageTable,
+ IN PAGING_MODE PagingMode,
+ IN UINT64 LinearAddress,
+ IN UINT64 Length,
+ IN IA32_MAP_ATTRIBUTE MapAttribute,
+ IN IA32_MAP_ATTRIBUTE MapMask
)
{
- RETURN_STATUS Status;
- UINTN PageTableBufferSize;
- VOID *PageTableBuffer;
- IA32_MAP_ATTRIBUTE MapAttribute;
- IA32_MAP_ATTRIBUTE MapMask;
-
- MapMask.Uint64 = MAX_UINT64;
- MapAttribute.Uint64 = mAddressEncMask|LinearAddress;
- MapAttribute.Bits.Present = 1;
- MapAttribute.Bits.ReadWrite = 1;
- MapAttribute.Bits.UserSupervisor = 1;
- MapAttribute.Bits.Accessed = 1;
- MapAttribute.Bits.Dirty = 1;
- PageTableBufferSize = 0;
+ RETURN_STATUS Status;
+ UINTN PageTableBufferSize;
+ VOID *PageTableBuffer;
+
+ PageTableBufferSize = 0;
Status = PageTableMap (
PageTable,
@@ -1690,7 +1206,6 @@ GenPageTable (
NULL
);
if (Status == RETURN_BUFFER_TOO_SMALL) {
- DEBUG ((DEBUG_INFO, "GenSMMPageTable: 0x%x bytes needed for initial SMM page table\n", PageTableBufferSize));
PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (PageTableBufferSize));
ASSERT (PageTableBuffer != NULL);
Status = PageTableMap (
@@ -1725,37 +1240,85 @@ GenSmmPageTable (
IN UINT8 PhysicalAddressBits
)
{
- UINTN PageTable;
- RETURN_STATUS Status;
- UINTN GuardPage;
- UINTN Index;
- UINT64 Length;
- PAGING_MODE SmramPagingMode;
+ UINTN PageTable;
+ UINTN Index;
+ MM_CPU_MEMORY_REGION *MemoryRegion;
+ UINTN MemoryRegionCount;
+ IA32_MAP_ATTRIBUTE MapAttribute;
+ IA32_MAP_ATTRIBUTE MapMask;
+ RETURN_STATUS Status;
+ UINTN GuardPage;
- PageTable = 0;
- Length = LShiftU64 (1, PhysicalAddressBits);
- ASSERT (Length > mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize);
+ PageTable = 0;
+ MemoryRegion = NULL;
+ MemoryRegionCount = 0;
+ MapMask.Uint64 = MAX_UINT64;
- if (sizeof (UINTN) == sizeof (UINT64)) {
- SmramPagingMode = m5LevelPagingNeeded ? Paging5Level4KB : Paging4Level4KB;
- } else {
- SmramPagingMode = PagingPae4KB;
+ //
+ // 1. Create NonMmram MemoryRegion
+ //
+ CreateNonMmramMemMap (PhysicalAddressBits, &MemoryRegion, &MemoryRegionCount);
+ ASSERT (MemoryRegion != NULL && MemoryRegionCount != 0);
+
+ //
+ // 2. Gen NonMmram MemoryRegion PageTable
+ //
+ for (Index = 0; Index < MemoryRegionCount; Index++) {
+ ASSERT (MemoryRegion[Index].Base % SIZE_4KB == 0);
+ ASSERT (MemoryRegion[Index].Length % EFI_PAGE_SIZE == 0);
+
+ //
+ // Set the MapAttribute
+ //
+ MapAttribute.Uint64 = mAddressEncMask|MemoryRegion[Index].Base;
+ MapAttribute.Bits.Present = 1;
+ MapAttribute.Bits.ReadWrite = 1;
+ MapAttribute.Bits.UserSupervisor = 1;
+ MapAttribute.Bits.Accessed = 1;
+ MapAttribute.Bits.Dirty = 1;
+
+ //
+ // Update the MapAttribute according MemoryRegion[Index].Attribute
+ //
+ if ((MemoryRegion[Index].Attribute & EFI_MEMORY_RO) != 0) {
+ MapAttribute.Bits.ReadWrite = 0;
+ }
+
+ if ((MemoryRegion[Index].Attribute & EFI_MEMORY_XP) != 0) {
+ if (mXdSupported) {
+ MapAttribute.Bits.Nx = 1;
+ }
+ }
+
+ GenPageTable (&PageTable, PagingMode, MemoryRegion[Index].Base, (UINTN)MemoryRegion[Index].Length, MapAttribute, MapMask);
}
- ASSERT (mCpuHotPlugData.SmrrBase % SIZE_4KB == 0);
- ASSERT (mCpuHotPlugData.SmrrSize % SIZE_4KB == 0);
- GenPageTable (&PageTable, PagingMode, 0, mCpuHotPlugData.SmrrBase);
+ //
+ // Free the MemoryRegion after usage
+ //
+ if (MemoryRegion != NULL) {
+ FreePool (MemoryRegion);
+ }
//
- // Map smram range in 4K page granularity to avoid subsequent page split when smm ready to lock.
- // If BSP are splitting the 1G/2M paging entries to 512 2M/4K paging entries, and all APs are
- // still running in SMI at the same time, which might access the affected linear-address range
- // between the time of modification and the time of invalidation access. That will be a potential
- // problem leading exception happen.
+ // 3. Gen MMRAM Range PageTable
//
- GenPageTable (&PageTable, SmramPagingMode, mCpuHotPlugData.SmrrBase, mCpuHotPlugData.SmrrSize);
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
+ ASSERT (mSmmCpuSmramRanges[Index].CpuStart % SIZE_4KB == 0);
+ ASSERT (mSmmCpuSmramRanges[Index].PhysicalSize % EFI_PAGE_SIZE == 0);
- GenPageTable (&PageTable, PagingMode, mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize, Length - mCpuHotPlugData.SmrrBase - mCpuHotPlugData.SmrrSize);
+ //
+ // Set the MapAttribute
+ //
+ MapAttribute.Uint64 = mAddressEncMask|mSmmCpuSmramRanges[Index].CpuStart;
+ MapAttribute.Bits.Present = 1;
+ MapAttribute.Bits.ReadWrite = 1;
+ MapAttribute.Bits.UserSupervisor = 1;
+ MapAttribute.Bits.Accessed = 1;
+ MapAttribute.Bits.Dirty = 1;
+
+ GenPageTable (&PageTable, PagingMode, mSmmCpuSmramRanges[Index].CpuStart, mSmmCpuSmramRanges[Index].PhysicalSize, MapAttribute, MapMask);
+ }
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
//
@@ -1923,31 +1486,14 @@ IfReadOnlyPageTableNeeded (
{
//
// Don't mark page table memory as read-only if
- // - no restriction on access to non-SMRAM memory; or
// - SMM heap guard feature enabled; or
// BIT2: SMM page guard enabled
// BIT3: SMM pool guard enabled
// - SMM profile feature enabled
//
- if (!IsRestrictedMemoryAccess () ||
- ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) ||
- FeaturePcdGet (PcdCpuSmmProfileEnable))
+ if (((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) ||
+ mSmmProfileEnabled)
{
- if (sizeof (UINTN) == sizeof (UINT64)) {
- //
- // Restriction on access to non-SMRAM memory and heap guard could not be enabled at the same time.
- //
- ASSERT (
- !(IsRestrictedMemoryAccess () &&
- (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0)
- );
-
- //
- // Restriction on access to non-SMRAM memory and SMM profile could not be enabled at the same time.
- //
- ASSERT (!(IsRestrictedMemoryAccess () && FeaturePcdGet (PcdCpuSmmProfileEnable)));
- }
-
return FALSE;
}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c
index 6cc5f01..f839d1a 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMp.c
@@ -1,13 +1,13 @@
/** @file
SMM MP protocol implementation
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2019 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
#include "SmmMp.h"
///
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c
index 6d5d2b2..723d0da 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmMpPerf.c
@@ -1,13 +1,13 @@
/** @file
SMM MP perf-logging implementation
-Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2023 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
#define SMM_MP_PERF_PROCEDURE_NAME(procedure) # procedure
GLOBAL_REMOVE_IF_UNREFERENCED
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
index 8142d3c..ee64d6b 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
@@ -1,14 +1,14 @@
/** @file
Enable SMM profile.
-Copyright (c) 2012 - 2023, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017 - 2020, AMD Incorporated. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
#include "SmmProfileInternal.h"
UINT32 mSmmProfileCr3;
@@ -41,6 +41,11 @@ BOOLEAN mXdEnabled = FALSE;
BOOLEAN mBtsSupported = TRUE;
//
+// The flag indicates if SMM profile is enabled.
+//
+BOOLEAN mSmmProfileEnabled = FALSE;
+
+//
// The flag indicates if SMM profile starts to record data.
//
BOOLEAN mSmmProfileStart = FALSE;
@@ -298,41 +303,35 @@ IsInSmmRanges (
}
/**
- Check if the memory address will be mapped by 4KB-page.
+ Check if the SMM profile page fault address above 4GB is in protected range or not.
- @param Address The address of Memory.
- @param Nx The flag indicates if the memory is execute-disable.
+ @param[in] Address The address of Memory.
+ @param[out] Nx The flag indicates if the memory is execute-disable.
+
+ @retval TRUE The input address is in protected range.
+ @retval FALSE The input address is not in protected range.
**/
BOOLEAN
-IsAddressValid (
- IN EFI_PHYSICAL_ADDRESS Address,
- IN BOOLEAN *Nx
+IsSmmProfilePFAddressAbove4GValid (
+ IN EFI_PHYSICAL_ADDRESS Address,
+ OUT BOOLEAN *Nx
)
{
UINTN Index;
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- //
- // Check configuration
- //
- for (Index = 0; Index < mProtectionMemRangeCount; Index++) {
- if ((Address >= mProtectionMemRange[Index].Range.Base) && (Address < mProtectionMemRange[Index].Range.Top)) {
- *Nx = mProtectionMemRange[Index].Nx;
- return mProtectionMemRange[Index].Present;
- }
- }
-
- *Nx = TRUE;
- return FALSE;
- } else {
- *Nx = TRUE;
- if (IsInSmmRanges (Address)) {
- *Nx = FALSE;
+ //
+ // Check configuration
+ //
+ for (Index = 0; Index < mProtectionMemRangeCount; Index++) {
+ if ((Address >= mProtectionMemRange[Index].Range.Base) && (Address < mProtectionMemRange[Index].Range.Top)) {
+ *Nx = mProtectionMemRange[Index].Nx;
+ return mProtectionMemRange[Index].Present;
}
-
- return TRUE;
}
+
+ *Nx = TRUE;
+ return FALSE;
}
/**
@@ -348,7 +347,7 @@ IsAddressSplit (
{
UINTN Index;
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ if (mSmmProfileEnabled) {
//
// Check configuration
//
@@ -410,108 +409,109 @@ InitProtectedMemRange (
VOID
)
{
- UINTN Index;
- UINTN NumberOfDescriptors;
- UINTN NumberOfAddedDescriptors;
- UINTN NumberOfProtectRange;
- UINTN NumberOfSpliteRange;
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
- UINTN TotalSize;
- EFI_PHYSICAL_ADDRESS ProtectBaseAddress;
- EFI_PHYSICAL_ADDRESS ProtectEndAddress;
- EFI_PHYSICAL_ADDRESS Top2MBAlignedAddress;
- EFI_PHYSICAL_ADDRESS Base2MBAlignedAddress;
- UINT64 High4KBPageSize;
- UINT64 Low4KBPageSize;
- MEMORY_PROTECTION_RANGE MemProtectionRange;
-
- NumberOfDescriptors = 0;
+ UINTN Index;
+ MM_CPU_MEMORY_REGION *MemoryRegion;
+ UINTN MemoryRegionCount;
+ UINTN NumberOfAddedDescriptors;
+ UINTN NumberOfProtectRange;
+ UINTN NumberOfSpliteRange;
+ UINTN TotalSize;
+ EFI_PHYSICAL_ADDRESS ProtectBaseAddress;
+ EFI_PHYSICAL_ADDRESS ProtectEndAddress;
+ EFI_PHYSICAL_ADDRESS Top2MBAlignedAddress;
+ EFI_PHYSICAL_ADDRESS Base2MBAlignedAddress;
+ UINT64 High4KBPageSize;
+ UINT64 Low4KBPageSize;
+ MEMORY_PROTECTION_RANGE MemProtectionRange;
+
+ MemoryRegion = NULL;
+ MemoryRegionCount = 0;
NumberOfAddedDescriptors = mSmmCpuSmramRangeCount;
NumberOfSpliteRange = 0;
- MemorySpaceMap = NULL;
//
- // Get MMIO ranges from GCD and add them into protected memory ranges.
+ // Create extended protection MemoryRegion and add them into protected memory ranges.
+ // Retrieve the accessible regions when SMM profile is enabled.
+ // In SMM: only MMIO is accessible.
+ // In MM: all regions described by resource HOBs are accessible.
//
- gDS->GetMemorySpaceMap (
- &NumberOfDescriptors,
- &MemorySpaceMap
- );
- for (Index = 0; Index < NumberOfDescriptors; Index++) {
- if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {
- NumberOfAddedDescriptors++;
- }
- }
+ CreateExtendedProtectionRange (&MemoryRegion, &MemoryRegionCount);
+ ASSERT (MemoryRegion != NULL);
- if (NumberOfAddedDescriptors != 0) {
- TotalSize = NumberOfAddedDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate);
- mProtectionMemRange = (MEMORY_PROTECTION_RANGE *)AllocateZeroPool (TotalSize);
- ASSERT (mProtectionMemRange != NULL);
- mProtectionMemRangeCount = TotalSize / sizeof (MEMORY_PROTECTION_RANGE);
+ NumberOfAddedDescriptors += MemoryRegionCount;
- //
- // Copy existing ranges.
- //
- CopyMem (mProtectionMemRange, mProtectionMemRangeTemplate, sizeof (mProtectionMemRangeTemplate));
+ ASSERT (NumberOfAddedDescriptors != 0);
- //
- // Create split ranges which come from protected ranges.
- //
- TotalSize = (TotalSize / sizeof (MEMORY_PROTECTION_RANGE)) * sizeof (MEMORY_RANGE);
- mSplitMemRange = (MEMORY_RANGE *)AllocateZeroPool (TotalSize);
- ASSERT (mSplitMemRange != NULL);
+ TotalSize = NumberOfAddedDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate);
+ mProtectionMemRange = (MEMORY_PROTECTION_RANGE *)AllocateZeroPool (TotalSize);
+ ASSERT (mProtectionMemRange != NULL);
+ mProtectionMemRangeCount = TotalSize / sizeof (MEMORY_PROTECTION_RANGE);
- //
- // Create SMM ranges which are set to present and execution-enable.
- //
- NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE);
- for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
- if ((mSmmCpuSmramRanges[Index].CpuStart >= mProtectionMemRange[0].Range.Base) &&
- (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize < mProtectionMemRange[0].Range.Top))
- {
- //
- // If the address have been already covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz
- //
- break;
- }
+ //
+ // Copy existing ranges.
+ //
+ CopyMem (mProtectionMemRange, mProtectionMemRangeTemplate, sizeof (mProtectionMemRangeTemplate));
- mProtectionMemRange[NumberOfProtectRange].Range.Base = mSmmCpuSmramRanges[Index].CpuStart;
- mProtectionMemRange[NumberOfProtectRange].Range.Top = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize;
- mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
- mProtectionMemRange[NumberOfProtectRange].Nx = FALSE;
- NumberOfProtectRange++;
+ //
+ // Create split ranges which come from protected ranges.
+ //
+ TotalSize = (TotalSize / sizeof (MEMORY_PROTECTION_RANGE)) * sizeof (MEMORY_RANGE);
+ mSplitMemRange = (MEMORY_RANGE *)AllocateZeroPool (TotalSize);
+ ASSERT (mSplitMemRange != NULL);
+
+ //
+ // Create SMM ranges which are set to present and execution-enable.
+ //
+ NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE);
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
+ if ((mSmmCpuSmramRanges[Index].CpuStart >= mProtectionMemRange[0].Range.Base) &&
+ (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize < mProtectionMemRange[0].Range.Top))
+ {
+ //
+ // If the address have been already covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz
+ //
+ break;
}
- //
- // Create MMIO ranges which are set to present and execution-disable.
- //
- for (Index = 0; Index < NumberOfDescriptors; Index++) {
- if (MemorySpaceMap[Index].GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {
- continue;
- }
+ mProtectionMemRange[NumberOfProtectRange].Range.Base = mSmmCpuSmramRanges[Index].CpuStart;
+ mProtectionMemRange[NumberOfProtectRange].Range.Top = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize;
+ mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
+ mProtectionMemRange[NumberOfProtectRange].Nx = FALSE;
+ NumberOfProtectRange++;
+ }
- mProtectionMemRange[NumberOfProtectRange].Range.Base = MemorySpaceMap[Index].BaseAddress;
- mProtectionMemRange[NumberOfProtectRange].Range.Top = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length;
- mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
- mProtectionMemRange[NumberOfProtectRange].Nx = TRUE;
- NumberOfProtectRange++;
- }
+ //
+ // Create protection ranges which are set to present and execution-disable.
+ //
+ for (Index = 0; Index < MemoryRegionCount; Index++) {
+ mProtectionMemRange[NumberOfProtectRange].Range.Base = MemoryRegion[Index].Base;
+ mProtectionMemRange[NumberOfProtectRange].Range.Top = MemoryRegion[Index].Base + MemoryRegion[Index].Length;
+ mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
+ mProtectionMemRange[NumberOfProtectRange].Nx = TRUE;
+ NumberOfProtectRange++;
+ }
- //
- // Check and updated actual protected memory ranges count
- //
- ASSERT (NumberOfProtectRange <= mProtectionMemRangeCount);
- mProtectionMemRangeCount = NumberOfProtectRange;
+ //
+ // Free the MemoryRegion
+ //
+ if (MemoryRegion != NULL) {
+ FreePool (MemoryRegion);
}
//
+ // Check and updated actual protected memory ranges count
+ //
+ ASSERT (NumberOfProtectRange <= mProtectionMemRangeCount);
+ mProtectionMemRangeCount = NumberOfProtectRange;
+
+ //
// According to protected ranges, create the ranges which will be mapped by 2KB page.
//
NumberOfSpliteRange = 0;
NumberOfProtectRange = mProtectionMemRangeCount;
for (Index = 0; Index < NumberOfProtectRange; Index++) {
//
- // If MMIO base address is not 2MB alignment, make 2MB alignment for create 4KB page in page table.
+ // If base address is not 2MB alignment, make 2MB alignment for create 4KB page in page table.
//
ProtectBaseAddress = mProtectionMemRange[Index].Range.Base;
ProtectEndAddress = mProtectionMemRange[Index].Range.Top;
@@ -578,11 +578,11 @@ InitProtectedMemRange (
}
/**
- Update page table according to protected memory ranges and the 4KB-page mapped memory ranges.
+ This function updates memory attribute according to mProtectionMemRangeCount.
**/
VOID
-InitPaging (
+SmmProfileUpdateMemoryAttributes (
VOID
)
{
@@ -597,115 +597,67 @@ InitPaging (
BOOLEAN WriteProtect;
BOOLEAN CetEnabled;
- PERF_FUNCTION_BEGIN ();
-
- PageTable = AsmReadCr3 ();
- if (sizeof (UINTN) == sizeof (UINT32)) {
- Limit = BASE_4GB;
- } else {
- Limit = (IsRestrictedMemoryAccess ()) ? LShiftU64 (1, mPhysicalAddressBits) : BASE_4GB;
- }
+ DEBUG ((DEBUG_INFO, "SmmProfileUpdateMemoryAttributes Start...\n"));
WRITE_UNPROTECT_RO_PAGES (WriteProtect, CetEnabled);
+ PageTable = AsmReadCr3 ();
+ Limit = LShiftU64 (1, mPhysicalAddressBits);
+
//
// [0, 4k] may be non-present.
//
PreviousAddress = ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) ? BASE_4KB : 0;
- DEBUG ((DEBUG_INFO, "Patch page table start ...\n"));
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- for (Index = 0; Index < mProtectionMemRangeCount; Index++) {
- MemoryAttrMask = 0;
- if (mProtectionMemRange[Index].Nx == TRUE) {
- MemoryAttrMask |= EFI_MEMORY_XP;
- }
-
- if (mProtectionMemRange[Index].Present == FALSE) {
- MemoryAttrMask = EFI_MEMORY_RP;
- }
-
- Base = mProtectionMemRange[Index].Range.Base;
- Length = mProtectionMemRange[Index].Range.Top - Base;
- if (MemoryAttrMask != 0) {
- Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, TRUE, NULL);
- ASSERT_RETURN_ERROR (Status);
- }
-
- if (Base > PreviousAddress) {
- //
- // Mark the ranges not in mProtectionMemRange as non-present.
- //
- MemoryAttrMask = EFI_MEMORY_RP;
- Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Base - PreviousAddress, MemoryAttrMask, TRUE, NULL);
- ASSERT_RETURN_ERROR (Status);
- }
+ for (Index = 0; Index < mProtectionMemRangeCount; Index++) {
+ MemoryAttrMask = 0;
+ if (mProtectionMemRange[Index].Nx == TRUE) {
+ MemoryAttrMask = EFI_MEMORY_XP;
+ }
- PreviousAddress = Base + Length;
+ if (mProtectionMemRange[Index].Present == FALSE) {
+ MemoryAttrMask = EFI_MEMORY_RP;
}
- //
- // This assignment is for setting the last remaining range
- //
- MemoryAttrMask = EFI_MEMORY_RP;
- } else {
- MemoryAttrMask = EFI_MEMORY_XP;
- for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
- Base = mSmmCpuSmramRanges[Index].CpuStart;
- if (Base > PreviousAddress) {
- //
- // Mark the ranges not in mSmmCpuSmramRanges as NX.
- //
- Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Base - PreviousAddress, MemoryAttrMask, TRUE, NULL);
- ASSERT_RETURN_ERROR (Status);
- }
+ Base = mProtectionMemRange[Index].Range.Base;
+ Length = mProtectionMemRange[Index].Range.Top - Base;
+ if (MemoryAttrMask != 0) {
+ Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, Base, Length, MemoryAttrMask, TRUE, NULL);
+ ASSERT_RETURN_ERROR (Status);
+ }
- PreviousAddress = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize;
+ if (Base > PreviousAddress) {
+ //
+ // Mark the ranges not in mProtectionMemRange as non-present.
+ //
+ Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Base - PreviousAddress, EFI_MEMORY_RP, TRUE, NULL);
+ ASSERT_RETURN_ERROR (Status);
}
+
+ PreviousAddress = Base + Length;
}
+ //
+ // Set the last remaining range
+ //
if (PreviousAddress < Limit) {
- //
- // Set the last remaining range to EFI_MEMORY_RP/EFI_MEMORY_XP.
- // This path applies to both SmmProfile enable/disable case.
- //
- Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Limit - PreviousAddress, MemoryAttrMask, TRUE, NULL);
+ Status = ConvertMemoryPageAttributes (PageTable, mPagingMode, PreviousAddress, Limit - PreviousAddress, EFI_MEMORY_RP, TRUE, NULL);
ASSERT_RETURN_ERROR (Status);
}
- WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled);
-
//
// Flush TLB
//
CpuFlushTlb ();
- DEBUG ((DEBUG_INFO, "Patch page table done!\n"));
+
//
// Set execute-disable flag
//
mXdEnabled = TRUE;
- PERF_FUNCTION_END ();
-}
-
-/**
- To get system port address of the SMI Command Port in FADT table.
-
-**/
-VOID
-GetSmiCommandPort (
- VOID
- )
-{
- EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
-
- Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)EfiLocateFirstAcpiTable (
- EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
- );
- ASSERT (Fadt != NULL);
+ WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled);
- mSmiCommandPort = Fadt->SmiCmd;
- DEBUG ((DEBUG_INFO, "mSmiCommandPort = %x\n", mSmiCommandPort));
+ DEBUG ((DEBUG_INFO, "SmmProfileUpdateMemoryAttributes Done.\n"));
}
/**
@@ -723,6 +675,11 @@ SmmProfileStart (
// The flag indicates SMM profile starts to work.
//
mSmmProfileStart = TRUE;
+
+ //
+ // Tell #PF handler to prepare a #DB subsequently.
+ //
+ mSetupDebugTrap = TRUE;
}
/**
@@ -742,26 +699,25 @@ InitSmmProfileCallBack (
IN EFI_HANDLE Handle
)
{
- //
- // Save to variable so that SMM profile data can be found.
- //
- gRT->SetVariable (
- SMM_PROFILE_NAME,
- &gEfiCallerIdGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof (mSmmProfileBase),
- &mSmmProfileBase
- );
+ EFI_STATUS Status;
+ EFI_SMM_VARIABLE_PROTOCOL *SmmProfileVariable;
//
- // Get Software SMI from FADT
+ // Locate SmmVariableProtocol.
//
- GetSmiCommandPort ();
+ Status = gMmst->MmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&SmmProfileVariable);
+ ASSERT_EFI_ERROR (Status);
//
- // Initialize protected memory range for patching page table later.
+ // Save to variable so that SMM profile data can be found.
//
- InitProtectedMemRange ();
+ SmmProfileVariable->SmmSetVariable (
+ SMM_PROFILE_NAME,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (mSmmProfileBase),
+ &mSmmProfileBase
+ );
return EFI_SUCCESS;
}
@@ -775,12 +731,11 @@ InitSmmProfileInternal (
VOID
)
{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS Base;
- VOID *Registration;
- UINTN Index;
- UINTN MsrDsAreaSizePerCpu;
- UINTN TotalSize;
+ EFI_STATUS Status;
+ VOID *Registration;
+ UINTN Index;
+ UINTN MsrDsAreaSizePerCpu;
+ UINT64 SmmProfileSize;
mPFEntryCount = (UINTN *)AllocateZeroPool (sizeof (UINTN) * mMaxNumberOfCpus);
ASSERT (mPFEntryCount != NULL);
@@ -794,28 +749,20 @@ InitSmmProfileInternal (
ASSERT (mLastPFEntryPointer != NULL);
//
- // Allocate memory for SmmProfile below 4GB.
- // The base address
+ // Get Smm Profile Base
//
- mSmmProfileSize = PcdGet32 (PcdCpuSmmProfileSize);
- ASSERT ((mSmmProfileSize & 0xFFF) == 0);
+ mSmmProfileBase = (SMM_PROFILE_HEADER *)(UINTN)GetSmmProfileData (&SmmProfileSize);
+ DEBUG ((DEBUG_ERROR, "SmmProfileBase = 0x%016x.\n", (UINTN)mSmmProfileBase));
+ DEBUG ((DEBUG_ERROR, "SmmProfileSize = 0x%016x.\n", (UINTN)SmmProfileSize));
if (mBtsSupported) {
- TotalSize = mSmmProfileSize + mMsrDsAreaSize;
+ ASSERT (SmmProfileSize > mMsrDsAreaSize);
+ mSmmProfileSize = (UINTN)SmmProfileSize - mMsrDsAreaSize;
} else {
- TotalSize = mSmmProfileSize;
+ mSmmProfileSize = (UINTN)SmmProfileSize;
}
- Base = 0xFFFFFFFF;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiReservedMemoryType,
- EFI_SIZE_TO_PAGES (TotalSize),
- &Base
- );
- ASSERT_EFI_ERROR (Status);
- ZeroMem ((VOID *)(UINTN)Base, TotalSize);
- mSmmProfileBase = (SMM_PROFILE_HEADER *)(UINTN)Base;
+ ASSERT ((mSmmProfileSize & 0xFFF) == 0);
//
// Initialize SMM profile data header.
@@ -838,7 +785,7 @@ InitSmmProfileInternal (
mMsrPEBSRecord = (PEBS_RECORD **)AllocateZeroPool (sizeof (PEBS_RECORD *) * mMaxNumberOfCpus);
ASSERT (mMsrPEBSRecord != NULL);
- mMsrDsAreaBase = (MSR_DS_AREA_STRUCT *)((UINTN)Base + mSmmProfileSize);
+ mMsrDsAreaBase = (MSR_DS_AREA_STRUCT *)((UINTN)mSmmProfileBase + mSmmProfileSize);
MsrDsAreaSizePerCpu = mMsrDsAreaSize / mMaxNumberOfCpus;
mBTSRecordNumber = (MsrDsAreaSizePerCpu - sizeof (PEBS_RECORD) * PEBS_RECORD_NUMBER - sizeof (MSR_DS_AREA_STRUCT)) / sizeof (BRANCH_TRACE_RECORD);
for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
@@ -871,7 +818,7 @@ InitSmmProfileInternal (
// Update SMM profile entry.
//
mProtectionMemRange[1].Range.Base = (EFI_PHYSICAL_ADDRESS)(UINTN)mSmmProfileBase;
- mProtectionMemRange[1].Range.Top = (EFI_PHYSICAL_ADDRESS)(UINTN)mSmmProfileBase + TotalSize;
+ mProtectionMemRange[1].Range.Top = (EFI_PHYSICAL_ADDRESS)(UINTN)mSmmProfileBase + SmmProfileSize;
//
// Allocate memory reserved for creating 4KB pages.
@@ -881,7 +828,7 @@ InitSmmProfileInternal (
//
// Start SMM profile when SmmReadyToLock protocol is installed.
//
- Status = gSmst->SmmRegisterProtocolNotify (
+ Status = gMmst->MmRegisterProtocolNotify (
&gEfiSmmReadyToLockProtocolGuid,
InitSmmProfileCallBack,
&Registration
@@ -894,10 +841,11 @@ InitSmmProfileInternal (
/**
Check if feature is supported by a processor.
+ @param CpuIndex The index of the CPU.
**/
VOID
CheckFeatureSupported (
- VOID
+ IN UINTN CpuIndex
)
{
UINT32 RegEax;
@@ -919,33 +867,6 @@ CheckFeatureSupported (
}
}
- if (mXdSupported) {
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
- if (RegEax <= CPUID_EXTENDED_FUNCTION) {
- //
- // Extended CPUID functions are not supported on this processor.
- //
- mXdSupported = FALSE;
- PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1);
- }
-
- AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & CPUID1_EDX_XD_SUPPORT) == 0) {
- //
- // Execute Disable Bit feature is not supported on this processor.
- //
- mXdSupported = FALSE;
- PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1);
- }
-
- if (StandardSignatureIsAuthenticAMD ()) {
- //
- // AMD processors do not support MSR_IA32_MISC_ENABLE
- //
- PatchInstructionX86 (gPatchMsrIa32MiscEnableSupported, FALSE, 1);
- }
- }
-
if (mBtsSupported) {
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx);
if ((RegEdx & CPUID1_EDX_BTS_AVAILABLE) != 0) {
@@ -966,6 +887,18 @@ CheckFeatureSupported (
}
}
}
+
+ if (mSmmCodeAccessCheckEnable) {
+ //
+ // Check to see if the CPU supports the SMM Code Access Check feature
+ // Do not access this MSR unless the CPU supports the SmmRegFeatureControl
+ //
+ if (!SmmCpuFeaturesIsSmmRegisterSupported (CpuIndex, SmmRegFeatureControl) ||
+ ((AsmReadMsr64 (EFI_MSR_SMM_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) == 0))
+ {
+ mSmmCodeAccessCheckEnable = FALSE;
+ }
+ }
}
/**
@@ -1094,7 +1027,7 @@ InitSmmProfile (
//
// Skip SMM profile initialization if feature is disabled
//
- if (!FeaturePcdGet (PcdCpuSmmProfileEnable) &&
+ if (!mSmmProfileEnabled &&
!HEAP_GUARD_NONSTOP_MODE &&
!NULL_DETECTION_NONSTOP_MODE)
{
@@ -1110,11 +1043,6 @@ InitSmmProfile (
// Initialize profile IDT.
//
InitIdtr ();
-
- //
- // Tell #PF handler to prepare a #DB subsequently.
- //
- mSetupDebugTrap = TRUE;
}
/**
@@ -1166,6 +1094,21 @@ RestorePageTableBelow4G (
// PDPTE
//
PTIndex = (UINTN)BitFieldRead64 (PFAddress, 30, 38);
+
+ if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
+ //
+ // For 32-bit case, because a full map page table for 0-4G is created by default,
+ // and since the PDPTE must be one non-leaf entry, the PDPTE must always be present.
+ // So, ASSERT it must be the 64-bit case running here.
+ //
+ ASSERT (sizeof (UINT64) == sizeof (UINTN));
+
+ //
+ // If the entry is not present, allocate one page from page pool for it
+ //
+ PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
+ }
+
ASSERT (PageTable[PTIndex] != 0);
PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
@@ -1173,9 +1116,9 @@ RestorePageTableBelow4G (
// PD
//
PTIndex = (UINTN)BitFieldRead64 (PFAddress, 21, 29);
- if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {
+ if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
//
- // Large page
+ // A 2M page size will be used directly when the 2M entry is marked as non-present.
//
//
@@ -1202,7 +1145,8 @@ RestorePageTableBelow4G (
}
} else {
//
- // Small page
+ // If the 2M entry is marked as present, a 4K page size will be utilized.
+ // In this scenario, the 2M entry must be a non-leaf entry.
//
ASSERT (PageTable[PTIndex] != 0);
PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
@@ -1305,14 +1249,6 @@ SmmProfilePFHandler (
UINT8 SoftSmiValue;
EFI_SMM_SAVE_STATE_IO_INFO IoInfo;
- if (!mSmmProfileStart) {
- //
- // If SMM profile does not start, call original page fault handler.
- //
- SmiDefaultPFHandler ();
- return;
- }
-
if (mBtsSupported) {
DisableBTS ();
}
@@ -1360,7 +1296,7 @@ SmmProfilePFHandler (
// Indicate it is not software SMI
//
SmiCommand = 0xFFFFFFFFFFFFFFFFULL;
- for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
+ for (Index = 0; Index < gMmst->NumberOfCpus; Index++) {
Status = SmmReadSaveState (&mSmmCpu, sizeof (IoInfo), EFI_SMM_SAVE_STATE_REGISTER_IO, Index, &IoInfo);
if (EFI_ERROR (Status)) {
continue;
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h
index 1a82ac0..2726840 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h
@@ -83,18 +83,28 @@ PageFaultIdtHandlerSmmProfile (
/**
Check if feature is supported by a processor.
+ @param CpuIndex The index of the CPU.
**/
VOID
CheckFeatureSupported (
+ IN UINTN CpuIndex
+ );
+
+/**
+ Initialize the protected memory ranges and the 4KB-page mapped memory ranges.
+
+**/
+VOID
+InitProtectedMemRange (
VOID
);
/**
- Update page table according to protected memory ranges and the 4KB-page mapped memory ranges.
+ This function updates memory attribute according to mProtectionMemRangeCount.
**/
VOID
-InitPaging (
+SmmProfileUpdateMemoryAttributes (
VOID
);
@@ -127,8 +137,16 @@ extern BOOLEAN mXdSupported;
//
extern BOOLEAN mXdEnabled;
//
+// The flag indicates if SMM profile is enabled.
+//
+extern BOOLEAN mSmmProfileEnabled;
+//
// The flag indicates if #DB will be setup in #PF handler.
//
extern BOOLEAN mSetupDebugTrap;
+//
+// SMI command port.
+//
+extern UINT32 mSmiCommandPort;
#endif // _SMM_PROFILE_H_
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h
index 964dd52..e8f3f64 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h
@@ -1,7 +1,7 @@
/** @file
SMM profile internal header file.
-Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2020, AMD Incorporated. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -11,8 +11,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define _SMM_PROFILE_INTERNAL_H_
#include <Protocol/SmmReadyToLock.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/DxeServicesTableLib.h>
#include <Library/CpuLib.h>
#include <IndustryStandard/Acpi.h>
@@ -41,9 +39,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
//
// CPU generic definition
//
-#define CPUID1_EDX_XD_SUPPORT 0x100000
-#define MSR_EFER 0xc0000080
-#define MSR_EFER_XD 0x800
+#define MSR_EFER 0xc0000080
+#define MSR_EFER_XD 0x800
#define CPUID1_EDX_BTS_AVAILABLE 0x200000
@@ -96,12 +93,11 @@ typedef struct {
UINT64 SmiCmd;
} SMM_PROFILE_ENTRY;
-extern SMM_S3_RESUME_STATE *mSmmS3ResumeState;
-extern UINTN gSmiExceptionHandlers[];
-extern BOOLEAN mXdSupported;
-X86_ASSEMBLY_PATCH_LABEL gPatchXdSupported;
-X86_ASSEMBLY_PATCH_LABEL gPatchMsrIa32MiscEnableSupported;
-extern UINTN *mPFEntryCount;
+extern UINTN gSmiExceptionHandlers[];
+extern BOOLEAN mXdSupported;
+X86_ASSEMBLY_PATCH_LABEL gPatchXdSupported;
+X86_ASSEMBLY_PATCH_LABEL gPatchMsrIa32MiscEnableSupported;
+extern UINTN *mPFEntryCount;
extern UINT64 (*mLastPFEntryValue)[MAX_PF_ENTRY_COUNT];
extern UINT64 *(*mLastPFEntryPointer)[MAX_PF_ENTRY_COUNT];
@@ -130,24 +126,38 @@ IsAddressSplit (
);
/**
- Check if the memory address will be mapped by 4KB-page.
+ Check if the SMM profile page fault address above 4GB is in protected range or not.
- @param Address The address of Memory.
- @param Nx The flag indicates if the memory is execute-disable.
+ @param[in] Address The address of Memory.
+ @param[out] Nx The flag indicates if the memory is execute-disable.
+
+ @retval TRUE The input address is in protected range.
+ @retval FALSE The input address is not in protected range.
**/
BOOLEAN
-IsAddressValid (
- IN EFI_PHYSICAL_ADDRESS Address,
- IN BOOLEAN *Nx
+IsSmmProfilePFAddressAbove4GValid (
+ IN EFI_PHYSICAL_ADDRESS Address,
+ OUT BOOLEAN *Nx
+ );
+
+/**
+ Allocate free Page for PageFault handler use.
+
+ @return Page address.
+
+**/
+UINT64
+AllocPage (
+ VOID
);
/**
- Page Fault handler for SMM use.
+ Create new entry in page table for page fault address in SmmProfilePFHandler.
**/
VOID
-SmiDefaultPFHandler (
+SmmProfileMapPFAddress (
VOID
);
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c
index b9a62ae..12fdf74 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c
@@ -1,7 +1,7 @@
/** @file
Provides services to access SMRAM Save State Map
-Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -17,7 +17,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/SmmServicesTableLib.h>
#include <Library/DebugLib.h>
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
typedef struct {
UINT64 Signature; // Offset 0x00
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c
index 8d29ba7..fcf002c 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c
@@ -6,7 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
UINT64 mTimeoutTicker = 0;
@@ -31,16 +31,22 @@ InitializeSmmTimer (
)
{
UINT64 TimerFrequency;
+ UINT64 SyncTimeout;
+ UINT64 SyncTimeout2;
UINT64 Start;
UINT64 End;
+ SyncTimeout = 0;
+ SyncTimeout2 = 0;
+ GetSmmCpuSyncConfigData (NULL, &SyncTimeout, &SyncTimeout2);
+
TimerFrequency = GetPerformanceCounterProperties (&Start, &End);
mTimeoutTicker = DivU64x32 (
- MultU64x64 (TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)),
+ MultU64x64 (TimerFrequency, SyncTimeout),
1000 * 1000
);
mTimeoutTicker2 = DivU64x32 (
- MultU64x64 (TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout2)),
+ MultU64x64 (TimerFrequency, SyncTimeout2),
1000 * 1000
);
if (End < Start) {
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
index 5964884..160e33b 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
@@ -1,21 +1,20 @@
/** @file
Page Fault (#PF) handler for X64 processors
-Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
#define PAGE_TABLE_PAGES 8
#define ACC_MAX_BIT BIT3
LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool);
BOOLEAN m1GPageTableSupport = FALSE;
-BOOLEAN mCpuSmmRestrictedMemoryAccess;
X86_ASSEMBLY_PATCH_LABEL gPatch5LevelPagingNeeded;
/**
@@ -201,17 +200,15 @@ SmmInitPageTable (
UINT64 *PdptEntry;
UINT64 *Pml4Entry;
UINT64 *Pml5Entry;
- UINT8 PhysicalAddressBits;
//
// Initialize spin lock
//
InitializeSpinLock (mPFLock);
- mCpuSmmRestrictedMemoryAccess = PcdGetBool (PcdCpuSmmRestrictedMemoryAccess);
- m1GPageTableSupport = Is1GPageSupport ();
- m5LevelPagingNeeded = Is5LevelPagingNeeded ();
- mPhysicalAddressBits = CalculateMaximumSupportAddress (m5LevelPagingNeeded);
+ m1GPageTableSupport = Is1GPageSupport ();
+ m5LevelPagingNeeded = Is5LevelPagingNeeded ();
+ mPhysicalAddressBits = CalculateMaximumSupportAddress (m5LevelPagingNeeded);
PatchInstructionX86 (gPatch5LevelPagingNeeded, m5LevelPagingNeeded, 1);
if (m5LevelPagingNeeded) {
mPagingMode = m1GPageTableSupport ? Paging5Level1GB : Paging5Level;
@@ -221,36 +218,33 @@ SmmInitPageTable (
DEBUG ((DEBUG_INFO, "5LevelPaging Needed - %d\n", m5LevelPagingNeeded));
DEBUG ((DEBUG_INFO, "1GPageTable Support - %d\n", m1GPageTableSupport));
- DEBUG ((DEBUG_INFO, "PcdCpuSmmRestrictedMemoryAccess - %d\n", mCpuSmmRestrictedMemoryAccess));
DEBUG ((DEBUG_INFO, "PhysicalAddressBits - %d\n", mPhysicalAddressBits));
//
// Generate initial SMM page table.
- // Only map [0, 4G] when PcdCpuSmmRestrictedMemoryAccess is FALSE.
//
- PhysicalAddressBits = mCpuSmmRestrictedMemoryAccess ? mPhysicalAddressBits : 32;
- PageTable = GenSmmPageTable (mPagingMode, PhysicalAddressBits);
+ PageTable = GenSmmPageTable (mPagingMode, mPhysicalAddressBits);
+
+ if (mSmmProfileEnabled) {
+ if (m5LevelPagingNeeded) {
+ Pml5Entry = (UINT64 *)PageTable;
+ //
+ // Set Pml5Entry sub-entries number for smm PF handler usage.
+ //
+ SetSubEntriesNum (Pml5Entry, 1);
+ Pml4Entry = (UINT64 *)((*Pml5Entry) & ~mAddressEncMask & gPhyMask);
+ } else {
+ Pml4Entry = (UINT64 *)PageTable;
+ }
- if (m5LevelPagingNeeded) {
- Pml5Entry = (UINT64 *)PageTable;
//
- // Set Pml5Entry sub-entries number for smm PF handler usage.
+ // Set IA32_PG_PMNT bit to mask first 4 PdptEntry.
//
- SetSubEntriesNum (Pml5Entry, 1);
- Pml4Entry = (UINT64 *)((*Pml5Entry) & ~mAddressEncMask & gPhyMask);
- } else {
- Pml4Entry = (UINT64 *)PageTable;
- }
-
- //
- // Set IA32_PG_PMNT bit to mask first 4 PdptEntry.
- //
- PdptEntry = (UINT64 *)((*Pml4Entry) & ~mAddressEncMask & gPhyMask);
- for (Index = 0; Index < 4; Index++) {
- PdptEntry[Index] |= IA32_PG_PMNT;
- }
+ PdptEntry = (UINT64 *)((*Pml4Entry) & ~mAddressEncMask & gPhyMask);
+ for (Index = 0; Index < 4; Index++) {
+ PdptEntry[Index] |= IA32_PG_PMNT;
+ }
- if (!mCpuSmmRestrictedMemoryAccess) {
//
// Set Pml4Entry sub-entries number for smm PF handler usage.
//
@@ -267,7 +261,7 @@ SmmInitPageTable (
}
}
- if (FeaturePcdGet (PcdCpuSmmProfileEnable) ||
+ if (mSmmProfileEnabled ||
HEAP_GUARD_NONSTOP_MODE ||
NULL_DETECTION_NONSTOP_MODE)
{
@@ -704,152 +698,6 @@ AllocPage (
}
/**
- Page Fault handler for SMM use.
-
-**/
-VOID
-SmiDefaultPFHandler (
- VOID
- )
-{
- UINT64 *PageTable;
- UINT64 *PageTableTop;
- UINT64 PFAddress;
- UINTN StartBit;
- UINTN EndBit;
- UINT64 PTIndex;
- UINTN Index;
- SMM_PAGE_SIZE_TYPE PageSize;
- UINTN NumOfPages;
- UINTN PageAttribute;
- EFI_STATUS Status;
- UINT64 *UpperEntry;
- BOOLEAN Enable5LevelPaging;
- IA32_CR4 Cr4;
-
- //
- // Set default SMM page attribute
- //
- PageSize = SmmPageSize2M;
- NumOfPages = 1;
- PageAttribute = 0;
-
- EndBit = 0;
- PageTableTop = (UINT64 *)(AsmReadCr3 () & gPhyMask);
- PFAddress = AsmReadCr2 ();
-
- Cr4.UintN = AsmReadCr4 ();
- Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 != 0);
-
- Status = GetPlatformPageTableAttribute (PFAddress, &PageSize, &NumOfPages, &PageAttribute);
- //
- // If platform not support page table attribute, set default SMM page attribute
- //
- if (Status != EFI_SUCCESS) {
- PageSize = SmmPageSize2M;
- NumOfPages = 1;
- PageAttribute = 0;
- }
-
- if (PageSize >= MaxSmmPageSizeType) {
- PageSize = SmmPageSize2M;
- }
-
- if (NumOfPages > 512) {
- NumOfPages = 512;
- }
-
- switch (PageSize) {
- case SmmPageSize4K:
- //
- // BIT12 to BIT20 is Page Table index
- //
- EndBit = 12;
- break;
- case SmmPageSize2M:
- //
- // BIT21 to BIT29 is Page Directory index
- //
- EndBit = 21;
- PageAttribute |= (UINTN)IA32_PG_PS;
- break;
- case SmmPageSize1G:
- if (!m1GPageTableSupport) {
- DEBUG ((DEBUG_ERROR, "1-GByte pages is not supported!"));
- ASSERT (FALSE);
- }
-
- //
- // BIT30 to BIT38 is Page Directory Pointer Table index
- //
- EndBit = 30;
- PageAttribute |= (UINTN)IA32_PG_PS;
- break;
- default:
- ASSERT (FALSE);
- }
-
- //
- // If execute-disable is enabled, set NX bit
- //
- if (mXdEnabled) {
- PageAttribute |= IA32_PG_NX;
- }
-
- for (Index = 0; Index < NumOfPages; Index++) {
- PageTable = PageTableTop;
- UpperEntry = NULL;
- for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > EndBit; StartBit -= 9) {
- PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
- if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
- //
- // If the entry is not present, allocate one page from page pool for it
- //
- PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
- } else {
- //
- // Save the upper entry address
- //
- UpperEntry = PageTable + PTIndex;
- }
-
- //
- // BIT9 to BIT11 of entry is used to save access record,
- // initialize value is 7
- //
- PageTable[PTIndex] |= (UINT64)IA32_PG_A;
- SetAccNum (PageTable + PTIndex, 7);
- PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask);
- }
-
- PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
- if ((PageTable[PTIndex] & IA32_PG_P) != 0) {
- //
- // Check if the entry has already existed, this issue may occur when the different
- // size page entries created under the same entry
- //
- DEBUG ((DEBUG_ERROR, "PageTable = %lx, PTIndex = %x, PageTable[PTIndex] = %lx\n", PageTable, PTIndex, PageTable[PTIndex]));
- DEBUG ((DEBUG_ERROR, "New page table overlapped with old page table!\n"));
- ASSERT (FALSE);
- }
-
- //
- // Fill the new entry
- //
- PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & gPhyMask & ~((1ull << EndBit) - 1)) |
- PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS;
- if (UpperEntry != NULL) {
- SetSubEntriesNum (UpperEntry, (GetSubEntriesNum (UpperEntry) + 1) & 0x1FF);
- }
-
- //
- // Get the next page address if we need to create more page tables
- //
- PFAddress += (1ull << EndBit);
- }
-}
-
-/**
ThePage Fault handler wrapper for SMM use.
@param InterruptType Defines the type of interrupt or exception that
@@ -875,7 +723,7 @@ SmiPFHandler (
PFAddress = AsmReadCr2 ();
- if (mCpuSmmRestrictedMemoryAccess && (PFAddress >= LShiftU64 (1, (mPhysicalAddressBits - 1)))) {
+ if (PFAddress >= LShiftU64 (1, (mPhysicalAddressBits - 1))) {
DumpCpuContext (InterruptType, SystemContext);
DEBUG ((DEBUG_ERROR, "Do not support address 0x%lx by processor!\n", PFAddress));
CpuDeadLoop ();
@@ -964,24 +812,29 @@ SmiPFHandler (
goto Exit;
}
- if (mCpuSmmRestrictedMemoryAccess && IsSmmCommBufferForbiddenAddress (PFAddress)) {
- DumpCpuContext (InterruptType, SystemContext);
+ if (IsSmmCommBufferForbiddenAddress (PFAddress)) {
DEBUG ((DEBUG_ERROR, "Access SMM communication forbidden address (0x%lx)!\n", PFAddress));
- DEBUG_CODE (
- DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextX64->Rip);
- );
- CpuDeadLoop ();
- goto Exit;
}
}
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ if (mSmmProfileEnabled) {
+ if (mIsStandaloneMm) {
+ //
+ // Only logging ranges shall run here in MM env.
+ //
+ ASSERT (IsNonMmramLoggingAddress (PFAddress));
+ }
+
SmmProfilePFHandler (
SystemContext.SystemContextX64->Rip,
SystemContext.SystemContextX64->ExceptionData
);
} else {
- SmiDefaultPFHandler ();
+ DumpCpuContext (InterruptType, SystemContext);
+ DEBUG_CODE (
+ DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextX64->Rip);
+ );
+ CpuDeadLoop ();
}
Exit:
@@ -989,7 +842,7 @@ Exit:
}
/**
- This function reads CR2 register when on-demand paging is enabled.
+ This function reads CR2 register.
@param[out] *Cr2 Pointer to variable to hold CR2 register value.
**/
@@ -998,16 +851,11 @@ SaveCr2 (
OUT UINTN *Cr2
)
{
- if (!mCpuSmmRestrictedMemoryAccess) {
- //
- // On-demand paging is enabled when access to non-SMRAM is not restricted.
- //
- *Cr2 = AsmReadCr2 ();
- }
+ *Cr2 = AsmReadCr2 ();
}
/**
- This function restores CR2 register when on-demand paging is enabled.
+ This function restores CR2 register.
@param[in] Cr2 Value to write into CR2 register.
**/
@@ -1016,24 +864,5 @@ RestoreCr2 (
IN UINTN Cr2
)
{
- if (!mCpuSmmRestrictedMemoryAccess) {
- //
- // On-demand paging is enabled when access to non-SMRAM is not restricted.
- //
- AsmWriteCr2 (Cr2);
- }
-}
-
-/**
- Return whether access to non-SMRAM is restricted.
-
- @retval TRUE Access to non-SMRAM is restricted.
- @retval FALSE Access to non-SMRAM is not restricted.
-**/
-BOOLEAN
-IsRestrictedMemoryAccess (
- VOID
- )
-{
- return mCpuSmmRestrictedMemoryAccess;
+ AsmWriteCr2 (Cr2);
}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm
index f329a98..cddc55f 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm
@@ -13,6 +13,7 @@
;-------------------------------------------------------------------------------
extern ASM_PFX(SmiPFHandler)
+extern ASM_PFX(mSetupDebugTrap)
global ASM_PFX(gcSmiIdtr)
global ASM_PFX(gcSmiGdtr)
@@ -369,9 +370,14 @@ ASM_PFX(PageFaultIdtHandlerSmmProfile):
mov rsp, rbp
+; Check if mSetupDebugTrap is TRUE (non-zero)
+ cmp byte [dword ASM_PFX(mSetupDebugTrap)], 0
+ jz SkipSettingTF
+
; Enable TF bit after page fault handler runs
bts dword [rsp + 40], 8 ;RFLAGS
+SkipSettingTF:
pop rbp
add rsp, 16 ; skip INT# & ErrCode
iretq
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
index ca706ee..1be2de4 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
@@ -6,7 +6,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
EFI_PHYSICAL_ADDRESS mGdtBuffer;
UINTN mGdtBufferSize;
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArchDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArchDxeSmm.c
new file mode 100644
index 0000000..e812a43
--- /dev/null
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArchDxeSmm.c
@@ -0,0 +1,22 @@
+/** @file
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiSmmCpuCommon.h"
+
+/**
+ Return whether access to non-SMRAM is restricted.
+
+ @retval TRUE Access to non-SMRAM is restricted.
+ @retval FALSE Access to non-SMRAM is not restricted.
+**/
+BOOLEAN
+IsRestrictedMemoryAccess (
+ VOID
+ )
+{
+ return PcdGetBool (PcdCpuSmmRestrictedMemoryAccess);
+}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c
index 01432d4..be9cd89 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c
@@ -1,14 +1,14 @@
/** @file
X64 processor specific functions to enable SMM profile.
-Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
-#include "PiSmmCpuDxeSmm.h"
+#include "PiSmmCpuCommon.h"
#include "SmmProfileInternal.h"
//
@@ -29,20 +29,21 @@ UINT64 *mPFPageUplink[MAX_PF_PAGE_COUNT];
/**
Create SMM page table for S3 path.
+ @param[out] Cr3 The base address of the page tables.
+
**/
VOID
InitSmmS3Cr3 (
- VOID
+ OUT UINTN *Cr3
)
{
+ ASSERT (Cr3 != NULL);
+
//
// Generate level4 page table for the first 4GB memory space
// Return the address of PML4 (to set CR3)
//
- //
- // The SmmS3Cr3 is only used by S3Resume PEIM to switch CPU from 32bit to 64bit
- //
- mSmmS3ResumeState->SmmS3Cr3 = (UINT32)GenSmmPageTable (Paging4Level, 32);
+ *Cr3 = GenSmmPageTable (Paging4Level, 32);
return;
}
@@ -109,6 +110,156 @@ AcquirePage (
}
/**
+ Create new entry in page table for page fault address in SmmProfilePFHandler.
+
+**/
+VOID
+SmmProfileMapPFAddress (
+ VOID
+ )
+{
+ UINT64 *PageTable;
+ UINT64 *PageTableTop;
+ UINT64 PFAddress;
+ UINTN StartBit;
+ UINTN EndBit;
+ UINT64 PTIndex;
+ UINTN Index;
+ SMM_PAGE_SIZE_TYPE PageSize;
+ UINTN NumOfPages;
+ UINTN PageAttribute;
+ EFI_STATUS Status;
+ UINT64 *UpperEntry;
+ BOOLEAN Enable5LevelPaging;
+ IA32_CR4 Cr4;
+
+ //
+ // Set default SMM page attribute
+ //
+ PageSize = SmmPageSize2M;
+ NumOfPages = 1;
+ PageAttribute = 0;
+
+ EndBit = 0;
+ PageTableTop = (UINT64 *)(AsmReadCr3 () & gPhyMask);
+ PFAddress = AsmReadCr2 ();
+
+ Cr4.UintN = AsmReadCr4 ();
+ Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 != 0);
+
+ Status = GetPlatformPageTableAttribute (PFAddress, &PageSize, &NumOfPages, &PageAttribute);
+ //
+ // If platform not support page table attribute, set default SMM page attribute
+ //
+ if (Status != EFI_SUCCESS) {
+ PageSize = SmmPageSize2M;
+ NumOfPages = 1;
+ PageAttribute = 0;
+ }
+
+ if (PageSize >= MaxSmmPageSizeType) {
+ PageSize = SmmPageSize2M;
+ }
+
+ if (NumOfPages > 512) {
+ NumOfPages = 512;
+ }
+
+ switch (PageSize) {
+ case SmmPageSize4K:
+ //
+ // BIT12 to BIT20 is Page Table index
+ //
+ EndBit = 12;
+ break;
+ case SmmPageSize2M:
+ //
+ // BIT21 to BIT29 is Page Directory index
+ //
+ EndBit = 21;
+ PageAttribute |= (UINTN)IA32_PG_PS;
+ break;
+ case SmmPageSize1G:
+ if (!m1GPageTableSupport) {
+ DEBUG ((DEBUG_ERROR, "1-GByte pages is not supported!"));
+ ASSERT (FALSE);
+ }
+
+ //
+ // BIT30 to BIT38 is Page Directory Pointer Table index
+ //
+ EndBit = 30;
+ PageAttribute |= (UINTN)IA32_PG_PS;
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+
+ //
+ // If execute-disable is enabled, set NX bit
+ //
+ if (mXdEnabled) {
+ PageAttribute |= IA32_PG_NX;
+ }
+
+ for (Index = 0; Index < NumOfPages; Index++) {
+ PageTable = PageTableTop;
+ UpperEntry = NULL;
+ for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > 12; StartBit -= 9) {
+ PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
+
+ //
+ // Iterate through the page table to find the appropriate page table entry for page creation if one of the following cases is met:
+ // 1) StartBit > EndBit: The PageSize of current entry is bigger than the platform-specified PageSize granularity.
+ // 2) IA32_PG_P bit is 0 & IA32_PG_PS bit is not 0: The current entry is present and it's a non-leaf entry.
+ //
+ if ((StartBit > EndBit) || ((((PageTable[PTIndex] & IA32_PG_P) != 0) && ((PageTable[PTIndex] & IA32_PG_PS) == 0)))) {
+ if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
+ //
+ // If the entry is not present, allocate one page from page pool for it
+ //
+ PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
+ } else {
+ //
+ // Save the upper entry address
+ //
+ UpperEntry = PageTable + PTIndex;
+ }
+
+ //
+ // BIT9 to BIT11 of entry is used to save access record,
+ // initialize value is 7
+ //
+ PageTable[PTIndex] |= (UINT64)IA32_PG_A;
+ SetAccNum (PageTable + PTIndex, 7);
+ PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask);
+ } else {
+ //
+ // Found the appropriate entry.
+ //
+ break;
+ }
+ }
+
+ PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
+
+ //
+ // Fill the new entry
+ //
+ PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & gPhyMask & ~((1ull << StartBit) - 1)) |
+ PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS;
+ if (UpperEntry != NULL) {
+ SetSubEntriesNum (UpperEntry, (GetSubEntriesNum (UpperEntry) + 1) & 0x1FF);
+ }
+
+ //
+ // Get the next page address if we need to create more page tables
+ //
+ PFAddress += (1ull << StartBit);
+ }
+}
+
+/**
Update page table to map the memory correctly in order to make the instruction
which caused page fault execute successfully. And it also save the original page
table to be restored in single-step exception.
@@ -207,7 +358,7 @@ RestorePageTableAbove4G (
// If page entry does not existed in page table at all, create a new entry.
//
if (!Existed) {
- if (IsAddressValid (PFAddress, &Nx)) {
+ if (IsSmmProfilePFAddressAbove4GValid (PFAddress, &Nx)) {
//
// If page fault address above 4GB is in protected range but it causes a page fault exception,
// Will create a page entry for this page fault address, make page table entry as present/rw and execution-disable.
@@ -219,7 +370,7 @@ RestorePageTableAbove4G (
//
// Create one entry in page table for page fault address.
//
- SmiDefaultPFHandler ();
+ SmmProfileMapPFAddress ();
//
// Find the page table entry created just now.
//
@@ -250,7 +401,7 @@ RestorePageTableAbove4G (
PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);
for (Index = 0; Index < 512; Index++) {
PageTable[Index] = Address | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
- if (!IsAddressValid (Address, &Nx)) {
+ if (!IsSmmProfilePFAddressAbove4GValid (Address, &Nx)) {
PageTable[Index] = PageTable[Index] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);
}
@@ -268,7 +419,7 @@ RestorePageTableAbove4G (
//
// Update 2MB page entry.
//
- if (!IsAddressValid (Address, &Nx)) {
+ if (!IsSmmProfilePFAddressAbove4GValid (Address, &Nx)) {
//
// Patch to remove present flag and rw flag.
//
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h
index 80205c9..5249360 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h
@@ -1,7 +1,7 @@
/** @file
X64 processor specific header file to enable SMM profile.
-Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -55,6 +55,8 @@ typedef struct _PEBS_RECORD {
#pragma pack ()
+extern BOOLEAN m1GPageTableSupport;
+
#define PHYSICAL_ADDRESS_MASK ((1ull << 52) - SIZE_4KB)
/**
@@ -81,10 +83,12 @@ RestorePageTableAbove4G (
/**
Create SMM page table for S3 path.
+ @param[out] Cr3 The base address of the page tables.
+
**/
VOID
InitSmmS3Cr3 (
- VOID
+ OUT UINTN *Cr3
);
/**
@@ -96,4 +100,57 @@ InitPagesForPFHandler (
VOID
);
+/**
+ Set sub-entries number in entry.
+
+ @param[in, out] Entry Pointer to entry
+ @param[in] SubEntryNum Sub-entries number based on 0:
+ 0 means there is 1 sub-entry under this entry
+ 0x1ff means there is 512 sub-entries under this entry
+
+**/
+VOID
+SetSubEntriesNum (
+ IN OUT UINT64 *Entry,
+ IN UINT64 SubEntryNum
+ );
+
+/**
+ Return sub-entries number in entry.
+
+ @param[in] Entry Pointer to entry
+
+ @return Sub-entries number based on 0:
+ 0 means there is 1 sub-entry under this entry
+ 0x1ff means there is 512 sub-entries under this entry
+**/
+UINT64
+GetSubEntriesNum (
+ IN UINT64 *Entry
+ );
+
+/**
+ Allocate free Page for PageFault handler use.
+
+ @return Page address.
+
+**/
+UINT64
+AllocPage (
+ VOID
+ );
+
+/**
+ Set access record in entry.
+
+ @param[in, out] Entry Pointer to entry
+ @param[in] Acc Access record value
+
+**/
+VOID
+SetAccNum (
+ IN OUT UINT64 *Entry,
+ IN UINT64 Acc
+ );
+
#endif // _SMM_PROFILE_ARCH_H_
diff --git a/UefiCpuPkg/UefiCpuPkg.ci.yaml b/UefiCpuPkg/UefiCpuPkg.ci.yaml
index c2280ae..80a043f 100644
--- a/UefiCpuPkg/UefiCpuPkg.ci.yaml
+++ b/UefiCpuPkg/UefiCpuPkg.ci.yaml
@@ -6,6 +6,9 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "UefiCpuPkg.dsc",
+ },
"LicenseCheck": {
"IgnoreFiles": []
},
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index c026cf5..33ac8cf 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -108,6 +108,18 @@
## Include/Guid/GhcbApicIds.h
gGhcbApicIdsGuid = { 0xbc964338, 0xee39, 0x4fc8, { 0xa2, 0x24, 0x10, 0x10, 0x8b, 0x17, 0x80, 0x1b }}
+ ## Include/Guid/MmUnblockRegion.h
+ gMmUnblockRegionHobGuid = { 0x7c316fb3, 0x849e, 0x4ee7, { 0x87, 0xfc, 0x16, 0x2d, 0x0b, 0x03, 0x42, 0xbf }}
+
+ ## Include/Guid/MmProfileData.h
+ gMmProfileDataHobGuid = { 0x26ef081d, 0x19b0, 0x4c42, { 0xa2, 0x57, 0xa7, 0xf5, 0x9f, 0x8b, 0xd0, 0x38 }}
+
+ ## Include/Guid/MmCpuSyncConfig.h
+ gMmCpuSyncConfigHobGuid = { 0x8b90bd26, 0xe4f9, 0x45c2, { 0x92, 0xa2, 0x9e, 0xac, 0xe6, 0x0e, 0x9d, 0xcc }}
+
+ # Include/Guid/MmAcpiS3Enable.h
+ gMmAcpiS3EnableHobGuid = { 0xe7402821, 0x2654, 0x4c1b, { 0x99, 0x0e, 0x04, 0x8f, 0x8d, 0x82, 0xcf, 0x67 }}
+
[Protocols]
## Include/Protocol/SmmCpuService.h
gEfiSmmCpuServiceProtocolGuid = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }}
@@ -269,7 +281,7 @@
## Specifies buffer size in bytes to save SMM profile data. The value should be a multiple of 4KB.
# @Prompt SMM profile data buffer size.
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize|0x200000|UINT32|0x32132107
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize|0x600000|UINT32|0x32132107
## Specifies stack size in bytes for each processor in SMM.
# @Prompt Processor stack size in SMM.
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 1b52760..f173bba 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -69,6 +69,8 @@
UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf
UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
+ HobLib|MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf
+ MemoryAllocationLib|MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf
[LibraryClasses.common.SEC]
PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
@@ -102,11 +104,14 @@
MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf
MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
- CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
- MmSaveStateLib|UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf
[LibraryClasses.common.MM_STANDALONE]
MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
+ SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf
+
+[LibraryClasses.common.MM_STANDALONE, LibraryClasses.common.DXE_SMM_DRIVER]
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
+ MmSaveStateLib|UefiCpuPkg/Library/MmSaveStateLib/IntelMmSaveStateLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
@@ -128,6 +133,7 @@
UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf
UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf
UefiCpuPkg/MicrocodeMeasurementDxe/MicrocodeMeasurementDxe.inf
+ UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf
[Components.IA32, Components.X64]
UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -167,8 +173,14 @@
UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf
UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf
UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf
- UefiCpuPkg/SecCore/SecCore.inf
- UefiCpuPkg/SecCore/SecCoreNative.inf
+ UefiCpuPkg/SecCore/SecCore.inf {
+ <LibraryClasses>
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+ }
+ UefiCpuPkg/SecCore/SecCoreNative.inf {
+ <LibraryClasses>
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+ }
UefiCpuPkg/SecMigrationPei/SecMigrationPei.inf
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
@@ -206,6 +218,7 @@
UefiCpuPkg/Library/SmmRelocationLib/AmdSmmRelocationLib.inf
[Components.X64]
+ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf
UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandlerLibUnitTest.inf
[Components.RISCV64]
diff --git a/UefiPayloadPkg/Include/Guid/PciSegmentInfoGuid.h b/UefiPayloadPkg/Include/Guid/PciSegmentInfoGuid.h
new file mode 100644
index 0000000..57872ba
--- /dev/null
+++ b/UefiPayloadPkg/Include/Guid/PciSegmentInfoGuid.h
@@ -0,0 +1,32 @@
+/** @file
+ This file defines the hob structure for PCI Segment related information.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef UPL_PCI_SEGMENT_INFO_GUID_H_
+#define UPL_PCI_SEGMENT_INFO_GUID_H_
+
+///
+/// UPL Pcie Segment Information Hob GUID
+///
+extern EFI_GUID gUplPciSegmentInfoHobGuid;
+
+#pragma pack(1)
+typedef struct {
+ UINT16 SegmentNumber; ///< Segment number.
+ UINT64 BaseAddress; ///< ECAM Base address.
+} UPL_SEGMENT_INFO;
+
+typedef struct {
+ UNIVERSAL_PAYLOAD_GENERIC_HEADER Header;
+ UINTN Count;
+ UPL_SEGMENT_INFO SegmentInfo[0];
+} UPL_PCI_SEGMENT_INFO_HOB;
+#pragma pack()
+
+#define UNIVERSAL_PAYLOAD_PCI_SEGMENT_INFO_REVISION 1
+
+#endif
diff --git a/UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h b/UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h
index 60f2aa3..26a999d 100644
--- a/UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h
+++ b/UefiPayloadPkg/Include/Guid/UniversalPayloadBase.h
@@ -16,4 +16,14 @@ typedef struct {
EFI_PHYSICAL_ADDRESS Entry;
} UNIVERSAL_PAYLOAD_BASE;
+#define UNIVERSAL_PAYLOAD_BASE_REVISION 1
+
+#define N_NON_RELOCATABLE BIT31
+#define P_PREFETCHABLE BIT30
+#define SS_CONFIGURATION_SPACE 0
+#define SS_IO_SPACE BIT24
+#define SS_32BIT_MEMORY_SPACE BIT25
+#define SS_64BIT_MEMORY_SPACE BIT24+BIT25
+#define DWORDS_TO_NEXT_ADDR_TYPE 7
+
#endif // UNIVERSAL_PAYLOAD_BASE_H_
diff --git a/UefiPayloadPkg/Include/Guid/UniversalPayloadSerialPortDeviceParentInfo.h b/UefiPayloadPkg/Include/Guid/UniversalPayloadSerialPortDeviceParentInfo.h
new file mode 100644
index 0000000..969befe
--- /dev/null
+++ b/UefiPayloadPkg/Include/Guid/UniversalPayloadSerialPortDeviceParentInfo.h
@@ -0,0 +1,28 @@
+/** @file
+ Universal Payload serial port parent device information definitions.
+
+Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO_
+#define UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO_
+
+extern GUID gUniversalPayloadSerialPortParentDeviceInfoGuid;
+
+// IsIsaCompatible
+// TRUE: the serial port device is under an ISA compatible bus, which means the parent device is ISA/LPC/eSPI bus controller.
+// FALSE: the serial port device is native PCI device under PCI bridge.
+#pragma pack(1)
+typedef struct {
+ UINT32 Revision;
+ BOOLEAN IsIsaCompatible;
+ UINT8 Reserved[3];
+ UINT64 ParentDevicePcieBaseAddress;
+} UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO;
+#pragma pack()
+
+#define UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO_REVISION 1
+
+#endif // UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO_
diff --git a/UefiPayloadPkg/Include/Library/BuildFdtLib.h b/UefiPayloadPkg/Include/Library/BuildFdtLib.h
new file mode 100644
index 0000000..b674a6c
--- /dev/null
+++ b/UefiPayloadPkg/Include/Library/BuildFdtLib.h
@@ -0,0 +1,22 @@
+/** @file
+ This library will Build the FDT (flat device tree) table information.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef BUILD_FDT_LIB_H_
+#define BUILD_FDT_LIB_H_
+
+/**
+ It will build FDT for UPL consumed.
+ @param[in] FdtBase Address of the Fdt data.
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to build required FDT.
+**/
+EFI_STATUS
+BuildFdtForUPL (
+ IN VOID *FdtBase
+ );
+
+#endif
diff --git a/UefiPayloadPkg/Include/Library/FdtParserLib.h b/UefiPayloadPkg/Include/Library/FdtParserLib.h
new file mode 100644
index 0000000..87109f1
--- /dev/null
+++ b/UefiPayloadPkg/Include/Library/FdtParserLib.h
@@ -0,0 +1,64 @@
+/** @file
+ This library will parse the FDT (flat device tree) table information.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef FDT_PARSER_LIB_H_
+#define FDT_PARSER_LIB_H_
+
+/**
+ It will parse FDT based on DTB.
+
+ @param[in] FdtBase Address of the Fdt data.
+
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to parse DTB.
+**/
+UINTN
+EFIAPI
+ParseDtb (
+ IN VOID *FdtBase
+ );
+
+/**
+ It will Parse FDT -node based on information.
+ @param[in] FdtBase The starting memory address of FdtBase
+ @retval HobList The base address of Hoblist.
+
+**/
+UINT64
+EFIAPI
+FdtNodeParser (
+ IN VOID *FdtBase
+ );
+
+/**
+ It will Parse FDT -custom node based on information.
+ @param[in] FdtBase The starting memory address of FdtBase
+ @param[in] HostList The starting memory address of New Hob list.
+
+**/
+UINTN
+EFIAPI
+CustomFdtNodeParser (
+ IN VOID *FdtBase,
+ IN VOID *HostList
+ );
+
+/**
+ It will initialize HOBs for UPL.
+
+ @param[in] FdtBase Address of the Fdt data.
+
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to initialize HOBs.
+**/
+UINTN
+EFIAPI
+UplInitHob (
+ IN VOID *FdtBase
+ );
+
+#endif
diff --git a/UefiPayloadPkg/Include/Library/HobParserLib.h b/UefiPayloadPkg/Include/Library/HobParserLib.h
new file mode 100644
index 0000000..98a64b8
--- /dev/null
+++ b/UefiPayloadPkg/Include/Library/HobParserLib.h
@@ -0,0 +1,70 @@
+/** @file
+ This library will provide services for handling HOB data.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef HOB_PARSER_LIB_H_
+#define HOB_PARSER_LIB_H_
+
+/**
+ *
+ Add HOB into HOB list
+
+ @param[in] Hob The HOB to be added into the HOB list.
+**/
+VOID
+AddNewHob (
+ IN EFI_PEI_HOB_POINTERS *Hob
+ );
+
+/**
+ Found the Resource Descriptor HOB that contains a range (Base, Top)
+
+ @param[in] HobList Hob start address
+ @param[in] Base Memory start address
+ @param[in] Top Memory end address.
+
+ @retval The pointer to the Resource Descriptor HOB.
+**/
+EFI_HOB_RESOURCE_DESCRIPTOR *
+FindResourceDescriptorByRange (
+ IN VOID *HobList,
+ IN EFI_PHYSICAL_ADDRESS Base,
+ IN EFI_PHYSICAL_ADDRESS Top
+ );
+
+/**
+ Find the highest below 4G memory resource descriptor, except the input Resource Descriptor.
+
+ @param[in] HobList Hob start address
+ @param[in] MinimalNeededSize Minimal needed size.
+ @param[in] ExceptResourceHob Ignore this Resource Descriptor.
+
+ @retval The pointer to the Resource Descriptor HOB.
+**/
+EFI_HOB_RESOURCE_DESCRIPTOR *
+FindAnotherHighestBelow4GResourceDescriptor (
+ IN VOID *HobList,
+ IN UINTN MinimalNeededSize,
+ IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob
+ );
+
+/**
+ Check the HOB and decide if it is need inside Payload
+
+ Payload maintainer may make decision which HOB is need or needn't
+ Then add the check logic in the function.
+
+ @param[in] Hob The HOB to check
+
+ @retval TRUE If HOB is need inside Payload
+ @retval FALSE If HOB is needn't inside Payload
+**/
+BOOLEAN
+IsHobNeed (
+ EFI_PEI_HOB_POINTERS Hob
+ );
+
+#endif
diff --git a/UefiPayloadPkg/Include/UniversalPayload/DeviceTree.h b/UefiPayloadPkg/Include/UniversalPayload/DeviceTree.h
new file mode 100644
index 0000000..b7c2163
--- /dev/null
+++ b/UefiPayloadPkg/Include/UniversalPayload/DeviceTree.h
@@ -0,0 +1,30 @@
+/** @file
+ This file defines the structure for the PCI Root Bridges.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ - Universal Payload Specification 0.8 (https://universalpayload.github.io/spec/)
+**/
+
+#ifndef UNIVERSAL_PAYLOAD_DEVICE_TREE_H_
+#define UNIVERSAL_PAYLOAD_DEVICE_TREE_H_
+
+#include <Uefi.h>
+#include <UniversalPayload/UniversalPayload.h>
+
+#pragma pack (1)
+
+typedef struct {
+ UNIVERSAL_PAYLOAD_GENERIC_HEADER Header;
+ EFI_PHYSICAL_ADDRESS DeviceTreeAddress;
+} UNIVERSAL_PAYLOAD_DEVICE_TREE;
+
+#pragma pack()
+
+#define UNIVERSAL_PAYLOAD_DEVICE_TREE_REVISION 1
+
+extern GUID gUniversalPayloadDeviceTreeGuid;
+
+#endif // UNIVERSAL_PAYLOAD_SMBIOS_TABLE_H_
diff --git a/UefiPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.c b/UefiPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.c
index 1ed589a..8c41366 100644
--- a/UefiPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.c
+++ b/UefiPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.c
@@ -47,6 +47,7 @@ AcpiTimerLibConstructor (
pAcpiBoardInfo = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob);
mPmTimerReg = (UINTN)pAcpiBoardInfo->PmTimerRegBase;
+ ASSERT (pAcpiBoardInfo->PmTimerRegBase != 0);
return EFI_SUCCESS;
}
diff --git a/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c
index 82d0dd5..55e85dc 100644
--- a/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c
+++ b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c
@@ -143,6 +143,75 @@ SerialPortInitialize (
return RETURN_SUCCESS;
}
+ if (GetHobList () == NULL) {
+ mUartCount = 0;
+ SerialRegisterBase = PcdGet64 (PcdSerialRegisterBase);
+ MmioEnable = PcdGetBool (PcdSerialUseMmio);
+ BaudRate = PcdGet32 (PcdSerialBaudRate);
+ RegisterStride = (UINT8)PcdGet32 (PcdSerialRegisterStride);
+
+ mUartInfo[mUartCount].BaseAddress = SerialRegisterBase;
+ mUartInfo[mUartCount].UseMmio = MmioEnable;
+ mUartInfo[mUartCount].BaudRate = BaudRate;
+ mUartInfo[mUartCount].RegisterStride = RegisterStride;
+ mUartCount++;
+
+ Divisor = PcdGet32 (PcdSerialClockRate) / (BaudRate * 16);
+ if ((PcdGet32 (PcdSerialClockRate) % (BaudRate * 16)) >= BaudRate * 8) {
+ Divisor++;
+ }
+
+ //
+ // See if the serial port is already initialized
+ //
+ Initialized = TRUE;
+ if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) & 0x3F) != (PcdGet8 (PcdSerialLineControl) & 0x3F)) {
+ Initialized = FALSE;
+ }
+
+ Value = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) | B_UART_LCR_DLAB);
+ SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, Value, MmioEnable, RegisterStride);
+ CurrentDivisor = SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_HIGH, MmioEnable, RegisterStride) << 8;
+ CurrentDivisor |= (UINT32)SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_LOW, MmioEnable, RegisterStride);
+ Value = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStride) & ~B_UART_LCR_DLAB);
+ SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, Value, MmioEnable, RegisterStride);
+ if (CurrentDivisor != Divisor) {
+ Initialized = FALSE;
+ }
+
+ //
+ // Configure baud rate
+ //
+ SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB, MmioEnable, RegisterStride);
+ SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)(Divisor >> 8), MmioEnable, RegisterStride);
+ SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8)(Divisor & 0xff), MmioEnable, RegisterStride);
+
+ //
+ // Clear DLAB and configure Data Bits, Parity, and Stop Bits.
+ // Strip reserved bits from PcdSerialLineControl
+ //
+ SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3F), MmioEnable, RegisterStride);
+
+ //
+ // Enable and reset FIFOs
+ // Strip reserved bits from PcdSerialFifoControl
+ //
+ SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00, MmioEnable, RegisterStride);
+ SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64)), MmioEnable, RegisterStride);
+
+ //
+ // Set FIFO Polled Mode by clearing IER after setting FCR
+ //
+ SerialPortWriteRegister (SerialRegisterBase, R_UART_IER, 0x00, MmioEnable, RegisterStride);
+
+ //
+ // Put Modem Control Register(MCR) into its reset state of 0x00.
+ //
+ SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, 0x00, MmioEnable, RegisterStride);
+
+ return RETURN_SUCCESS;
+ }
+
GuidHob = GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid);
while (GuidHob != NULL) {
SerialPortInfo = (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *)GET_GUID_HOB_DATA (GuidHob);
diff --git a/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf
index ac857d3..5ebfe99 100644
--- a/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf
+++ b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf
@@ -34,6 +34,12 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## CONSUMES
+
+
[Guids]
gUniversalPayloadSerialPortInfoGuid
diff --git a/UefiPayloadPkg/Library/BaseSerialPortLibHob/DxeBaseSerialPortLibHob.inf b/UefiPayloadPkg/Library/BaseSerialPortLibHob/DxeBaseSerialPortLibHob.inf
index 7bb3a6a..d79fc5a 100644
--- a/UefiPayloadPkg/Library/BaseSerialPortLibHob/DxeBaseSerialPortLibHob.inf
+++ b/UefiPayloadPkg/Library/BaseSerialPortLibHob/DxeBaseSerialPortLibHob.inf
@@ -6,7 +6,6 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
-
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = DxeBaseSerialPortLibHob
@@ -15,7 +14,6 @@
VERSION_STRING = 1.0
LIBRARY_CLASS = SerialPortLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
CONSTRUCTOR = DxeBaseSerialPortLibHobConstructor
-
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
@@ -25,7 +23,7 @@
IoLib
HobLib
TimerLib
-
+ PlatformHookLib
[Sources]
DxeBaseSerialPortLibHob.c
BaseSerialPortLibHob.c
@@ -36,6 +34,12 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## CONSUMES
+
+
[Guids]
gUniversalPayloadSerialPortInfoGuid
diff --git a/UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf b/UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf
new file mode 100644
index 0000000..12461a9
--- /dev/null
+++ b/UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf
@@ -0,0 +1,65 @@
+## @file
+# Flat Device Tree Table Build Library.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BuildFdtLib
+ FILE_GUID = 5DA69A29-C990-49EE-A4E6-BA5311A1ADAF
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BuildFdtLib
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ X86_BuildFdtLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiPayloadPkg/UefiPayloadPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ PcdLib
+ HobLib
+ FdtLib
+
+[Guids]
+ gUniversalPayloadDeviceTreeGuid
+ gEfiGraphicsInfoHobGuid
+ gEfiGraphicsDeviceInfoHobGuid
+ gUniversalPayloadAcpiTableGuid
+ gUniversalPayloadSerialPortInfoGuid
+ gEfiHobMemoryAllocModuleGuid
+ gEfiHobMemoryAllocStackGuid
+ gEfiHobMemoryAllocBspStoreGuid
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Ppis]
+ gEdkiiPeiPciDevicePpiGuid ## CONSUMES
+
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /wd4305
+ GCC:*_*_IA32_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_X64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_ARM_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_AARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_RISCV64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_LOONGARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
diff --git a/UefiPayloadPkg/Library/BuildFdtLib/X86_BuildFdtLib.c b/UefiPayloadPkg/Library/BuildFdtLib/X86_BuildFdtLib.c
new file mode 100644
index 0000000..d7d44df
--- /dev/null
+++ b/UefiPayloadPkg/Library/BuildFdtLib/X86_BuildFdtLib.c
@@ -0,0 +1,945 @@
+/** @file
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/PrintLib.h>
+#include <Library/FdtLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeiServicesLib.h>
+#include <UniversalPayload/UniversalPayload.h>
+#include <UniversalPayload/AcpiTable.h>
+#include <UniversalPayload/SerialPortInfo.h>
+#include <UniversalPayload/PciRootBridges.h>
+#include <Guid/GraphicsInfoHob.h>
+#include <Guid/UniversalPayloadSerialPortDeviceParentInfo.h>
+#include <Guid/UniversalPayloadBase.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Ppi/PciDevice.h>
+
+#define IGD_BUS_NUM 0x00
+#define IGD_DEV_NUM 0x02
+#define IGD_FUN_NUM 0x00
+
+EDKII_PCI_DEVICE_PPI *mPciDevicePpi;
+BOOLEAN mResourceAssigned;
+
+CHAR8 *mMemoryAllocType[] = {
+ "Reserved",
+ "LoaderCode",
+ "LoaderData",
+ "boot-code",
+ "boot-data",
+ "runtime-code",
+ "runtime-data",
+ "ConventionalMemory",
+ "UnusableMemory",
+ "acpi",
+ "acpi-nvs",
+ "mmio",
+ "MemoryMappedIOPortSpace",
+ "PalCode",
+ "PersistentMemory",
+};
+
+/**
+ The wrapper function of PeiServicesLocatePpi() for gEdkiiPeiPciDevicePpiGuid
+ and Save the PPI to mPciDevicePpi.
+ @retval EFI_SUCCESS If it locate gEdkiiPeiPciDevicePpiGuid successfully.
+ @retval EFI_NOT_FOUND If it can't find gEdkiiPeiPciDevicePpiGuid.
+**/
+EFI_STATUS
+EFIAPI
+LocatePciDevicePpi (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
+
+ mPciDevicePpi = NULL;
+ Status = PeiServicesLocatePpi (
+ &gEdkiiPeiPciDevicePpiGuid,
+ 0,
+ &PpiDescriptor,
+ (void **)&mPciDevicePpi
+ );
+ if (EFI_ERROR (Status) || (mPciDevicePpi == NULL)) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ It will build FDT based on memory information from Hobs.
+ @param[in] FdtBase Address of the Fdt data.
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to build required FDT.
+**/
+EFI_STATUS
+BuildFdtForMemory (
+ IN VOID *FdtBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
+ VOID *HobStart;
+ VOID *Fdt;
+ INT32 TempNode;
+ CHAR8 TempStr[32];
+ UINT64 RegTmp[2];
+
+ Fdt = FdtBase;
+
+ HobStart = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+ //
+ // Scan resource descriptor hobs to set memory nodes
+ //
+ for (Hob.Raw = HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ ResourceHob = Hob.ResourceDescriptor;
+ // Memory
+ if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+ // DEBUG ((DEBUG_ERROR, "Found hob for memory: base %016lX length %016lX\n", ResourceHob->PhysicalStart, ResourceHob->ResourceLength));
+
+ Status = AsciiSPrint (TempStr, sizeof (TempStr), "memory@%lX", ResourceHob->PhysicalStart);
+ TempNode = FdtAddSubnode (Fdt, 0, TempStr);
+ ASSERT (TempNode > 0);
+
+ RegTmp[0] = CpuToFdt64 (ResourceHob->PhysicalStart);
+ RegTmp[1] = CpuToFdt64 (ResourceHob->ResourceLength);
+ Status = FdtSetProperty (Fdt, TempNode, "reg", &RegTmp, sizeof (RegTmp));
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtSetProperty (Fdt, TempNode, "device_type", "memory", (UINT32)(AsciiStrLen ("memory")+1));
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ It will build FDT based on memory allocation information from Hobs.
+ @param[in] FdtBase Address of the Fdt data.
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to build required FDT.
+**/
+EFI_STATUS
+BuildFdtForMemAlloc (
+ IN VOID *FdtBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ VOID *HobStart;
+ VOID *Fdt;
+ INT32 ParentNode;
+ INT32 TempNode;
+ CHAR8 TempStr[32];
+ UINT64 RegTmp[2];
+ UINT32 AllocMemType;
+ EFI_GUID *AllocMemName;
+ UINT8 IsStackHob;
+ UINT8 IsBspStore;
+ UINT32 Data32;
+
+ Fdt = FdtBase;
+
+ ParentNode = FdtAddSubnode (Fdt, 0, "reserved-memory");
+ ASSERT (ParentNode > 0);
+
+ Data32 = CpuToFdt32 (2);
+ Status = FdtSetProperty (Fdt, ParentNode, "#address-cells", &Data32, sizeof (UINT32));
+ Status = FdtSetProperty (Fdt, ParentNode, "#size-cells", &Data32, sizeof (UINT32));
+
+ HobStart = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
+ //
+ // Scan memory allocation hobs to set memory type
+ //
+ for (Hob.Raw = HobStart; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
+ AllocMemName = NULL;
+ IsStackHob = 0;
+ IsBspStore = 0;
+ if (CompareGuid (&(Hob.MemoryAllocationModule->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid)) {
+ continue;
+ } else if (IsZeroGuid (&(Hob.MemoryAllocationModule->MemoryAllocationHeader.Name)) == FALSE) {
+ AllocMemName = &(Hob.MemoryAllocationModule->MemoryAllocationHeader.Name);
+
+ if (CompareGuid (AllocMemName, &gEfiHobMemoryAllocStackGuid)) {
+ IsStackHob = 1;
+ } else if (CompareGuid (AllocMemName, &gEfiHobMemoryAllocBspStoreGuid)) {
+ IsBspStore = 1;
+ }
+ }
+
+ DEBUG ((
+ DEBUG_ERROR,
+ "Found hob for rsvd memory alloc: base %016lX length %016lX type %x\n",
+ Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,
+ Hob.MemoryAllocation->AllocDescriptor.MemoryLength,
+ Hob.MemoryAllocation->AllocDescriptor.MemoryType
+ ));
+
+ AllocMemType = Hob.MemoryAllocation->AllocDescriptor.MemoryType;
+ if (IsStackHob == 1) {
+ Status = AsciiSPrint (
+ TempStr,
+ sizeof (TempStr),
+ "%a@%lX",
+ "stackhob",
+ Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress
+ );
+ } else if (IsBspStore == 1) {
+ Status = AsciiSPrint (
+ TempStr,
+ sizeof (TempStr),
+ "%a@%lX",
+ "bspstore",
+ Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress
+ );
+ } else {
+ Status = AsciiSPrint (
+ TempStr,
+ sizeof (TempStr),
+ "%a@%lX",
+ mMemoryAllocType[AllocMemType],
+ Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress
+ );
+ }
+
+ if (AsciiStrCmp (mMemoryAllocType[AllocMemType], "ConventionalMemory") == 0) {
+ continue;
+ }
+
+ if (AsciiStrCmp (mMemoryAllocType[AllocMemType], "mmio") == 0) {
+ Status = AsciiSPrint (TempStr, sizeof (TempStr), "mmio@%lX", Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress);
+ } else {
+ Status = AsciiSPrint (TempStr, sizeof (TempStr), "memory@%lX", Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress);
+ }
+
+ TempNode = FdtAddSubnode (Fdt, ParentNode, TempStr);
+ DEBUG ((DEBUG_INFO, "FdtAddSubnode %x", TempNode));
+ if (TempNode < 0) {
+ continue;
+ }
+
+ RegTmp[0] = CpuToFdt64 (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress);
+ RegTmp[1] = CpuToFdt64 (Hob.MemoryAllocation->AllocDescriptor.MemoryLength);
+ Status = FdtSetProperty (Fdt, TempNode, "reg", &RegTmp, sizeof (RegTmp));
+ ASSERT_EFI_ERROR (Status);
+
+ if (!(AsciiStrCmp (mMemoryAllocType[AllocMemType], "mmio") == 0)) {
+ Status = FdtSetProperty (Fdt, TempNode, "compatible", mMemoryAllocType[AllocMemType], (UINT32)(AsciiStrLen (mMemoryAllocType[AllocMemType])+1));
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ It will build FDT based on serial information.
+ @param[in] ISANode ISANode.
+ @param[in] FdtBase Address of the Fdt data.
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to build required FDT.
+**/
+EFI_STATUS
+BuildFdtForSerial (
+ IN INT32 ISANode,
+ IN VOID *FdtBase
+ )
+{
+ EFI_STATUS Status;
+ VOID *Fdt;
+ INT32 TempNode;
+ UINT64 RegisterBase;
+ CHAR8 TempStr[32];
+ UINT32 RegData[3];
+ UINT32 Data32;
+ UINT64 Data64;
+
+ Fdt = FdtBase;
+ RegisterBase = 0;
+
+ //
+ // Create SerialPortInfo FDT node.
+ //
+ Status = AsciiSPrint (TempStr, sizeof (TempStr), "serial@%lX", (RegisterBase == 0) ? PcdGet64 (PcdSerialRegisterBase) : RegisterBase);
+ TempNode = FdtAddSubnode (Fdt, ISANode, TempStr);
+ ASSERT (TempNode > 0);
+
+ Data32 = CpuToFdt32 (PcdGet32 (PcdSerialBaudRate));
+ Status = FdtSetProperty (Fdt, TempNode, "current-speed", &Data32, sizeof (Data32));
+ ASSERT_EFI_ERROR (Status);
+
+ if (PcdGetBool (PcdSerialUseMmio)) {
+ Data32 = 0;
+ RegData[0] = CpuToFdt32 (Data32);
+ } else {
+ Data32 = 1;
+ RegData[0] = CpuToFdt32 (Data32);
+ }
+
+ Data64 = (RegisterBase == 0) ? PcdGet64 (PcdSerialRegisterBase) : RegisterBase;
+ Data32 = (UINT32)((Data64 & 0x0FFFFFFFF));
+ RegData[1] = CpuToFdt32 (Data32);
+ RegData[2] = CpuToFdt32 (8);
+ Status = FdtSetProperty (Fdt, TempNode, "reg", &RegData, sizeof (RegData));
+ ASSERT_EFI_ERROR (Status);
+
+ Data32 = CpuToFdt32 (1);
+ Status = FdtSetProperty (Fdt, TempNode, "reg-io-width", &Data32, sizeof (Data32));
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtSetProperty (Fdt, TempNode, "compatible", "isa", (UINT32)(AsciiStrLen ("isa")+1));
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ It will build FDT based on serial information.
+
+ @param[in] ISANode ISANode.
+ @param[in] FdtBase Address of the Fdt data.
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to build required FDT.
+**/
+EFI_STATUS
+BuildFdtForSerialLpss (
+ IN INT32 ISANode,
+ IN VOID *FdtBase
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ EFI_STATUS Status;
+ UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *SerialPortInfo;
+ VOID *Fdt;
+ INT32 TempNode;
+ UINT32 Data32;
+ UINT32 RegData[2];
+ CHAR8 TempStr[32];
+
+ Status = EFI_SUCCESS;
+ SerialPortInfo = NULL;
+ Fdt = FdtBase;
+
+ DEBUG ((DEBUG_INFO, "BuildFdtForSerialLpss start \n"));
+ GuidHob = GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid);
+ while (GuidHob != NULL) {
+ SerialPortInfo = (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *)GET_GUID_HOB_DATA (GuidHob);
+
+ if (!SerialPortInfo->UseMmio) {
+ GuidHob = GET_NEXT_HOB (GuidHob);
+ GuidHob = GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid, GuidHob);
+ continue;
+ }
+
+ DEBUG ((DEBUG_INFO, "Create SerialPortInfo LPSS FDT node \n"));
+ //
+ // Create SerialPortInfo FDT node.
+ //
+ Status = AsciiSPrint (TempStr, sizeof (TempStr), "serial@%lX", SerialPortInfo->RegisterBase);
+ TempNode = FdtAddSubnode (Fdt, ISANode, TempStr);
+ ASSERT (TempNode > 0);
+
+ Data32 = CpuToFdt32 (SerialPortInfo->BaudRate);
+ Status = FdtSetProperty (Fdt, TempNode, "current-speed", &Data32, sizeof (Data32));
+ ASSERT_EFI_ERROR (Status);
+
+ RegData[0] = CpuToFdt32 ((UINT32)SerialPortInfo->RegisterBase);
+ RegData[1] = CpuToFdt32 (0x80);
+ Status = FdtSetProperty (Fdt, TempNode, "reg", &RegData, sizeof (RegData));
+ ASSERT_EFI_ERROR (Status);
+
+ Data32 = CpuToFdt32 (4);
+ Status = FdtSetProperty (Fdt, TempNode, "reg-io-width", &Data32, sizeof (Data32));
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtSetProperty (Fdt, TempNode, "compatible", "ns16550a", (UINT32)(AsciiStrLen ("ns16550a")+1));
+ ASSERT_EFI_ERROR (Status);
+
+ GuidHob = GET_NEXT_HOB (GuidHob);
+ GuidHob = GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid, GuidHob);
+ }
+
+ return Status;
+}
+
+/**
+ It will build FDT based on BuildFdtForPciRootBridge information.
+ @param[in] FdtBase Address of the Fdt data.
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to build required FDT.
+**/
+EFI_STATUS
+BuildFdtForPciRootBridge (
+ IN VOID *FdtBase
+ )
+{
+ EFI_STATUS Status;
+ VOID *Fdt;
+ INT32 TempNode;
+ INT32 GmaNode;
+ INT32 eSPINode;
+ CHAR8 TempStr[32];
+ CHAR8 GmaStr[32];
+ CHAR8 eSPIStr[32];
+ UINT32 RegTmp[2];
+ UINT32 RegData[21];
+ UINT32 DMARegData[8];
+ UINT32 Data32;
+ UINT64 Data64;
+ UINT8 BusNumber;
+ UINT8 BusLimit;
+ UINT8 BusBase;
+ UINT8 DevBase;
+ UINT8 FunBase;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader;
+ UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo;
+ UINT8 Index;
+ PCI_TYPE00 PciData;
+ UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO *SerialParent;
+
+ Fdt = FdtBase;
+ BusNumber = 0;
+ BusLimit = 0;
+ BusBase = 0x80;
+ DevBase = 0x31;
+ FunBase = 0;
+ Status = EFI_SUCCESS;
+ PciRootBridgeInfo = NULL;
+
+ DEBUG ((DEBUG_INFO, "%a: #1 \n", __func__));
+ //
+ // Create BuildFdtForPciRootBridge FDT node.
+ //
+
+ GuidHob = GetFirstGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid);
+ if (GuidHob != NULL) {
+ GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob);
+ if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) <= GET_GUID_HOB_DATA_SIZE (GuidHob)) && (GenericHeader->Length <= GET_GUID_HOB_DATA_SIZE (GuidHob))) {
+ if ((GenericHeader->Revision == UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) && (GenericHeader->Length >= sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES))) {
+ DEBUG ((DEBUG_INFO, "%a: #2 \n", __func__));
+
+ //
+ // UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES structure is used when Revision equals to UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION
+ //
+ PciRootBridgeInfo = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)GET_GUID_HOB_DATA (GuidHob);
+ }
+ }
+ }
+
+ GuidHob = GetFirstGuidHob (&gUniversalPayloadSerialPortParentDeviceInfoGuid);
+ if (GuidHob != NULL) {
+ SerialParent = (UNIVERSAL_PAYLOAD_SERIAL_PORT_PARENT_DEVICE_INFO *)GET_GUID_HOB_DATA (GuidHob);
+ BusBase = (SerialParent->ParentDevicePcieBaseAddress >> 20) & 0xFF;
+ DevBase = (SerialParent->ParentDevicePcieBaseAddress >> 15) & 0x1F;
+ FunBase = (SerialParent->ParentDevicePcieBaseAddress >> 12) & 0x07;
+ }
+
+ DEBUG ((DEBUG_INFO, "PciRootBridgeInfo->Count %x\n", PciRootBridgeInfo->Count));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Segment %x, \n", PciRootBridgeInfo->RootBridge[0].Segment));
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.Base %x, \n", PciRootBridgeInfo->RootBridge[0].Bus.Base));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.limit %x, \n", PciRootBridgeInfo->RootBridge[0].Bus.Limit));
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base %x, \n", PciRootBridgeInfo->RootBridge[0].Mem.Base));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.limit %x, \n", PciRootBridgeInfo->RootBridge[0].Mem.Limit));
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base %llx, \n", PciRootBridgeInfo->RootBridge[0].MemAbove4G.Base));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.limit %llx, \n", PciRootBridgeInfo->RootBridge[0].MemAbove4G.Limit));
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.Base %llx, \n", PciRootBridgeInfo->RootBridge[0].PMem.Base));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.limit %llx, \n", PciRootBridgeInfo->RootBridge[0].PMem.Limit));
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.Base %x, \n", PciRootBridgeInfo->RootBridge[1].Bus.Base));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.limit %x, \n", PciRootBridgeInfo->RootBridge[1].Bus.Limit));
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base %x, \n", PciRootBridgeInfo->RootBridge[1].Mem.Base));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.limit %x, \n", PciRootBridgeInfo->RootBridge[1].Mem.Limit));
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base %llx, \n", PciRootBridgeInfo->RootBridge[1].MemAbove4G.Base));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.limit %llx, \n", PciRootBridgeInfo->RootBridge[1].MemAbove4G.Limit));
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.Base %x, \n", PciRootBridgeInfo->RootBridge[1].PMem.Base));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->PMem.limit %x, \n", PciRootBridgeInfo->RootBridge[1].PMem.Limit));
+
+ if (PciRootBridgeInfo != NULL) {
+ for (Index = 0; Index < PciRootBridgeInfo->Count; Index++) {
+ UINTN PciExpressBaseAddress;
+
+ mResourceAssigned = PciRootBridgeInfo->ResourceAssigned;
+ PciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress) + (PCI_LIB_ADDRESS (PciRootBridgeInfo->RootBridge[Index].Bus.Base, 0, 0, 0));
+ Status = AsciiSPrint (TempStr, sizeof (TempStr), "pci-rb%d@%lX", Index, PciExpressBaseAddress);
+ TempNode = FdtAddSubnode (Fdt, 0, TempStr);
+ ASSERT (TempNode > 0);
+ SetMem (RegData, sizeof (RegData), 0);
+
+ // non-reloc/non-prefetch/mmio, child-addr, parent-addr, length
+ Data32 = (N_NON_RELOCATABLE + SS_32BIT_MEMORY_SPACE);
+ RegData[0] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base RegData[0] %x, \n", Data32));
+
+ // child-addr
+ RegData[1] = CpuToFdt32 (0);
+ Data32 = (UINT32)PciRootBridgeInfo->RootBridge[Index].Mem.Base;
+ RegData[2] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base RegData[2] %x, \n", Data32));
+
+ // parent-addr
+ RegData[3] = CpuToFdt32 (0);
+ RegData[4] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base RegData[4] %x, \n", Data32));
+
+ // size
+ Data64 = (PciRootBridgeInfo->RootBridge[Index].Mem.Limit - PciRootBridgeInfo->RootBridge[Index].Mem.Base + 1);
+ if (Data64 & 0xFFFFFFFF00000000) {
+ Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 31);
+ } else {
+ Data32 = 0;
+ }
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.size RegData[5] %x, \n", Data32));
+ RegData[5] = CpuToFdt32 (Data32);
+ Data32 = (UINT32)((Data64 & 0x0FFFFFFFF));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.size RegData[6] %x, \n", Data32));
+
+ RegData[6] = CpuToFdt32 (Data32);
+
+ // non-reloc/non-prefetch/64 mmio, child-addr, parent-addr, length
+ Data32 = (N_NON_RELOCATABLE + SS_64BIT_MEMORY_SPACE);
+ RegData[7] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base RegData[7] %x, \n", Data32));
+
+ // child-addr
+ Data64 = PciRootBridgeInfo->RootBridge[Index].MemAbove4G.Base;
+ Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 32);
+
+ RegData[8] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base RegData[8] %x, \n", Data32));
+ Data32 = (UINT32)((Data64 & 0x0FFFFFFFF));
+ RegData[9] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base RegData[9] %x, \n", Data32));
+
+ // parent-addr
+ RegData[10] = RegData[8];
+ RegData[11] = RegData[9];
+
+ // size
+ Data64 = (PciRootBridgeInfo->RootBridge[Index].MemAbove4G.Limit - PciRootBridgeInfo->RootBridge[Index].MemAbove4G.Base + 1);
+ if (Data64 & 0xFFFFFFFF00000000) {
+ Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 32);
+ } else {
+ Data32 = 0;
+ }
+
+ RegData[12] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.size RegData[12] %x, \n", Data32));
+
+ Data32 = (UINT32)((Data64 & 0x0FFFFFFFF));
+ RegData[13] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.size RegData[13] %x, \n", Data32));
+
+ // non-reloc/32bit/io, child-addr, parent-addr, length
+ Data32 = (N_NON_RELOCATABLE + SS_IO_SPACE);
+
+ RegData[14] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base RegData[14] %x, \n", Data32));
+
+ Data32 = (UINT32)PciRootBridgeInfo->RootBridge[Index].Io.Base;
+ // child-addr
+ RegData[15] = CpuToFdt32 (0);
+ RegData[16] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base RegData[16] %x, \n", Data32));
+
+ // parent-addr
+ RegData[17] = CpuToFdt32 (0);
+ RegData[18] = CpuToFdt32 (Data32);
+ // size
+ Data64 = (PciRootBridgeInfo->RootBridge[Index].Io.Limit - PciRootBridgeInfo->RootBridge[Index].Io.Base + 1);
+ if (Data64 & 0xFFFFFFFF00000000) {
+ Data32 = (UINT32)RShiftU64 ((Data64 & 0xFFFFFFFF00000000), 32);
+ } else {
+ Data32 = 0;
+ }
+
+ RegData[19] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base size [19] %x, \n", Data32));
+
+ Data32 = (UINT32)((Data64 & 0x0FFFFFFFF));
+ RegData[20] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Io.base size [20] %x, \n", Data32));
+
+ Status = FdtSetProperty (Fdt, TempNode, "ranges", &RegData, sizeof (RegData));
+ ASSERT_EFI_ERROR (Status);
+
+ // non-reloc/non-prefetch/memory, child-addr, parent-addr, length
+ // indicate rb1 does not support above 4GB DMA
+ Data32 = (N_NON_RELOCATABLE + SS_32BIT_MEMORY_SPACE);
+
+ DMARegData[0] = CpuToFdt32 (Data32);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->DMA base RegData[0] %x, \n", Data32));
+
+ // child-addr
+ DMARegData[2] = CpuToFdt32 (0);
+ DMARegData[3] = CpuToFdt32 (0);
+ // parent-addr
+ DMARegData[4] = CpuToFdt32 (0);
+ DMARegData[5] = CpuToFdt32 (0);
+ // size
+ DMARegData[6] = CpuToFdt32 (1);
+ DMARegData[7] = CpuToFdt32 (0);
+
+ Status = FdtSetProperty (Fdt, TempNode, "dma-ranges", &DMARegData, sizeof (DMARegData));
+ ASSERT_EFI_ERROR (Status);
+
+ Data32 = CpuToFdt32 (2);
+ Status = FdtSetProperty (Fdt, TempNode, "#size-cells", &Data32, sizeof (UINT32));
+
+ Data32 = CpuToFdt32 (3);
+ Status = FdtSetProperty (Fdt, TempNode, "#address-cells", &Data32, sizeof (UINT32));
+
+ BusNumber = PciRootBridgeInfo->RootBridge[Index].Bus.Base & 0xFF;
+ RegTmp[0] = CpuToFdt32 (BusNumber);
+ BusLimit = PciRootBridgeInfo->RootBridge[Index].Bus.Limit & 0xFF;
+ RegTmp[1] = CpuToFdt32 (BusLimit);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->BusNumber %x, \n", BusNumber));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->BusLimit %x, \n", BusLimit));
+
+ Status = FdtSetProperty (Fdt, TempNode, "bus-range", &RegTmp, sizeof (RegTmp));
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtSetProperty (Fdt, TempNode, "compatible", "pci-rb", (UINT32)(AsciiStrLen ("pci-rb")+1));
+ ASSERT_EFI_ERROR (Status);
+
+ if (Index == 0) {
+ PciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress) + (PCI_LIB_ADDRESS (IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, 0));
+ Status = AsciiSPrint (GmaStr, sizeof (GmaStr), "gma@%lX", PciExpressBaseAddress);
+ GmaNode = FdtAddSubnode (Fdt, TempNode, GmaStr);
+ Status = LocatePciDevicePpi ();
+ if (!EFI_ERROR (Status)) {
+ Status = mPciDevicePpi->PciIo.Pci.Read (
+ &mPciDevicePpi->PciIo,
+ (EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16,
+ PCI_VENDOR_ID_OFFSET,
+ sizeof (PciData.Hdr.VendorId),
+ &(PciData.Hdr.VendorId)
+ );
+
+ Status = mPciDevicePpi->PciIo.Pci.Read (
+ &mPciDevicePpi->PciIo,
+ (EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16,
+ PCI_DEVICE_ID_OFFSET,
+ sizeof (PciData.Hdr.DeviceId),
+ &(PciData.Hdr.DeviceId)
+ );
+
+ Status = mPciDevicePpi->PciIo.Pci.Read (
+ &mPciDevicePpi->PciIo,
+ (EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint8,
+ PCI_REVISION_ID_OFFSET,
+ sizeof (PciData.Hdr.RevisionID),
+ &(PciData.Hdr.RevisionID)
+ );
+
+ Status = mPciDevicePpi->PciIo.Pci.Read (
+ &mPciDevicePpi->PciIo,
+ (EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16,
+ PCI_SVID_OFFSET,
+ sizeof (PciData.Device.SubsystemVendorID),
+ &(PciData.Device.SubsystemVendorID)
+ );
+
+ Status = mPciDevicePpi->PciIo.Pci.Read (
+ &mPciDevicePpi->PciIo,
+ (EFI_PCI_IO_PROTOCOL_WIDTH)EfiPciWidthUint16,
+ PCI_SID_OFFSET,
+ sizeof (PciData.Device.SubsystemID),
+ &(PciData.Device.SubsystemID)
+ );
+ }
+
+ Data32 = CpuToFdt32 (PciData.Device.SubsystemID);
+ Status = FdtSetProperty (Fdt, GmaNode, "subsystem-id", &Data32, sizeof (UINT32));
+
+ Data32 = CpuToFdt32 (PciData.Device.SubsystemVendorID);
+ Status = FdtSetProperty (Fdt, GmaNode, "subsystem-vendor-id", &Data32, sizeof (UINT32));
+
+ Data32 = CpuToFdt32 (PciData.Hdr.RevisionID);
+ Status = FdtSetProperty (Fdt, GmaNode, "revision-id", &Data32, sizeof (UINT32));
+
+ Data32 = CpuToFdt32 (PciData.Hdr.DeviceId);
+ Status = FdtSetProperty (Fdt, GmaNode, "device-id", &Data32, sizeof (UINT32));
+
+ Data32 = CpuToFdt32 (PciData.Hdr.VendorId);
+ Status = FdtSetProperty (Fdt, GmaNode, "vendor-id", &Data32, sizeof (UINT32));
+ }
+
+ if (SerialParent != NULL) {
+ DEBUG ((DEBUG_INFO, "SerialParent->IsIsaCompatible :%x , SerialParent->ParentDevicePcieBaseAddress :%x\n", SerialParent->IsIsaCompatible, SerialParent->ParentDevicePcieBaseAddress));
+ DEBUG ((DEBUG_INFO, "BusBase :%x , PciRootBridgeInfo->RootBridge[Index].Bus.Base :%x\n", BusBase, PciRootBridgeInfo->RootBridge[Index].Bus.Base));
+ }
+
+ {
+ if ((BusBase >= PciRootBridgeInfo->RootBridge[Index].Bus.Base) && (BusBase <= PciRootBridgeInfo->RootBridge[Index].Bus.Limit)) {
+ eSPINode = TempNode;
+ if (SerialParent != NULL) {
+ if (SerialParent->IsIsaCompatible) {
+ Status = AsciiSPrint (eSPIStr, sizeof (eSPIStr), "isa@%X,%X", DevBase, FunBase);
+ eSPINode = FdtAddSubnode (Fdt, TempNode, eSPIStr);
+ Status = FdtSetProperty (Fdt, eSPINode, "compatible", "isa", (UINT32)(AsciiStrLen ("isa")+1));
+ ASSERT_EFI_ERROR (Status);
+ Data32 = CpuToFdt32 (1);
+ Status = FdtSetProperty (Fdt, eSPINode, "#size-cells", &Data32, sizeof (UINT32));
+ Data32 = CpuToFdt32 (2);
+ Status = FdtSetProperty (Fdt, eSPINode, "#address-cells", &Data32, sizeof (UINT32));
+ Status = BuildFdtForSerial (eSPINode, FdtBase);
+ ASSERT_EFI_ERROR (Status);
+ }
+ } else {
+ Status = BuildFdtForSerialLpss (eSPINode, FdtBase);
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ }
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "%a: #3 \n", __func__));
+
+ return Status;
+}
+
+/**
+ It will build FDT based on FrameBuffer.
+ @param[in] FdtBase Address of the Fdt data.
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to build required FDT.
+**/
+EFI_STATUS
+BuildFdtForFrameBuffer (
+ IN VOID *FdtBase
+ )
+{
+ EFI_STATUS Status;
+ VOID *Fdt;
+ INT32 TempNode;
+ UINT32 Data32;
+ CHAR8 TempStr[32];
+ UINT64 RegData[2];
+ EFI_HOB_GUID_TYPE *GuidHob;
+ EFI_PEI_GRAPHICS_INFO_HOB *GraphicsInfo;
+
+ Fdt = FdtBase;
+
+ GuidHob = GetFirstGuidHob (&gEfiGraphicsInfoHobGuid);
+ if (GuidHob != NULL) {
+ GraphicsInfo = (EFI_PEI_GRAPHICS_INFO_HOB *)(GET_GUID_HOB_DATA (GuidHob));
+ Status = AsciiSPrint (TempStr, sizeof (TempStr), "framebuffer@%lX", GraphicsInfo->FrameBufferBase);
+ TempNode = FdtAddSubnode (Fdt, 0, TempStr);
+ ASSERT (TempNode > 0);
+
+ Status = FdtSetProperty (Fdt, TempNode, "display", "&gma", (UINT32)(AsciiStrLen ("&gma")+1));
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtSetProperty (Fdt, TempNode, "format", "a8r8g8b8", (UINT32)(AsciiStrLen ("a8r8g8b8")+1));
+ ASSERT_EFI_ERROR (Status);
+
+ Data32 = CpuToFdt32 (GraphicsInfo->GraphicsMode.VerticalResolution);
+ Status = FdtSetProperty (Fdt, TempNode, "height", &Data32, sizeof (UINT32));
+ ASSERT_EFI_ERROR (Status);
+
+ Data32 = CpuToFdt32 (GraphicsInfo->GraphicsMode.HorizontalResolution);
+ Status = FdtSetProperty (Fdt, TempNode, "width", &Data32, sizeof (UINT32));
+ ASSERT_EFI_ERROR (Status);
+
+ RegData[0] = CpuToFdt64 (GraphicsInfo->FrameBufferBase);
+ RegData[1] = CpuToFdt64 (GraphicsInfo->FrameBufferSize);
+ Status = FdtSetProperty (Fdt, TempNode, "reg", &RegData, sizeof (RegData));
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtSetProperty (Fdt, TempNode, "compatible", "simple-framebuffer", (UINT32)(AsciiStrLen ("simple-framebuffer")+1));
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ Status = AsciiSPrint (TempStr, sizeof (TempStr), "framebuffer@%lX", 0xB0000000);
+ TempNode = FdtAddSubnode (Fdt, 0, TempStr);
+ ASSERT (TempNode > 0);
+
+ Status = FdtSetProperty (Fdt, TempNode, "display", "&gma", (UINT32)(AsciiStrLen ("&gma")+1));
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtSetProperty (Fdt, TempNode, "format", "a8r8g8b8", (UINT32)(AsciiStrLen ("a8r8g8b8")+1));
+ ASSERT_EFI_ERROR (Status);
+
+ Data32 = CpuToFdt32 (1024);
+ Status = FdtSetProperty (Fdt, TempNode, "height", &Data32, sizeof (UINT32));
+ ASSERT_EFI_ERROR (Status);
+
+ Data32 = CpuToFdt32 (1280);
+ Status = FdtSetProperty (Fdt, TempNode, "width", &Data32, sizeof (UINT32));
+ ASSERT_EFI_ERROR (Status);
+
+ RegData[0] = CpuToFdt64 (0xB0000000);
+ RegData[1] = CpuToFdt64 (0x500000);
+ Status = FdtSetProperty (Fdt, TempNode, "reg", &RegData, sizeof (RegData));
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtSetProperty (Fdt, TempNode, "compatible", "simple-framebuffer", (UINT32)(AsciiStrLen ("simple-framebuffer")+1));
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return Status;
+}
+
+/**
+ It will build FDT for UPL required data.
+ @param[in] FdtBase Address of the Fdt data.
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to build required FDT.
+**/
+EFI_STATUS
+BuildFdtForUplRequired (
+ IN VOID *FdtBase
+ )
+{
+ EFI_STATUS Status;
+ VOID *Fdt;
+ VOID *Fit;
+ INT32 ParentNode;
+ INT32 CustomNode;
+ INT32 UPLParaNode;
+ INT32 UPLImageNode;
+ EFI_HOB_CPU *CpuHob;
+ UINT64 Data64;
+ UINT32 Data32;
+ VOID *HobPtr;
+ EFI_BOOT_MODE BootMode;
+ CHAR8 TempStr[32];
+ UINT8 *GuidHob;
+ UNIVERSAL_PAYLOAD_BASE *PayloadBase;
+
+ Fdt = FdtBase;
+ Fit = NULL;
+
+ //
+ // Create Hob list FDT node.
+ //
+ ParentNode = FdtAddSubnode (Fdt, 0, "options");
+ ASSERT (ParentNode > 0);
+
+ UPLParaNode = FdtAddSubnode (Fdt, ParentNode, "upl-params");
+ ASSERT (UPLParaNode > 0);
+
+ //
+ // Create CPU info FDT node
+ //
+ CpuHob = GetFirstHob (EFI_HOB_TYPE_CPU);
+ ASSERT (CpuHob != NULL);
+
+ if (mResourceAssigned) {
+ Status = FdtSetProperty (Fdt, UPLParaNode, "pci-enum-done", NULL, 0);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ BootMode = GetBootModeHob ();
+
+ Data32 = CpuToFdt32 ((UINT32)CpuHob->SizeOfMemorySpace);
+ Status = FdtSetProperty (Fdt, UPLParaNode, "addr-width", &Data32, sizeof (Data32));
+ ASSERT_EFI_ERROR (Status);
+
+ if (BootMode == BOOT_WITH_FULL_CONFIGURATION) {
+ Status = FdtSetProperty (Fdt, UPLParaNode, "boot-mode", "normal", (UINT32)(AsciiStrLen ("normal")+1));
+ } else if (BootMode == BOOT_WITH_MINIMAL_CONFIGURATION) {
+ Status = FdtSetProperty (Fdt, UPLParaNode, "boot-mode", "fast", (UINT32)(AsciiStrLen ("fast")+1));
+ } else if (BootMode == BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS) {
+ Status = FdtSetProperty (Fdt, UPLParaNode, "boot-mode", "full", (UINT32)(AsciiStrLen ("full")+1));
+ } else if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
+ Status = FdtSetProperty (Fdt, UPLParaNode, "boot-mode", "default", (UINT32)(AsciiStrLen ("default")+1));
+ } else if (BootMode == BOOT_ON_S4_RESUME) {
+ Status = FdtSetProperty (Fdt, UPLParaNode, "boot-mode", "s4", (UINT32)(AsciiStrLen ("s4")+1));
+ } else if (BootMode == BOOT_ON_S3_RESUME) {
+ Status = FdtSetProperty (Fdt, UPLParaNode, "boot-mode", "s3", (UINT32)(AsciiStrLen ("s3")+1));
+ } else {
+ Status = FdtSetProperty (Fdt, UPLParaNode, "boot-mode", "na", (UINT32)(AsciiStrLen ("na")+1));
+ }
+
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtSetProperty (Fdt, UPLParaNode, "compatible", "upl", (UINT32)(AsciiStrLen ("upl")+1));
+ ASSERT_EFI_ERROR (Status);
+
+ GuidHob = GetFirstGuidHob (&gUniversalPayloadBaseGuid);
+ if (GuidHob != NULL) {
+ PayloadBase = (UNIVERSAL_PAYLOAD_BASE *)GET_GUID_HOB_DATA (GuidHob);
+ Fit = (VOID *)(UINTN)PayloadBase->Entry;
+ DEBUG ((DEBUG_INFO, "PayloadBase Entry = 0x%08x\n", PayloadBase->Entry));
+
+ Status = AsciiSPrint (TempStr, sizeof (TempStr), "upl-images@%lX", (UINTN)(Fit));
+ UPLImageNode = FdtAddSubnode (Fdt, ParentNode, TempStr);
+
+ Data64 = CpuToFdt64 ((UINTN)Fit);
+ Status = FdtSetProperty (FdtBase, UPLImageNode, "addr", &Data64, sizeof (Data64));
+ }
+
+ CustomNode = FdtAddSubnode (Fdt, ParentNode, "upl-custom");
+ ASSERT (CustomNode > 0);
+
+ HobPtr = GetHobList ();
+ Data64 = CpuToFdt64 ((UINT64)(EFI_PHYSICAL_ADDRESS)HobPtr);
+ Status = FdtSetProperty (Fdt, CustomNode, "hoblistptr", &Data64, sizeof (Data64));
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ It will build FDT for UPL consumed.
+ @param[in] FdtBase Address of the Fdt data.
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to build required FDT.
+**/
+EFI_STATUS
+BuildFdtForUPL (
+ IN VOID *FdtBase
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Build FDT for memory related
+ //
+ Status = BuildFdtForMemory (FdtBase);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = BuildFdtForMemAlloc (FdtBase);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = BuildFdtForPciRootBridge (FdtBase);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = BuildFdtForFrameBuffer (FdtBase);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = BuildFdtForUplRequired (FdtBase);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c
new file mode 100644
index 0000000..0c45449
--- /dev/null
+++ b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.c
@@ -0,0 +1,164 @@
+/** @file
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <PiPei.h>
+#include <Pi/PiHob.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PrintLib.h>
+#include <Library/FdtLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+
+/**
+ Add a new HOB to the HOB List.
+
+ @param HobType Type of the new HOB.
+ @param HobLength Length of the new HOB to allocate.
+
+ @return NULL if there is no space to create a hob.
+ @return The address point to the new created hob.
+
+**/
+VOID *
+EFIAPI
+CreateHob (
+ IN UINT16 HobType,
+ IN UINT16 HobLength
+ );
+
+/**
+ Add HOB into HOB list
+ @param[in] Hob The HOB to be added into the HOB list.
+**/
+VOID
+AddNewHob (
+ IN EFI_PEI_HOB_POINTERS *Hob
+ );
+
+/**
+ Check the HOB and decide if it is need inside Payload
+ Payload maintainer may make decision which HOB is need or needn't
+ Then add the check logic in the function.
+ @param[in] Hob The HOB to check
+ @retval TRUE If HOB is need inside Payload
+ @retval FALSE If HOB is needn't inside Payload
+**/
+BOOLEAN
+EFIAPI
+FitIsHobNeed (
+ EFI_PEI_HOB_POINTERS Hob
+ )
+{
+ if (FixedPcdGetBool (PcdHandOffFdtEnable)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) {
+ return FALSE;
+ }
+
+ if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
+ if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gUniversalPayloadDeviceTreeGuid)) {
+ return FALSE;
+ }
+
+ if (CompareGuid (&Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
+ return FALSE;
+ }
+
+ if ((Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiReservedMemoryType) ||
+ (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiBootServicesCode) ||
+ (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiBootServicesData) ||
+ (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiRuntimeServicesCode) ||
+ (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiRuntimeServicesData) ||
+ (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiACPIReclaimMemory) ||
+ (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiACPIMemoryNVS))
+ {
+ return FALSE;
+ }
+ }
+
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+ return FALSE;
+ }
+ }
+
+ if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
+ if (CompareGuid (&Hob.Guid->Name, &gUniversalPayloadSerialPortInfoGuid)) {
+ return FALSE;
+ }
+
+ if (CompareGuid (&Hob.Guid->Name, &gUniversalPayloadAcpiTableGuid)) {
+ return FALSE;
+ }
+
+ if (CompareGuid (&Hob.Guid->Name, &gUniversalPayloadPciRootBridgeInfoGuid)) {
+ return FALSE;
+ }
+ }
+ }
+
+ // Arrive here mean the HOB is need
+ return TRUE;
+}
+
+/**
+ It will Parse FDT -custom node based on information from bootloaders.
+ @param[in] FdtBase The starting memory address of FdtBase
+ @param[in] HobList The starting memory address of New Hob list.
+
+**/
+UINTN
+EFIAPI
+CustomFdtNodeParser (
+ IN VOID *FdtBase,
+ IN VOID *HobList
+ )
+{
+ INT32 Node, CustomNode;
+ INT32 TempLen;
+ UINT64 *Data64;
+ UINTN CHobList;
+ CONST FDT_PROPERTY *PropertyPtr;
+ EFI_PEI_HOB_POINTERS Hob;
+
+ CHobList = (UINTN)HobList;
+
+ DEBUG ((DEBUG_INFO, "%a() #1 \n", __func__));
+
+ //
+ // Look for if exists hob list node
+ //
+ Node = FdtSubnodeOffsetNameLen (FdtBase, 0, "options", (INT32)AsciiStrLen ("options"));
+ if (Node > 0) {
+ DEBUG ((DEBUG_INFO, " Found options node (%08X)", Node));
+ CustomNode = FdtSubnodeOffsetNameLen (FdtBase, Node, "upl-custom", (INT32)AsciiStrLen ("upl-custom"));
+ if (CustomNode > 0) {
+ DEBUG ((DEBUG_INFO, " Found upl-custom node (%08X)", CustomNode));
+ PropertyPtr = FdtGetProperty (FdtBase, CustomNode, "hoblistptr", &TempLen);
+ Data64 = (UINT64 *)(PropertyPtr->Data);
+ CHobList = (UINTN)Fdt64ToCpu (*Data64);
+ DEBUG ((DEBUG_INFO, " Found hob list node (%08X)", CustomNode));
+ DEBUG ((DEBUG_INFO, " -pointer %016lX\n", CHobList));
+ }
+ }
+
+ Hob.Raw = (UINT8 *)CHobList;
+
+ //
+ // Since payload created new Hob, move all hobs except PHIT from boot loader hob list.
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (FitIsHobNeed (Hob)) {
+ // Add this hob to payload HOB
+ AddNewHob (&Hob);
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ return CHobList;
+}
diff --git a/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf
new file mode 100644
index 0000000..036ed43
--- /dev/null
+++ b/UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf
@@ -0,0 +1,46 @@
+## @file
+# Custom FDT Node Parse Library.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = CustomFdtNodeParserLib
+ FILE_GUID = 732B2B8F-65AD-4BF8-A98F-6E0D330F7A60
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CustomFdtNodeParserLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ CustomFdtNodeParserLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiPayloadPkg/UefiPayloadPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ FdtLib
+ HobLib
+ PcdLib
+
+[Guids]
+ gUniversalPayloadPciRootBridgeInfoGuid
+ gUniversalPayloadSerialPortInfoGuid
+ gUniversalPayloadDeviceTreeGuid
+ gUniversalPayloadAcpiTableGuid
+ gEfiHobMemoryAllocModuleGuid
+
+[Pcd]
+ gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable
diff --git a/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.c b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.c
new file mode 100644
index 0000000..4b2a8b9
--- /dev/null
+++ b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.c
@@ -0,0 +1,46 @@
+/** @file
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Uefi.h>
+#include <PiPei.h>
+#include <Pi/PiHob.h>
+
+/**
+ Check the HOB and decide if it is need inside Payload
+ Payload maintainer may make decision which HOB is need or needn't
+ Then add the check logic in the function.
+ @param[in] Hob The HOB to check
+ @retval TRUE If HOB is need inside Payload
+ @retval FALSE If HOB is needn't inside Payload
+**/
+BOOLEAN
+FitIsHobNeed (
+ EFI_PEI_HOB_POINTERS Hob
+ )
+{
+ return FALSE;
+}
+
+/**
+ It will Parse FDT -custom node based on information from bootloaders.
+ @param[in] FdtBase The starting memory address of FdtBase.
+ @param[in] HobList The starting memory address of New Hob list.
+ @retval HobList The base address of Hoblist.
+
+**/
+UINTN
+CustomFdtNodeParser (
+ IN VOID *Fdt,
+ IN VOID *HobList
+ )
+{
+ UINTN CHobList;
+
+ CHobList = 0;
+ if (HobList != NULL) {
+ CHobList = (UINTN)HobList;
+ }
+
+ return CHobList;
+}
diff --git a/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf
new file mode 100644
index 0000000..8410f04
--- /dev/null
+++ b/UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf
@@ -0,0 +1,27 @@
+## @file
+# Custom FDT Node Parse Library.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = CustomFdtNodeParserLibNull
+ FILE_GUID = 386496E4-37DB-4531-BA0C-16D126E63C55
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CustomFdtNodeParserLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ CustomFdtNodeParserNullLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
diff --git a/UefiPayloadPkg/Library/DebugPrintErrorLevelLibHob/DebugPrintErrorLevelLibHob.c b/UefiPayloadPkg/Library/DebugPrintErrorLevelLibHob/DebugPrintErrorLevelLibHob.c
index 10bdbe2..ecffc5c 100644
--- a/UefiPayloadPkg/Library/DebugPrintErrorLevelLibHob/DebugPrintErrorLevelLibHob.c
+++ b/UefiPayloadPkg/Library/DebugPrintErrorLevelLibHob/DebugPrintErrorLevelLibHob.c
@@ -35,6 +35,10 @@ GetDebugPrintErrorLevel (
UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader;
UEFI_PAYLOAD_DEBUG_PRINT_ERROR_LEVEL *DebugPrintErrorLevel;
+ if (GetHobList () == NULL) {
+ return PcdGet32 (PcdDebugPrintErrorLevel);
+ }
+
if (!gDebugPrintErrorLevelInitialized) {
gDebugPrintErrorLevelInitialized = TRUE;
gDebugPrintErrorLevel = PcdGet32 (PcdDebugPrintErrorLevel);
diff --git a/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf b/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
new file mode 100644
index 0000000..aacd3f1
--- /dev/null
+++ b/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
@@ -0,0 +1,65 @@
+## @file
+# Coreboot Table Parse Library.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FdtParseLib
+ FILE_GUID = 8956F72D-9626-4959-98B7-1BD4A3EA687E
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FdtParseLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ FdtParserLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiPayloadPkg/UefiPayloadPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ PcdLib
+ HobLib
+ FdtLib
+ CustomFdtNodeParserLib
+
+[Guids]
+ gUniversalPayloadDeviceTreeGuid
+ gEfiGraphicsInfoHobGuid
+ gEfiGraphicsDeviceInfoHobGuid
+ gUniversalPayloadAcpiTableGuid
+ gUniversalPayloadSerialPortInfoGuid
+ gUplPciSegmentInfoHobGuid
+
+[Pcd.IA32,Pcd.X64,Pcd.RISCV64]
+ gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
+ gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+ gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable
+ gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
+ gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemBase
+ gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemLimit
+ gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBBase
+ gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBLimit
+ gUefiPayloadPkgTokenSpaceGuid.SizeOfIoSpace
+
+
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /wd4305
+ GCC:*_*_IA32_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_X64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_ARM_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_AARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_RISCV64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_LOONGARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
diff --git a/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c b/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c
new file mode 100644
index 0000000..9bece35
--- /dev/null
+++ b/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c
@@ -0,0 +1,1039 @@
+/** @file
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Guid/MemoryAllocationHob.h>
+#include <Guid/DebugPrintErrorLevel.h>
+#include <Guid/SerialPortInfoGuid.h>
+#include <Guid/MemoryMapInfoGuid.h>
+#include <Guid/AcpiBoardInfoGuid.h>
+#include <Guid/GraphicsInfoHob.h>
+#include <Guid/UniversalPayloadBase.h>
+#include <UniversalPayload/SmbiosTable.h>
+#include <UniversalPayload/AcpiTable.h>
+#include <UniversalPayload/UniversalPayload.h>
+#include <UniversalPayload/ExtraData.h>
+#include <UniversalPayload/SerialPortInfo.h>
+#include <UniversalPayload/DeviceTree.h>
+#include <UniversalPayload/PciRootBridges.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/PrintLib.h>
+#include <Library/FdtLib.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciIo.h>
+#include <Guid/PciSegmentInfoGuid.h>
+
+typedef enum {
+ ReservedMemory = 1,
+ Memory,
+ FrameBuffer,
+ PciRootBridge,
+ Options,
+ DoNothing
+} FDT_NODE_TYPE;
+
+#define MEMORY_ATTRIBUTE_DEFAULT (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
+ EFI_RESOURCE_ATTRIBUTE_TESTED | \
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | \
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | \
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | \
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE )
+
+#define ROOT_BRIDGE_SUPPORTS_DEFAULT (EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | \
+ EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | \
+ EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 | \
+ EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | \
+ EFI_PCI_IO_ATTRIBUTE_VGA_IO | \
+ EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | \
+ EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | \
+ EFI_PCI_IO_ATTRIBUTE_ISA_IO | \
+ EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO )
+
+extern VOID *mHobList;
+UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *mPciRootBridgeInfo = NULL;
+INT32 mNode[0x500] = { 0 };
+UINT32 mNodeIndex = 0;
+UPL_PCI_SEGMENT_INFO_HOB *mUplPciSegmentInfoHob;
+
+/**
+ Build a Handoff Information Table HOB
+
+ This function initialize a HOB region from EfiMemoryBegin to
+ EfiMemoryTop. And EfiFreeMemoryBottom and EfiFreeMemoryTop should
+ be inside the HOB region.
+
+ @param[in] EfiMemoryBottom Total memory start address
+ @param[in] EfiMemoryTop Total memory end address.
+ @param[in] EfiFreeMemoryBottom Free memory start address
+ @param[in] EfiFreeMemoryTop Free memory end address.
+
+ @return The pointer to the handoff HOB table.
+
+**/
+EFI_HOB_HANDOFF_INFO_TABLE *
+EFIAPI
+HobConstructor (
+ IN VOID *EfiMemoryBottom,
+ IN VOID *EfiMemoryTop,
+ IN VOID *EfiFreeMemoryBottom,
+ IN VOID *EfiFreeMemoryTop
+ );
+
+/**
+ It will record the memory node initialized.
+
+ @param[in] Node memory node is going to parsing..
+**/
+VOID
+RecordMemoryNode (
+ INT32 Node
+ )
+{
+ DEBUG ((DEBUG_INFO, "\n RecordMemoryNode %x , mNodeIndex :%x \n", Node, mNodeIndex));
+ mNode[mNodeIndex] = Node;
+ mNodeIndex++;
+}
+
+/**
+ Check the memory node if initialized.
+
+ @param[in] Node memory node is going to parsing..
+
+ @return TRUE memory node was initialized. don't parse it again.
+ @return FALSE memory node wasn't initialized , go to parse it.
+**/
+BOOLEAN
+CheckMemoryNodeIfInit (
+ INT32 Node
+ )
+{
+ UINT32 i;
+
+ for (i = 0; i < mNodeIndex; i++) {
+ if (mNode[i] == Node) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ It will check device node from FDT.
+
+ @param[in] NodeString Device node name string.
+ @param[in] Depth Check layer of Device node , only parse the 1st layer
+
+ @return FDT_NODE_TYPE what type of the device node.
+**/
+FDT_NODE_TYPE
+CheckNodeType (
+ CHAR8 *NodeString,
+ INT32 Depth
+ )
+{
+ DEBUG ((DEBUG_INFO, "\n CheckNodeType %a \n", NodeString));
+ if (AsciiStrnCmp (NodeString, "reserved-memory", AsciiStrLen ("reserved-memory")) == 0 ) {
+ return ReservedMemory;
+ } else if (AsciiStrnCmp (NodeString, "memory@", AsciiStrLen ("memory@")) == 0 ) {
+ return Memory;
+ } else if (AsciiStrnCmp (NodeString, "framebuffer@", AsciiStrLen ("framebuffer@")) == 0) {
+ return FrameBuffer;
+ } else if (AsciiStrnCmp (NodeString, "pci-rb", AsciiStrLen ("pci-rb")) == 0 ) {
+ return PciRootBridge;
+ } else if (AsciiStrCmp (NodeString, "options") == 0) {
+ return Options;
+ } else {
+ return DoNothing;
+ }
+}
+
+/**
+ It will ParseMemory node from FDT.
+
+ @param[in] Fdt Address of the Fdt data.
+ @param[in] SubNode first node of the PCI root bridge node.
+**/
+VOID
+ParseMemory (
+ IN VOID *Fdt,
+ IN INT32 Node
+ )
+{
+ UINT32 Attribute;
+ UINT8 ECCAttribute;
+ UINT32 ECCData, ECCData2;
+ INT32 Property;
+ CONST FDT_PROPERTY *PropertyPtr;
+ INT32 TempLen;
+ CONST CHAR8 *TempStr;
+ UINT64 *Data64;
+ UINT32 *Data32;
+ UINT64 StartAddress;
+ UINT64 NumberOfBytes;
+
+ Attribute = MEMORY_ATTRIBUTE_DEFAULT;
+ ECCAttribute = 0;
+ ECCData = ECCData2 = 0;
+ for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) {
+ PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
+ TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL);
+ if (AsciiStrCmp (TempStr, "reg") == 0) {
+ Data64 = (UINT64 *)(PropertyPtr->Data);
+ StartAddress = Fdt64ToCpu (*Data64);
+ NumberOfBytes = Fdt64ToCpu (*(Data64 + 1));
+ } else if (AsciiStrCmp (TempStr, "ecc-detection-bits") == 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ ECCData = Fdt32ToCpu (*Data32);
+ } else if (AsciiStrCmp (TempStr, "ecc-correction-bits") == 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ ECCData2 = Fdt32ToCpu (*Data32);
+ }
+ }
+
+ if (ECCData == ECCData2) {
+ if (ECCData == 1) {
+ ECCAttribute = EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC;
+ } else if (ECCData == 2) {
+ ECCAttribute = EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC;
+ }
+ }
+
+ if (ECCAttribute != 0) {
+ Attribute |= ECCAttribute;
+ }
+
+ BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attribute, StartAddress, NumberOfBytes);
+}
+
+/**
+ It will ParseReservedMemory node from FDT.
+
+ @param[in] Fdt Address of the Fdt data.
+ @param[in] SubNode first node of the PCI root bridge node.
+**/
+VOID
+ParseReservedMemory (
+ IN VOID *Fdt,
+ IN INT32 Node
+ )
+{
+ INT32 SubNode;
+ INT32 TempLen;
+ CONST CHAR8 *TempStr;
+ CONST FDT_PROPERTY *PropertyPtr;
+ UINT64 *Data64;
+ UINT64 StartAddress;
+ UINT64 NumberOfBytes;
+ UNIVERSAL_PAYLOAD_ACPI_TABLE *PlatformAcpiTable;
+ UNIVERSAL_PAYLOAD_SMBIOS_TABLE *SmbiosTable;
+ FDT_NODE_HEADER *NodePtr;
+ UINT32 Attribute;
+
+ PlatformAcpiTable = NULL;
+
+ for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode = FdtNextSubnode (Fdt, SubNode)) {
+ NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
+ DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr->Name));
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg", &TempLen);
+ ASSERT (TempLen > 0);
+ TempStr = (CHAR8 *)(PropertyPtr->Data);
+ if (TempLen > 0) {
+ Data64 = (UINT64 *)(PropertyPtr->Data);
+ StartAddress = Fdt64ToCpu (*Data64);
+ NumberOfBytes = Fdt64ToCpu (*(Data64 + 1));
+ DEBUG ((DEBUG_INFO, "\n Property %a", TempStr));
+ DEBUG ((DEBUG_INFO, " %016lX %016lX", StartAddress, NumberOfBytes));
+ }
+
+ RecordMemoryNode (SubNode);
+
+ if (AsciiStrnCmp (NodePtr->Name, "mmio@", AsciiStrLen ("mmio@")) == 0) {
+ DEBUG ((DEBUG_INFO, " MemoryMappedIO"));
+ BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiMemoryMappedIO);
+ } else {
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "compatible", &TempLen);
+ TempStr = (CHAR8 *)(PropertyPtr->Data);
+ if (AsciiStrnCmp (TempStr, "boot-code", AsciiStrLen ("boot-code")) == 0) {
+ DEBUG ((DEBUG_INFO, " boot-code"));
+ BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesCode);
+ } else if (AsciiStrnCmp (TempStr, "boot-data", AsciiStrLen ("boot-data")) == 0) {
+ DEBUG ((DEBUG_INFO, " boot-data"));
+ BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesData);
+ } else if (AsciiStrnCmp (TempStr, "runtime-code", AsciiStrLen ("runtime-code")) == 0) {
+ DEBUG ((DEBUG_INFO, " runtime-code"));
+ BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiRuntimeServicesCode);
+ } else if (AsciiStrnCmp (TempStr, "runtime-data", AsciiStrLen ("runtime-data")) == 0) {
+ DEBUG ((DEBUG_INFO, " runtime-data"));
+ BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiRuntimeServicesData);
+ } else if (AsciiStrnCmp (TempStr, "special-purpose", AsciiStrLen ("special-purpose")) == 0) {
+ Attribute = MEMORY_ATTRIBUTE_DEFAULT | EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE;
+ DEBUG ((DEBUG_INFO, " special-purpose memory"));
+ BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attribute, StartAddress, NumberOfBytes);
+ } else if (AsciiStrnCmp (TempStr, "acpi", AsciiStrLen ("acpi")) == 0) {
+ DEBUG ((DEBUG_INFO, " acpi, StartAddress:%x, NumberOfBytes:%x", StartAddress, NumberOfBytes));
+ BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesData);
+ PlatformAcpiTable = BuildGuidHob (&gUniversalPayloadAcpiTableGuid, sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE));
+ if (PlatformAcpiTable != NULL) {
+ DEBUG ((DEBUG_INFO, " build gUniversalPayloadAcpiTableGuid , NumberOfBytes:%x", NumberOfBytes));
+ PlatformAcpiTable->Rsdp = (EFI_PHYSICAL_ADDRESS)(UINTN)StartAddress;
+ PlatformAcpiTable->Header.Revision = UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION;
+ PlatformAcpiTable->Header.Length = sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE);
+ }
+ } else if (AsciiStrnCmp (TempStr, "smbios", AsciiStrLen ("smbios")) == 0) {
+ DEBUG ((DEBUG_INFO, " build smbios, NumberOfBytes:%x", NumberOfBytes));
+ BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiBootServicesData);
+ SmbiosTable = BuildGuidHob (&gUniversalPayloadSmbios3TableGuid, sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE));
+ if (SmbiosTable != NULL) {
+ SmbiosTable->Header.Revision = UNIVERSAL_PAYLOAD_SMBIOS_TABLE_REVISION;
+ SmbiosTable->Header.Length = sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE);
+ SmbiosTable->SmBiosEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)(StartAddress);
+ }
+ } else if (AsciiStrnCmp (TempStr, "acpi-nvs", AsciiStrLen ("acpi-nvs")) == 0) {
+ DEBUG ((DEBUG_INFO, " acpi-nvs"));
+ BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiACPIMemoryNVS);
+ } else {
+ BuildMemoryAllocationHob (StartAddress, NumberOfBytes, EfiReservedMemoryType);
+ }
+ }
+ }
+}
+
+/**
+ It will ParseFrameBuffer node from FDT.
+
+ @param[in] Fdt Address of the Fdt data.
+ @param[in] SubNode first Sub node of the PCI root bridge node.
+
+ @return GmaStr Graphic device node name string.
+**/
+CHAR8 *
+ParseFrameBuffer (
+ IN VOID *Fdt,
+ IN INT32 Node
+ )
+{
+ INT32 Property;
+ INT32 TempLen;
+ CONST FDT_PROPERTY *PropertyPtr;
+ CONST CHAR8 *TempStr;
+ UINT32 *Data32;
+ UINT64 FrameBufferBase;
+ UINT32 FrameBufferSize;
+ EFI_PEI_GRAPHICS_INFO_HOB *GraphicsInfo;
+ CHAR8 *GmaStr;
+
+ GmaStr = "Gma";
+ //
+ // Create GraphicInfo HOB.
+ //
+ GraphicsInfo = BuildGuidHob (&gEfiGraphicsInfoHobGuid, sizeof (EFI_PEI_GRAPHICS_INFO_HOB));
+ ASSERT (GraphicsInfo != NULL);
+ if (GraphicsInfo == NULL) {
+ return GmaStr;
+ }
+
+ ZeroMem (GraphicsInfo, sizeof (EFI_PEI_GRAPHICS_INFO_HOB));
+
+ for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) {
+ PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
+ TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL);
+ if (AsciiStrCmp (TempStr, "reg") == 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ FrameBufferBase = Fdt32ToCpu (*(Data32 + 0));
+ FrameBufferSize = Fdt32ToCpu (*(Data32 + 1));
+ GraphicsInfo->FrameBufferBase = FrameBufferBase;
+ GraphicsInfo->FrameBufferSize = (UINT32)FrameBufferSize;
+ } else if (AsciiStrCmp (TempStr, "width") == 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ GraphicsInfo->GraphicsMode.HorizontalResolution = Fdt32ToCpu (*Data32);
+ } else if (AsciiStrCmp (TempStr, "height") == 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ GraphicsInfo->GraphicsMode.VerticalResolution = Fdt32ToCpu (*Data32);
+ } else if (AsciiStrCmp (TempStr, "format") == 0) {
+ TempStr = (CHAR8 *)(PropertyPtr->Data);
+ if (AsciiStrCmp (TempStr, "a8r8g8b8") == 0) {
+ GraphicsInfo->GraphicsMode.PixelFormat = PixelRedGreenBlueReserved8BitPerColor;
+ } else if (AsciiStrCmp (TempStr, "a8b8g8r8") == 0) {
+ GraphicsInfo->GraphicsMode.PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
+ } else {
+ GraphicsInfo->GraphicsMode.PixelFormat = PixelFormatMax;
+ }
+ } else if (AsciiStrCmp (TempStr, "display") == 0) {
+ GmaStr = (CHAR8 *)(PropertyPtr->Data);
+ GmaStr++;
+ DEBUG ((DEBUG_INFO, " display (%s)", GmaStr));
+ }
+ }
+
+ return GmaStr;
+}
+
+/**
+ It will ParseOptions node from FDT.
+
+ @param[in] Fdt Address of the Fdt data.
+ @param[in] SubNode first Sub node of the PCI root bridge node.
+ @param[out] PciEnumDone Init ParsePciRootBridge node for ParsePciRootBridge.
+ @param[out] BootMode Init the system boot mode
+**/
+VOID
+ParseOptions (
+ IN VOID *Fdt,
+ IN INT32 Node,
+ OUT UINT8 *PciEnumDone,
+ OUT EFI_BOOT_MODE *BootMode
+ )
+{
+ INT32 SubNode;
+ FDT_NODE_HEADER *NodePtr;
+ UNIVERSAL_PAYLOAD_BASE *PayloadBase;
+ CONST FDT_PROPERTY *PropertyPtr;
+ CONST CHAR8 *TempStr;
+ INT32 TempLen;
+ UINT32 *Data32;
+ UINT64 *Data64;
+ UINT64 StartAddress;
+ UINT8 SizeOfMemorySpace;
+
+ for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode = FdtNextSubnode (Fdt, SubNode)) {
+ NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
+ DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr->Name));
+
+ if (AsciiStrnCmp (NodePtr->Name, "upl-images@", AsciiStrLen ("upl-images@")) == 0) {
+ DEBUG ((DEBUG_INFO, " Found image@ node \n"));
+ //
+ // Build PayloadBase HOB .
+ //
+ PayloadBase = BuildGuidHob (&gUniversalPayloadBaseGuid, sizeof (UNIVERSAL_PAYLOAD_BASE));
+ ASSERT (PayloadBase != NULL);
+ if (PayloadBase == NULL) {
+ return;
+ }
+
+ PayloadBase->Header.Revision = UNIVERSAL_PAYLOAD_BASE_REVISION;
+ PayloadBase->Header.Length = sizeof (UNIVERSAL_PAYLOAD_BASE);
+
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "addr", &TempLen);
+
+ ASSERT (TempLen > 0);
+ if (TempLen > 0) {
+ Data64 = (UINT64 *)(PropertyPtr->Data);
+ StartAddress = Fdt64ToCpu (*Data64);
+ DEBUG ((DEBUG_INFO, "\n Property(00000000) entry"));
+ DEBUG ((DEBUG_INFO, " %016lX\n", StartAddress));
+
+ PayloadBase->Entry = (EFI_PHYSICAL_ADDRESS)StartAddress;
+ }
+ }
+
+ if (AsciiStrnCmp (NodePtr->Name, "upl-params", AsciiStrLen ("upl-params")) == 0) {
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "addr-width", &TempLen);
+ if (TempLen > 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ DEBUG ((DEBUG_INFO, "\n Property(00000000) address_width"));
+ DEBUG ((DEBUG_INFO, " %X", Fdt32ToCpu (*Data32)));
+ SizeOfMemorySpace = (UINT8)Fdt32ToCpu (*Data32);
+ BuildCpuHob (SizeOfMemorySpace, PcdGet8 (SizeOfIoSpace));
+ }
+
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "pci-enum-done", &TempLen);
+ if (TempLen > 0) {
+ *PciEnumDone = 1;
+ DEBUG ((DEBUG_INFO, " Found PciEnumDone (%08X)\n", *PciEnumDone));
+ } else {
+ *PciEnumDone = 0;
+ DEBUG ((DEBUG_INFO, " Not Found PciEnumDone \n"));
+ }
+
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "boot-mode", &TempLen);
+ if (TempLen > 0) {
+ TempStr = (CHAR8 *)(PropertyPtr->Data);
+ if (AsciiStrCmp (TempStr, "normal") == 0) {
+ *BootMode = BOOT_WITH_FULL_CONFIGURATION;
+ } else if (AsciiStrCmp (TempStr, "fast") == 0) {
+ *BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
+ } else if (AsciiStrCmp (TempStr, "full") == 0) {
+ *BootMode = BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS;
+ } else if (AsciiStrCmp (TempStr, "default") == 0) {
+ *BootMode = BOOT_WITH_DEFAULT_SETTINGS;
+ } else if (AsciiStrCmp (TempStr, "s4") == 0) {
+ *BootMode = BOOT_ON_S4_RESUME;
+ } else if (AsciiStrCmp (TempStr, "s3") == 0) {
+ *BootMode = BOOT_ON_S3_RESUME;
+ }
+ }
+ }
+ }
+}
+
+/**
+ It will Parsegraphic node from FDT.
+
+ @param[in] Fdt Address of the Fdt data.
+ @param[in] SubNode first Sub node of the PCI root bridge node.
+**/
+VOID
+ParsegraphicNode (
+ IN VOID *Fdt,
+ IN INT32 SubNode
+ )
+{
+ EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *GraphicsDev;
+ CONST FDT_PROPERTY *PropertyPtr;
+ UINT16 GmaID;
+ UINT32 *Data32;
+ INT32 TempLen;
+
+ DEBUG ((DEBUG_INFO, " Found gma@ node \n"));
+ GraphicsDev = NULL;
+ //
+ // Build Graphic info HOB .
+ //
+ GraphicsDev = BuildGuidHob (&gEfiGraphicsDeviceInfoHobGuid, sizeof (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB));
+ ASSERT (GraphicsDev != NULL);
+ if (GraphicsDev == NULL) {
+ return;
+ }
+
+ SetMem (GraphicsDev, sizeof (EFI_PEI_GRAPHICS_DEVICE_INFO_HOB), 0xFF);
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "vendor-id", &TempLen);
+ ASSERT (TempLen > 0);
+ if (TempLen > 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ GmaID = (UINT16)Fdt32ToCpu (*Data32);
+ DEBUG ((DEBUG_INFO, "\n vendor-id"));
+ DEBUG ((DEBUG_INFO, " %016lX\n", GmaID));
+ GraphicsDev->VendorId = GmaID;
+ }
+
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "device-id", &TempLen);
+ ASSERT (TempLen > 0);
+ if (TempLen > 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ GmaID = (UINT16)Fdt32ToCpu (*Data32);
+ DEBUG ((DEBUG_INFO, "\n device-id"));
+ DEBUG ((DEBUG_INFO, " %016lX\n", GmaID));
+ GraphicsDev->DeviceId = GmaID;
+ }
+
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "revision-id", &TempLen);
+ ASSERT (TempLen > 0);
+ if (TempLen > 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ GmaID = (UINT16)Fdt32ToCpu (*Data32);
+ DEBUG ((DEBUG_INFO, "\n revision-id"));
+ DEBUG ((DEBUG_INFO, " %016lX\n", GmaID));
+ GraphicsDev->RevisionId = (UINT8)GmaID;
+ }
+
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "subsystem-vendor-id", &TempLen);
+ ASSERT (TempLen > 0);
+ if (TempLen > 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ GmaID = (UINT16)Fdt32ToCpu (*Data32);
+ DEBUG ((DEBUG_INFO, "\n subsystem-vendor-id"));
+ DEBUG ((DEBUG_INFO, " %016lX\n", GmaID));
+ GraphicsDev->SubsystemVendorId = GmaID;
+ }
+
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "subsystem-id", &TempLen);
+ ASSERT (TempLen > 0);
+ if (TempLen > 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ GmaID = (UINT16)Fdt32ToCpu (*Data32);
+ DEBUG ((DEBUG_INFO, "\n subsystem-id"));
+ DEBUG ((DEBUG_INFO, " %016lX\n", GmaID));
+ GraphicsDev->SubsystemId = GmaID;
+ }
+}
+
+/**
+ It will ParseSerialPort node from FDT.
+
+ @param[in] Fdt Address of the Fdt data.
+ @param[in] SubNode first Sub node of the PCI root bridge node.
+**/
+VOID
+ParseSerialPort (
+ IN VOID *Fdt,
+ IN INT32 SubNode
+ )
+{
+ UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *Serial;
+ CONST FDT_PROPERTY *PropertyPtr;
+ INT32 TempLen;
+ CONST CHAR8 *TempStr;
+ UINT32 *Data32;
+ UINT32 Attribute;
+
+ //
+ // Create SerialPortInfo HOB.
+ //
+ Serial = BuildGuidHob (&gUniversalPayloadSerialPortInfoGuid, sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO));
+ ASSERT (Serial != NULL);
+ if (Serial == NULL) {
+ return;
+ }
+
+ Serial->Header.Revision = UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO_REVISION;
+ Serial->Header.Length = sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO);
+ Serial->RegisterStride = 1;
+ Serial->UseMmio = 1;
+
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "current-speed", &TempLen);
+ ASSERT (TempLen > 0);
+ if (TempLen > 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ DEBUG ((DEBUG_INFO, " %X", Fdt32ToCpu (*Data32)));
+ Serial->BaudRate = Fdt32ToCpu (*Data32);
+ }
+
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "compatible", &TempLen);
+ TempStr = (CHAR8 *)(PropertyPtr->Data);
+ if (AsciiStrnCmp (TempStr, "isa", AsciiStrLen ("isa")) == 0) {
+ DEBUG ((DEBUG_INFO, " find serial compatible isa \n"));
+ Serial->UseMmio = 0;
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg", &TempLen);
+ ASSERT (TempLen > 0);
+ if (TempLen > 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ Attribute = Fdt32ToCpu (*(Data32 + 0));
+ Serial->RegisterBase = Fdt32ToCpu (*(Data32 + 1));
+ Serial->UseMmio = Attribute == 1 ? FALSE : TRUE;
+ DEBUG ((DEBUG_INFO, "\n in espi serial Property() %a", TempStr));
+ DEBUG ((DEBUG_INFO, " StartAddress %016lX\n", Serial->RegisterBase));
+ DEBUG ((DEBUG_INFO, " Attribute %016lX\n", Attribute));
+ }
+ } else {
+ DEBUG ((DEBUG_INFO, " NOT serial compatible isa \n"));
+ PropertyPtr = FdtGetProperty (Fdt, SubNode, "reg", &TempLen);
+ ASSERT (TempLen > 0);
+ if (TempLen > 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ Serial->RegisterBase = Fdt32ToCpu (*Data32);
+ }
+ }
+}
+
+/**
+ It will ParsePciRootBridge node from FDT.
+
+ @param[in] Fdt Address of the Fdt data.
+ @param[in] Node first node of the Fdt data.
+ @param[in] PciEnumDone To use ParsePciRootBridge node.
+ @param[in] RootBridgeCount Number of pci RootBridge.
+ @param[in] GmaStr Graphic device node name string.
+ @param[in] index Index of ParsePciRootBridge node.
+**/
+VOID
+ParsePciRootBridge (
+ IN VOID *Fdt,
+ IN INT32 Node,
+ IN UINT8 RootBridgeCount,
+ IN CHAR8 *GmaStr,
+ IN UINT8 *index
+ )
+{
+ INT32 SubNode;
+ INT32 Property;
+ INT32 SSubNode;
+ FDT_NODE_HEADER *NodePtr;
+ CONST FDT_PROPERTY *PropertyPtr;
+ INT32 TempLen;
+ UINT32 *Data32;
+ UINT32 MemType;
+ CONST CHAR8 *TempStr;
+ UINT8 RbIndex;
+ UINTN HobDataSize;
+ UINT8 Base;
+
+ if (RootBridgeCount == 0) {
+ return;
+ }
+
+ RbIndex = *index;
+ HobDataSize = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES) + (RootBridgeCount * sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE));
+ //
+ // Create PCI Root Bridge Info Hob.
+ //
+ if (mPciRootBridgeInfo == NULL) {
+ mPciRootBridgeInfo = BuildGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid, HobDataSize);
+ ASSERT (mPciRootBridgeInfo != NULL);
+ if (mPciRootBridgeInfo == NULL) {
+ return;
+ }
+
+ ZeroMem (mPciRootBridgeInfo, HobDataSize);
+ mPciRootBridgeInfo->Header.Length = (UINT16)HobDataSize;
+ mPciRootBridgeInfo->Header.Revision = UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION;
+ mPciRootBridgeInfo->Count = RootBridgeCount;
+ mPciRootBridgeInfo->ResourceAssigned = FALSE;
+ }
+
+ if (mUplPciSegmentInfoHob == NULL) {
+ HobDataSize = sizeof (UPL_PCI_SEGMENT_INFO_HOB) + ((RootBridgeCount) * sizeof (UPL_SEGMENT_INFO));
+ mUplPciSegmentInfoHob = BuildGuidHob (&gUplPciSegmentInfoHobGuid, HobDataSize);
+ if (mUplPciSegmentInfoHob != NULL) {
+ ZeroMem (mUplPciSegmentInfoHob, HobDataSize);
+ mUplPciSegmentInfoHob->Header.Revision = UNIVERSAL_PAYLOAD_PCI_SEGMENT_INFO_REVISION;
+ mUplPciSegmentInfoHob->Header.Length = (UINT16)HobDataSize;
+ mUplPciSegmentInfoHob->Count = RootBridgeCount;
+ }
+ }
+
+ for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode = FdtNextSubnode (Fdt, SubNode)) {
+ NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
+ DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr->Name));
+
+ if (AsciiStrnCmp (NodePtr->Name, GmaStr, AsciiStrLen (GmaStr)) == 0) {
+ DEBUG ((DEBUG_INFO, " Found gma@ node \n"));
+ ParsegraphicNode (Fdt, SubNode);
+ }
+
+ if (AsciiStrnCmp (NodePtr->Name, "isa", AsciiStrLen ("isa")) == 0) {
+ SSubNode = FdtFirstSubnode (Fdt, SubNode); // serial
+ ParseSerialPort (Fdt, SSubNode);
+ }
+
+ if (AsciiStrnCmp (NodePtr->Name, "serial@", AsciiStrLen ("serial@")) == 0) {
+ ParseSerialPort (Fdt, SubNode);
+ }
+ }
+
+ for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) {
+ PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
+ TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL);
+
+ if (AsciiStrCmp (TempStr, "ranges") == 0) {
+ DEBUG ((DEBUG_INFO, " Found ranges Property TempLen (%08X), limit %x\n", TempLen, TempLen/sizeof (UINT32)));
+
+ mPciRootBridgeInfo->RootBridge[RbIndex].AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
+ mPciRootBridgeInfo->RootBridge[RbIndex].Supports = ROOT_BRIDGE_SUPPORTS_DEFAULT;
+ mPciRootBridgeInfo->RootBridge[RbIndex].PMemAbove4G.Base = PcdGet64 (PcdPciReservedPMemAbove4GBBase);
+ mPciRootBridgeInfo->RootBridge[RbIndex].PMemAbove4G.Limit = PcdGet64 (PcdPciReservedPMemAbove4GBLimit);
+ mPciRootBridgeInfo->RootBridge[RbIndex].PMem.Base = PcdGet32 (PcdPciReservedPMemBase);
+ mPciRootBridgeInfo->RootBridge[RbIndex].PMem.Limit = PcdGet32 (PcdPciReservedPMemLimit);
+ mPciRootBridgeInfo->RootBridge[RbIndex].UID = RbIndex;
+ mPciRootBridgeInfo->RootBridge[RbIndex].HID = EISA_PNP_ID (0x0A03);
+
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ for (Base = 0; Base < TempLen/sizeof (UINT32); Base = Base + DWORDS_TO_NEXT_ADDR_TYPE) {
+ DEBUG ((DEBUG_INFO, " Base :%x \n", Base));
+ MemType = Fdt32ToCpu (*(Data32 + Base));
+ if (((MemType) & (SS_64BIT_MEMORY_SPACE)) == SS_64BIT_MEMORY_SPACE) {
+ mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base = Fdt32ToCpu (*(Data32 + Base + 2)) + LShiftU64 (Fdt32ToCpu (*(Data32 + Base + 1)), 32);
+ mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base + LShiftU64 (Fdt32ToCpu (*(Data32 + Base + 5)), 32) + Fdt32ToCpu (*(Data32 + Base + 6)) -1;
+ } else if (((MemType) & (SS_32BIT_MEMORY_SPACE)) == SS_32BIT_MEMORY_SPACE) {
+ mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base = Fdt32ToCpu (*(Data32 + Base + 2));
+ mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base + Fdt32ToCpu (*(Data32 + Base + 6)) -1;
+ } else if (((MemType) & (SS_IO_SPACE)) == SS_IO_SPACE) {
+ mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base = Fdt32ToCpu (*(Data32 + Base + 2));
+ mPciRootBridgeInfo->RootBridge[RbIndex].Io.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base + Fdt32ToCpu (*(Data32 + Base + 6)) -1;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "RootBridgeCount %x, index :%x\n", RootBridgeCount, RbIndex));
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.Base %x, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Mem.limit %x, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Limit));
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.Base %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->MemAbove4G.limit %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Limit));
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Io.Base %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Io.limit %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Io.Limit));
+ }
+
+ if (AsciiStrCmp (TempStr, "reg") == 0) {
+ UINT64 *Data64 = (UINT64 *)(PropertyPtr->Data);
+ mUplPciSegmentInfoHob->SegmentInfo[RbIndex].BaseAddress = Fdt64ToCpu (*Data64);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Ecam.Base %llx, \n", mUplPciSegmentInfoHob->SegmentInfo[RbIndex].BaseAddress));
+ }
+
+ if (AsciiStrCmp (TempStr, "bus-range") == 0) {
+ Data32 = (UINT32 *)(PropertyPtr->Data);
+ mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Base = Fdt32ToCpu (*Data32) & 0xFF;
+ mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Limit = Fdt32ToCpu (*(Data32 + 1)) & 0xFF;
+ mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Translation = 0;
+
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.Base %x, index %x\n", mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Base, RbIndex));
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Bus.limit %x, index %x\n", mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Limit, RbIndex));
+ }
+ }
+
+ if (RbIndex > 0) {
+ RbIndex--;
+ }
+
+ *index = RbIndex;
+}
+
+/**
+ It will parse FDT based on DTB from bootloaders.
+
+ @param[in] FdtBase Address of the Fdt data.
+
+ @return The address to the new hob list
+**/
+UINTN
+EFIAPI
+ParseDtb (
+ IN VOID *FdtBase
+ )
+{
+ VOID *Fdt;
+ INT32 Node;
+ INT32 Property;
+ INT32 Depth;
+ FDT_NODE_HEADER *NodePtr;
+ CONST FDT_PROPERTY *PropertyPtr;
+ CONST CHAR8 *TempStr;
+ INT32 TempLen;
+ UINT64 *Data64;
+ UINT64 StartAddress;
+ UINT64 NumberOfBytes;
+ UINTN MinimalNeededSize;
+ EFI_PHYSICAL_ADDRESS FreeMemoryBottom;
+ EFI_PHYSICAL_ADDRESS FreeMemoryTop;
+ EFI_PHYSICAL_ADDRESS MemoryBottom;
+ EFI_PHYSICAL_ADDRESS MemoryTop;
+ BOOLEAN IsHobConstructed;
+ UINTN NewHobList;
+ UINT8 RootBridgeCount;
+ UINT8 index;
+ UINT8 PciEnumDone;
+ UINT8 NodeType;
+ EFI_BOOT_MODE BootMode;
+ CHAR8 *GmaStr;
+ INTN NumRsv;
+ EFI_PHYSICAL_ADDRESS Addr;
+ UINT64 Size;
+ UINT16 SegmentNumber;
+ UINT64 CurrentPciBaseAddress;
+ UINT64 NextPciBaseAddress;
+ UINT8 *RbSegNumAlreadyAssigned;
+ UINT8 NumberOfRbSegNumAlreadyAssigned;
+
+ Fdt = FdtBase;
+ Depth = 0;
+ MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
+ IsHobConstructed = FALSE;
+ NewHobList = 0;
+ RootBridgeCount = 0;
+ index = 0;
+ // TODO: This value comes from FDT. Currently there is a bug in implementation
+ // which assumes node ordering. Which requires a fix.
+ PciEnumDone = 1;
+ BootMode = 0;
+ NodeType = 0;
+
+ DEBUG ((DEBUG_INFO, "FDT = 0x%x %x\n", Fdt, Fdt32ToCpu (*((UINT32 *)Fdt))));
+ DEBUG ((DEBUG_INFO, "Start parsing DTB data\n"));
+ DEBUG ((DEBUG_INFO, "MinimalNeededSize :%x\n", MinimalNeededSize));
+
+ for (Node = FdtNextNode (Fdt, 0, &Depth); Node >= 0; Node = FdtNextNode (Fdt, Node, &Depth)) {
+ NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + Node + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
+ DEBUG ((DEBUG_INFO, "\n Node(%08x) %a Depth %x", Node, NodePtr->Name, Depth));
+ // memory node
+ if (AsciiStrnCmp (NodePtr->Name, "memory@", AsciiStrLen ("memory@")) == 0) {
+ for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) {
+ PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
+ TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL);
+ if (AsciiStrCmp (TempStr, "reg") == 0) {
+ Data64 = (UINT64 *)(PropertyPtr->Data);
+ StartAddress = Fdt64ToCpu (*Data64);
+ NumberOfBytes = Fdt64ToCpu (*(Data64 + 1));
+ DEBUG ((DEBUG_INFO, "\n Property(%08X) %a", Property, TempStr));
+ DEBUG ((DEBUG_INFO, " %016lX %016lX", StartAddress, NumberOfBytes));
+ if (!IsHobConstructed) {
+ if ((NumberOfBytes > MinimalNeededSize) && (StartAddress < BASE_4GB)) {
+ MemoryBottom = StartAddress + NumberOfBytes - MinimalNeededSize;
+ FreeMemoryBottom = MemoryBottom;
+ FreeMemoryTop = StartAddress + NumberOfBytes;
+ MemoryTop = FreeMemoryTop;
+
+ DEBUG ((DEBUG_INFO, "MemoryBottom :0x%llx\n", MemoryBottom));
+ DEBUG ((DEBUG_INFO, "FreeMemoryBottom :0x%llx\n", FreeMemoryBottom));
+ DEBUG ((DEBUG_INFO, "FreeMemoryTop :0x%llx\n", FreeMemoryTop));
+ DEBUG ((DEBUG_INFO, "MemoryTop :0x%llx\n", MemoryTop));
+ mHobList = HobConstructor ((VOID *)(UINTN)MemoryBottom, (VOID *)(UINTN)MemoryTop, (VOID *)(UINTN)FreeMemoryBottom, (VOID *)(UINTN)FreeMemoryTop);
+ IsHobConstructed = TRUE;
+ NewHobList = (UINTN)mHobList;
+ break;
+ }
+ }
+ }
+ }
+ } // end of memory node
+ else {
+ PropertyPtr = FdtGetProperty (Fdt, Node, "compatible", &TempLen);
+ if (PropertyPtr == NULL) {
+ continue;
+ }
+
+ TempStr = (CHAR8 *)(PropertyPtr->Data);
+ if (AsciiStrnCmp (TempStr, "pci-rb", AsciiStrLen ("pci-rb")) == 0) {
+ RootBridgeCount++;
+ }
+ }
+ }
+
+ NumRsv = FdtGetNumberOfReserveMapEntries (Fdt);
+ /* Look for an existing entry and add it to the efi mem map. */
+ for (index = 0; index < NumRsv; index++) {
+ if (FdtGetReserveMapEntry (Fdt, index, &Addr, &Size) != 0) {
+ continue;
+ }
+
+ BuildMemoryAllocationHob (Addr, Size, EfiReservedMemoryType);
+ }
+
+ index = RootBridgeCount - 1;
+ Depth = 0;
+ for (Node = FdtNextNode (Fdt, 0, &Depth); Node >= 0; Node = FdtNextNode (Fdt, Node, &Depth)) {
+ NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + Node + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
+ DEBUG ((DEBUG_INFO, "\n Node(%08x) %a Depth %x", Node, NodePtr->Name, Depth));
+
+ NodeType = CheckNodeType (NodePtr->Name, Depth);
+ DEBUG ((DEBUG_INFO, "NodeType :0x%x\n", NodeType));
+ switch (NodeType) {
+ case ReservedMemory:
+ DEBUG ((DEBUG_INFO, "ParseReservedMemory\n"));
+ ParseReservedMemory (Fdt, Node);
+ break;
+ case Memory:
+ DEBUG ((DEBUG_INFO, "ParseMemory\n"));
+ if (!CheckMemoryNodeIfInit (Node)) {
+ ParseMemory (Fdt, Node);
+ } else {
+ DEBUG ((DEBUG_INFO, "Memory has initialized\n"));
+ }
+
+ break;
+ case FrameBuffer:
+ DEBUG ((DEBUG_INFO, "ParseFrameBuffer\n"));
+ GmaStr = ParseFrameBuffer (Fdt, Node);
+ break;
+ case PciRootBridge:
+ DEBUG ((DEBUG_INFO, "ParsePciRootBridge, index :%x \n", index));
+ ParsePciRootBridge (Fdt, Node, RootBridgeCount, GmaStr, &index);
+ DEBUG ((DEBUG_INFO, "After ParsePciRootBridge, index :%x\n", index));
+ break;
+ case Options:
+ // FIXME: Need to ensure this node gets parsed first so that it gets
+ // correct options to feed into other init like PciEnumDone etc.
+ DEBUG ((DEBUG_INFO, "ParseOptions\n"));
+ ParseOptions (Fdt, Node, &PciEnumDone, &BootMode);
+ break;
+ default:
+ DEBUG ((DEBUG_INFO, "ParseNothing\n"));
+ break;
+ }
+ }
+
+ // Post processing: TODO: Need to look into it. Such cross dependency on DT nodes
+ // may not be good idea. Instead have this prop part of RB
+ mPciRootBridgeInfo->ResourceAssigned = (BOOLEAN)PciEnumDone;
+
+ //
+ // Assign PCI Segment number after all root bridge info ready
+ //
+ SegmentNumber = 0;
+ RbSegNumAlreadyAssigned = AllocateZeroPool (sizeof (UINT8) * RootBridgeCount);
+ NextPciBaseAddress = 0;
+ NumberOfRbSegNumAlreadyAssigned = 0;
+
+ //
+ // Always assign first root bridge segment number as 0
+ //
+ CurrentPciBaseAddress = mUplPciSegmentInfoHob->SegmentInfo[0].BaseAddress & ~0xFFFFFFF;
+ NextPciBaseAddress = CurrentPciBaseAddress;
+ mUplPciSegmentInfoHob->SegmentInfo[0].SegmentNumber = SegmentNumber;
+ mPciRootBridgeInfo->RootBridge[0].Segment = SegmentNumber;
+ RbSegNumAlreadyAssigned[0] = 1;
+ NumberOfRbSegNumAlreadyAssigned++;
+
+ while (NumberOfRbSegNumAlreadyAssigned < RootBridgeCount) {
+ for (index = 1; index < RootBridgeCount; index++) {
+ if (RbSegNumAlreadyAssigned[index] == 1) {
+ continue;
+ }
+
+ if (CurrentPciBaseAddress == (mUplPciSegmentInfoHob->SegmentInfo[index].BaseAddress & ~0xFFFFFFF)) {
+ mUplPciSegmentInfoHob->SegmentInfo[index].SegmentNumber = SegmentNumber;
+ mPciRootBridgeInfo->RootBridge[index].Segment = SegmentNumber;
+ RbSegNumAlreadyAssigned[index] = 1;
+ NumberOfRbSegNumAlreadyAssigned++;
+ } else if (CurrentPciBaseAddress == NextPciBaseAddress) {
+ NextPciBaseAddress = mUplPciSegmentInfoHob->SegmentInfo[index].BaseAddress & ~0xFFFFFFF;
+ }
+ }
+
+ SegmentNumber++;
+ CurrentPciBaseAddress = NextPciBaseAddress;
+ }
+
+ ((EFI_HOB_HANDOFF_INFO_TABLE *)(mHobList))->BootMode = BootMode;
+ DEBUG ((DEBUG_INFO, "\n"));
+
+ return NewHobList;
+}
+
+/**
+ It will Parse FDT -node based on information from bootloaders.
+ @param[in] FdtBase The starting memory address of FdtBase
+ @retval HobList The base address of Hoblist.
+
+**/
+UINTN
+EFIAPI
+FdtNodeParser (
+ IN VOID *FdtBase
+ )
+{
+ return ParseDtb (FdtBase);
+}
+
+/**
+ It will initialize HOBs for UPL.
+
+ @param[in] FdtBase Address of the Fdt data.
+
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to initialize HOBs.
+**/
+UINTN
+EFIAPI
+UplInitHob (
+ IN VOID *FdtBase
+ )
+{
+ UINTN NHobAddress;
+
+ NHobAddress = 0;
+ //
+ // Check parameter type(
+ //
+ if (FdtCheckHeader (FdtBase) == 0) {
+ DEBUG ((DEBUG_INFO, "%a() FDT blob\n", __func__));
+ NHobAddress = FdtNodeParser ((VOID *)FdtBase);
+ } else {
+ DEBUG ((DEBUG_INFO, "%a() HOb list\n", __func__));
+ mHobList = FdtBase;
+
+ return (UINTN)(mHobList);
+ }
+
+ return NHobAddress;
+}
diff --git a/UefiPayloadPkg/Library/HobParseLib/HobParseLib.c b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.c
new file mode 100644
index 0000000..98a5dcf
--- /dev/null
+++ b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.c
@@ -0,0 +1,280 @@
+/** @file
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Guid/MemoryAllocationHob.h>
+#include <Library/IoLib.h>
+#include <Library/CpuLib.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <Guid/AcpiBoardInfoGuid.h>
+#include <UniversalPayload/AcpiTable.h>
+#include <UniversalPayload/UniversalPayload.h>
+#include <UniversalPayload/ExtraData.h>
+
+#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
+ EFI_RESOURCE_ATTRIBUTE_TESTED | \
+ EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | \
+ EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | \
+ EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | \
+ EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED | \
+ EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \
+ EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \
+ EFI_RESOURCE_ATTRIBUTE_64_BIT_IO | \
+ EFI_RESOURCE_ATTRIBUTE_PERSISTENT )
+
+#define TESTED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
+ EFI_RESOURCE_ATTRIBUTE_TESTED )
+
+extern VOID *mHobList;
+
+/**
+ Add a new HOB to the HOB List.
+
+ @param HobType Type of the new HOB.
+ @param HobLength Length of the new HOB to allocate.
+
+ @return NULL if there is no space to create a hob.
+ @return The address point to the new created hob.
+
+**/
+VOID *
+EFIAPI
+CreateHob (
+ IN UINT16 HobType,
+ IN UINT16 HobLength
+ );
+
+/**
+ Build a Handoff Information Table HOB
+
+ This function initialize a HOB region from EfiMemoryBegin to
+ EfiMemoryTop. And EfiFreeMemoryBottom and EfiFreeMemoryTop should
+ be inside the HOB region.
+
+ @param[in] EfiMemoryBottom Total memory start address
+ @param[in] EfiMemoryTop Total memory end address.
+ @param[in] EfiFreeMemoryBottom Free memory start address
+ @param[in] EfiFreeMemoryTop Free memory end address.
+
+ @return The pointer to the handoff HOB table.
+
+**/
+EFI_HOB_HANDOFF_INFO_TABLE *
+EFIAPI
+HobConstructor (
+ IN VOID *EfiMemoryBottom,
+ IN VOID *EfiMemoryTop,
+ IN VOID *EfiFreeMemoryBottom,
+ IN VOID *EfiFreeMemoryTop
+ );
+
+/**
+ Build ACPI board info HOB using infomation from ACPI table
+
+ @param AcpiTableBase ACPI table start address in memory
+
+ @retval A pointer to ACPI board HOB ACPI_BOARD_INFO. Null if build HOB failure.
+**/
+ACPI_BOARD_INFO *
+BuildHobFromAcpi (
+ IN UINT64 AcpiTableBase
+ );
+
+/**
+ *
+ Add HOB into HOB list
+
+ @param[in] Hob The HOB to be added into the HOB list.
+**/
+VOID
+AddNewHob (
+ IN EFI_PEI_HOB_POINTERS *Hob
+ )
+{
+ EFI_PEI_HOB_POINTERS NewHob;
+
+ if (Hob->Raw == NULL) {
+ return;
+ }
+
+ NewHob.Header = CreateHob (Hob->Header->HobType, Hob->Header->HobLength);
+
+ if (NewHob.Header != NULL) {
+ CopyMem (NewHob.Header + 1, Hob->Header + 1, Hob->Header->HobLength - sizeof (EFI_HOB_GENERIC_HEADER));
+ }
+}
+
+/**
+ Found the Resource Descriptor HOB that contains a range (Base, Top)
+
+ @param[in] HobList Hob start address
+ @param[in] Base Memory start address
+ @param[in] Top Memory end address.
+
+ @retval The pointer to the Resource Descriptor HOB.
+**/
+EFI_HOB_RESOURCE_DESCRIPTOR *
+FindResourceDescriptorByRange (
+ IN VOID *HobList,
+ IN EFI_PHYSICAL_ADDRESS Base,
+ IN EFI_PHYSICAL_ADDRESS Top
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
+
+ for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
+ //
+ // Skip all HOBs except Resource Descriptor HOBs
+ //
+ if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ continue;
+ }
+
+ //
+ // Skip Resource Descriptor HOBs that do not describe tested system memory
+ //
+ ResourceHob = Hob.ResourceDescriptor;
+ if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
+ continue;
+ }
+
+ if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
+ continue;
+ }
+
+ //
+ // Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop
+ //
+ if (Base < ResourceHob->PhysicalStart) {
+ continue;
+ }
+
+ if (Top > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) {
+ continue;
+ }
+
+ return ResourceHob;
+ }
+
+ return NULL;
+}
+
+/**
+ Find the highest below 4G memory resource descriptor, except the input Resource Descriptor.
+
+ @param[in] HobList Hob start address
+ @param[in] MinimalNeededSize Minimal needed size.
+ @param[in] ExceptResourceHob Ignore this Resource Descriptor.
+
+ @retval The pointer to the Resource Descriptor HOB.
+**/
+EFI_HOB_RESOURCE_DESCRIPTOR *
+FindAnotherHighestBelow4GResourceDescriptor (
+ IN VOID *HobList,
+ IN UINTN MinimalNeededSize,
+ IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
+ EFI_HOB_RESOURCE_DESCRIPTOR *ReturnResourceHob;
+
+ ReturnResourceHob = NULL;
+
+ for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
+ //
+ // Skip all HOBs except Resource Descriptor HOBs
+ //
+ if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ continue;
+ }
+
+ //
+ // Skip Resource Descriptor HOBs that do not describe tested system memory
+ //
+ ResourceHob = Hob.ResourceDescriptor;
+ if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
+ continue;
+ }
+
+ if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
+ continue;
+ }
+
+ //
+ // Skip if the Resource Descriptor HOB equals to ExceptResourceHob
+ //
+ if (ResourceHob == ExceptResourceHob) {
+ continue;
+ }
+
+ //
+ // Skip Resource Descriptor HOBs that are beyond 4G
+ //
+ if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > BASE_4GB) {
+ continue;
+ }
+
+ //
+ // Skip Resource Descriptor HOBs that are too small
+ //
+ if (ResourceHob->ResourceLength < MinimalNeededSize) {
+ continue;
+ }
+
+ //
+ // Return the topest Resource Descriptor
+ //
+ if (ReturnResourceHob == NULL) {
+ ReturnResourceHob = ResourceHob;
+ } else {
+ if (ReturnResourceHob->PhysicalStart < ResourceHob->PhysicalStart) {
+ ReturnResourceHob = ResourceHob;
+ }
+ }
+ }
+
+ return ReturnResourceHob;
+}
+
+/**
+ Check the HOB and decide if it is need inside Payload
+
+ Payload maintainer may make decision which HOB is need or needn't
+ Then add the check logic in the function.
+
+ @param[in] Hob The HOB to check
+
+ @retval TRUE If HOB is need inside Payload
+ @retval FALSE If HOB is needn't inside Payload
+**/
+BOOLEAN
+IsHobNeed (
+ EFI_PEI_HOB_POINTERS Hob
+ )
+{
+ if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) {
+ return FALSE;
+ }
+
+ if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
+ if (CompareGuid (&Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
+ return FALSE;
+ }
+ }
+
+ // Arrive here mean the HOB is need
+ return TRUE;
+}
diff --git a/UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf
new file mode 100644
index 0000000..fb89608
--- /dev/null
+++ b/UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf
@@ -0,0 +1,40 @@
+## @file
+# UPL Hob Parse Library.
+#
+# Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = HobParseLib
+ FILE_GUID = EFB05FE7-604B-40DA-9A59-E2F998528754
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = HobParseLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ HobParseLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiPayloadPkg/UefiPayloadPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ IoLib
+ DebugLib
+ PcdLib
+ HobLib
+
+[Pcd.IA32,Pcd.X64,Pcd.RISCV64]
+ gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+ gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable
diff --git a/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c b/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c
index 51c2e28..dea6476 100644
--- a/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c
+++ b/UefiPayloadPkg/Library/PayloadEntryHobLib/Hob.c
@@ -31,7 +31,6 @@ GetHobList (
VOID
)
{
- ASSERT (mHobList != NULL);
return mHobList;
}
@@ -109,6 +108,7 @@ CreateHob (
VOID *Hob;
HandOffHob = GetHobList ();
+ ASSERT (HandOffHob != NULL);
//
// Check Length to avoid data overflow.
@@ -175,6 +175,7 @@ BuildResourceDescriptorHob (
Hob->ResourceAttribute = ResourceAttribute;
Hob->PhysicalStart = PhysicalStart;
Hob->ResourceLength = NumberOfBytes;
+ ZeroMem (&(Hob->Owner), sizeof (EFI_GUID));
}
/**
@@ -305,6 +306,7 @@ GetFirstGuidHob (
VOID *HobList;
HobList = GetHobList ();
+ ASSERT (HobList != NULL);
return GetNextGuidHob (Guid, HobList);
}
@@ -651,6 +653,7 @@ UpdateStackHob (
EFI_PEI_HOB_POINTERS Hob;
Hob.Raw = GetHobList ();
+ ASSERT (Hob.Raw != NULL);
while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
//
@@ -709,6 +712,7 @@ BuildMemoryAllocationHob (
}
ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
+
Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
Hob->AllocDescriptor.MemoryLength = Length;
Hob->AllocDescriptor.MemoryType = MemoryType;
diff --git a/UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf b/UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf
index cbb4f02..496a5c8 100644
--- a/UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf
+++ b/UefiPayloadPkg/Library/PayloadEntryHobLib/HobLib.inf
@@ -26,7 +26,6 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
- UefiPayloadPkg/UefiPayloadPkg.dec
[LibraryClasses]
BaseLib
@@ -36,4 +35,3 @@
[Guids]
gEfiHobMemoryAllocModuleGuid
gEfiHobMemoryAllocStackGuid
-
diff --git a/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c b/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c
index 6953cfd..369e015 100644
--- a/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c
+++ b/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c
@@ -3,6 +3,8 @@
segment base address is retrieved from AcpiBoardInfo HOB.
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2024, Rivos Inc. All rights reserved.<BR>
+
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -13,22 +15,187 @@
#include <Library/HobLib.h>
#include <Library/PciSegmentInfoLib.h>
#include <Library/DebugLib.h>
+#include <UniversalPayload/PciRootBridges.h>
+#include <Library/PciLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Guid/PciSegmentInfoGuid.h>
+
+static PCI_SEGMENT_INFO *mPciSegments;
+static UINTN mCount;
+
+/**
+ Find segment info from all root bridges
+
+ @param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob
+ @param[in] UplSegmentInfo Pointer of Universal UPL Segment Info
+
+ @param[out] NumberOfRootBridges Number of root bridges detected
+
+**/
+VOID
+RetrieveMultiSegmentInfoFromHob (
+ IN UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo,
+ IN UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo,
+ OUT UINTN *NumberOfRootBridges
+ )
+{
+ UINTN Size;
+ UINT8 Index;
+
+ if (PciRootBridgeInfo == NULL) {
+ mPciSegments = NULL;
+ return;
+ }
+
+ *NumberOfRootBridges = PciRootBridgeInfo->Count;
+
+ Size = PciRootBridgeInfo->Count * sizeof (PCI_SEGMENT_INFO);
+ mPciSegments = (PCI_SEGMENT_INFO *)AllocatePool (Size);
+ ASSERT (mPciSegments != NULL);
+ ZeroMem (mPciSegments, PciRootBridgeInfo->Count * sizeof (PCI_SEGMENT_INFO));
-STATIC PCI_SEGMENT_INFO mPciSegment0 = {
- 0, // Segment number
- 0, // To be fixed later
- 0, // Start bus number
- 255 // End bus number
-};
+ //
+ // Create all root bridges with PciRootBridgeInfoHob
+ //
+ for (Index = 0; Index < PciRootBridgeInfo->Count; Index++) {
+ if (UplSegmentInfo->SegmentInfo[Index].SegmentNumber == (UINT16)(PciRootBridgeInfo->RootBridge[Index].Segment)) {
+ mPciSegments[Index].BaseAddress = UplSegmentInfo->SegmentInfo[Index].BaseAddress;
+ }
+
+ mPciSegments[Index].SegmentNumber = (UINT16)(PciRootBridgeInfo->RootBridge[Index].Segment);
+ mPciSegments[Index].StartBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[Index].Bus.Base;
+ mPciSegments[Index].EndBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[Index].Bus.Limit;
+ }
+
+ return;
+}
/**
- Return an array of PCI_SEGMENT_INFO holding the segment information.
+ Find segment info from all root bridges for legacy systems
- Note: The returned array/buffer is owned by callee.
+ @param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob
+ @param[out] NumberOfRootBridges Number of root bridges detected
- @param Count Return the count of segments.
+**/
+VOID
+RetrieveSegmentInfoFromHob (
+ OUT UINTN *NumberOfRootBridges
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ ACPI_BOARD_INFO *AcpiBoardInfo;
+
+ *NumberOfRootBridges = 1;
+ // old model relies on gUefiAcpiBoardInfoGuid and hardcoded values for single segment only.
+ // This is only for backward compatibility, new platforms should adopt new model even in single segment cases.
+ //
+ mPciSegments = (PCI_SEGMENT_INFO *)AllocatePool (sizeof (PCI_SEGMENT_INFO));
+ ASSERT (mPciSegments != NULL);
+ GuidHob = GetFirstGuidHob (&gUefiAcpiBoardInfoGuid);
+ ASSERT (GuidHob != NULL);
+ if (GuidHob != NULL) {
+ AcpiBoardInfo = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob);
+ mPciSegments->SegmentNumber = 0;
+ mPciSegments->BaseAddress = AcpiBoardInfo->PcieBaseAddress;
+ mPciSegments->StartBusNumber = 0;
+ mPciSegments->EndBusNumber = 0xFF;
+ }
+}
+
+/**
+ Return info for all root bridges
- @retval A callee owned array holding the segment information.
+ @return All the root bridge info instances in an array.
+**/
+UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *
+Get_RBInfo (
+ VOID
+ )
+{
+ UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader;
+
+ //
+ // Find Universal Payload PCI Root Bridge Info hob
+ //
+ GuidHob = GetFirstGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid);
+ if ((GuidHob == NULL) || (sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob))) {
+ return NULL;
+ }
+
+ GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob);
+ if (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob)) {
+ return NULL;
+ }
+
+ if ((GenericHeader->Revision != UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) || (GenericHeader->Length < sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES))) {
+ return NULL;
+ }
+
+ //
+ // UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES structure is used when Revision equals to UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION
+ //
+ PciRootBridgeInfo = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)GET_GUID_HOB_DATA (GuidHob);
+ if (PciRootBridgeInfo->Count <= (GET_GUID_HOB_DATA_SIZE (GuidHob) - sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES)) / sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE)) {
+ return PciRootBridgeInfo;
+ }
+
+ return NULL;
+}
+
+/**
+ Return info for all root bridge segments
+
+ @return All the segment info instances in an array.
+**/
+UPL_PCI_SEGMENT_INFO_HOB *
+Get_UPLSegInfo (
+ VOID
+ )
+{
+ UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader;
+
+ //
+ // Find Universal Payload Segment Info hob
+ //
+ GuidHob = GetFirstGuidHob (&gUplPciSegmentInfoHobGuid);
+ if ((GuidHob == NULL) || (sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob))) {
+ return NULL;
+ }
+
+ GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob);
+ if (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob)) {
+ return NULL;
+ }
+
+ if ((GenericHeader->Revision != UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) || (GenericHeader->Length < sizeof (UPL_PCI_SEGMENT_INFO_HOB))) {
+ return NULL;
+ }
+
+ //
+ // UPL_PCI_SEGMENT_INFO_HOB structure is used when Revision equals to UPL_PCI_SEGMENT_INFO_HOB_REVISION
+ //
+ UplSegmentInfo = (UPL_PCI_SEGMENT_INFO_HOB *)GET_GUID_HOB_DATA (GuidHob);
+ if (UplSegmentInfo->Count <= (GET_GUID_HOB_DATA_SIZE (GuidHob) - sizeof (UPL_PCI_SEGMENT_INFO_HOB)) / sizeof (UPL_SEGMENT_INFO)) {
+ return UplSegmentInfo;
+ }
+
+ return NULL;
+}
+
+/**
+ Return all the root bridge instances in an array.
+
+ @param Count Return the count of root bridge instances.
+
+ @return All the root bridge instances in an array.
+ The array should be passed into PciHostBridgeFreeRootBridges()
+ when it's not used.
**/
PCI_SEGMENT_INFO *
EFIAPI
@@ -36,25 +203,27 @@ GetPciSegmentInfo (
UINTN *Count
)
{
- EFI_HOB_GUID_TYPE *GuidHob;
- ACPI_BOARD_INFO *AcpiBoardInfo;
+ UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo;
+ UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo;
- ASSERT (Count != NULL);
- if (Count == NULL) {
- return NULL;
+ if (mPciSegments != NULL) {
+ *Count = mCount;
+ return mPciSegments;
}
- if (mPciSegment0.BaseAddress == 0) {
- //
- // Find the acpi board information guid hob
- //
- GuidHob = GetFirstGuidHob (&gUefiAcpiBoardInfoGuid);
- ASSERT (GuidHob != NULL);
+ UplSegmentInfo = Get_UPLSegInfo ();
+
+ if (UplSegmentInfo == NULL) {
+ RetrieveSegmentInfoFromHob (Count);
+ } else {
+ PciRootBridgeInfo = Get_RBInfo ();
+ if (PciRootBridgeInfo == NULL) {
+ return 0;
+ }
- AcpiBoardInfo = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob);
- mPciSegment0.BaseAddress = AcpiBoardInfo->PcieBaseAddress;
+ RetrieveMultiSegmentInfoFromHob (PciRootBridgeInfo, UplSegmentInfo, Count);
}
- *Count = 1;
- return &mPciSegment0;
+ mCount = *Count;
+ return mPciSegments;
}
diff --git a/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf b/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf
index b6140ab..2ec700e 100644
--- a/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf
+++ b/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf
@@ -29,6 +29,7 @@
[Packages]
MdePkg/MdePkg.dec
UefiPayloadPkg/UefiPayloadPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
PcdLib
@@ -37,3 +38,7 @@
[Guids]
gUefiAcpiBoardInfoGuid
+ gUplPciSegmentInfoHobGuid
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
diff --git a/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c b/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c
index 60a17b8..efaab32 100644
--- a/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c
+++ b/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c
@@ -51,6 +51,10 @@ PlatformHookSerialPortInitialize (
UINT8 *GuidHob;
UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader;
+ if (GetHobList () == NULL) {
+ return RETURN_SUCCESS;
+ }
+
GuidHob = GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid);
if (GuidHob == NULL) {
return EFI_NOT_FOUND;
diff --git a/UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c b/UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c
index 1f28820..f252855 100644
--- a/UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c
+++ b/UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -40,6 +40,12 @@ ResetSystemLibConstructor (
AcpiBoardInfoPtr = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob);
CopyMem (&mAcpiBoardInfo, AcpiBoardInfoPtr, sizeof (ACPI_BOARD_INFO));
+ ASSERT (mAcpiBoardInfo.ResetRegAddress != 0);
+ ASSERT (mAcpiBoardInfo.ResetValue != 0);
+ ASSERT (mAcpiBoardInfo.PmGpeEnBase != 0);
+ ASSERT (mAcpiBoardInfo.PmEvtBase != 0);
+ ASSERT (mAcpiBoardInfo.PmCtrlRegBase != 0);
+
return EFI_SUCCESS;
}
diff --git a/UefiPayloadPkg/PayloadLoaderPeim/FitLib.h b/UefiPayloadPkg/PayloadLoaderPeim/FitLib.h
index 6a93b41..05b790b 100644
--- a/UefiPayloadPkg/PayloadLoaderPeim/FitLib.h
+++ b/UefiPayloadPkg/PayloadLoaderPeim/FitLib.h
@@ -12,8 +12,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/FdtLib.h>
typedef struct {
- UINT64 RelocateType;
UINT64 Offset;
+ UINT64 RelocateType;
} FIT_RELOCATE_ITEM;
typedef struct {
diff --git a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c
index de33d49..72586db 100644
--- a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c
+++ b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c
@@ -6,18 +6,34 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <PiPei.h>
#include <UniversalPayload/UniversalPayload.h>
+#include <UniversalPayload/DeviceTree.h>
#include <Guid/UniversalPayloadBase.h>
#include <UniversalPayload/ExtraData.h>
-
+#include <UniversalPayload/DeviceTree.h>
#include <Ppi/LoadFile.h>
-
+#include <Library/PciHostBridgeLib.h>
+#include <Protocol/DevicePath.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
-#include <Library/PeiServicesLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
-
+#include <Library/FdtLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PeiServicesLib.h>
#include "FitLib.h"
+#define STACK_SIZE 0x20000
+
+CONST EFI_PEI_PPI_DESCRIPTOR gReadyToPayloadSignalPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gUplReadyToPayloadPpiGuid,
+ NULL
+};
+
+EFI_PEI_PPI_DESCRIPTOR mEndOfPeiSignalPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ NULL
+};
/**
The wrapper function of PeiLoadImageLoadImage().
@@ -50,6 +66,15 @@ PeiLoadFileLoadPayload (
UINTN Delta;
UINTN Index;
+ #if (FixedPcdGetBool (PcdHandOffFdtEnable))
+ VOID *BaseOfStack;
+ VOID *TopOfStack;
+ UNIVERSAL_PAYLOAD_DEVICE_TREE *Fdt;
+ VOID *Hob;
+
+ Fdt = NULL;
+ #endif
+
Instance = 0;
do {
Status = PeiServicesFfsFindSectionData3 (EFI_SECTION_RAW, Instance++, FileHandle, &Binary, AuthenticationState);
@@ -66,13 +91,15 @@ PeiLoadFileLoadPayload (
return Status;
}
- DEBUG ((
- DEBUG_INFO,
- "Before Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoint: 0x%08x\n",
- Context.PayloadBaseAddress,
- Context.PayloadSize,
- Context.PayloadEntryPoint
- ));
+ DEBUG (
+ (
+ DEBUG_INFO,
+ "Before Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoint: 0x%08x\n",
+ Context.PayloadBaseAddress,
+ Context.PayloadSize,
+ Context.PayloadEntryPoint
+ )
+ );
Context.PayloadBaseAddress = (EFI_PHYSICAL_ADDRESS)AllocatePages (EFI_SIZE_TO_PAGES (Context.PayloadSize));
RelocateTable = (FIT_RELOCATE_ITEM *)(UINTN)(Context.PayloadBaseAddress + Context.RelocateTableOffset);
@@ -96,13 +123,15 @@ PeiLoadFileLoadPayload (
}
}
- DEBUG ((
- DEBUG_INFO,
- "After Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoint: 0x%08x\n",
- Context.PayloadBaseAddress,
- Context.PayloadSize,
- Context.PayloadEntryPoint
- ));
+ DEBUG (
+ (
+ DEBUG_INFO,
+ "After Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoint: 0x%08x\n",
+ Context.PayloadBaseAddress,
+ Context.PayloadSize,
+ Context.PayloadEntryPoint
+ )
+ );
Length = sizeof (UNIVERSAL_PAYLOAD_BASE);
PayloadBase = BuildGuidHob (
@@ -115,6 +144,42 @@ PeiLoadFileLoadPayload (
*ImageSizeArg = Context.PayloadSize;
*EntryPoint = Context.PayloadEntryPoint;
+ Status = PeiServicesInstallPpi (&mEndOfPeiSignalPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PeiServicesInstallPpi (&gReadyToPayloadSignalPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ #if (FixedPcdGetBool (PcdHandOffFdtEnable))
+ Hob = GetFirstGuidHob (&gUniversalPayloadDeviceTreeGuid);
+ if (Hob != NULL) {
+ Fdt = (UNIVERSAL_PAYLOAD_DEVICE_TREE *)GET_GUID_HOB_DATA (Hob);
+ }
+
+ //
+ // Allocate 128KB for the Stack
+ //
+ BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
+ ASSERT (BaseOfStack != NULL);
+
+ //
+ // Compute the top of the stack we were allocated. Pre-allocate a UINTN
+ // for safety.
+ //
+ TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
+ TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
+
+ //
+ // Transfer the control to the entry point of UniveralPayloadEntry.
+ //
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)Context.PayloadEntryPoint,
+ (VOID *)(Fdt->DeviceTreeAddress),
+ NULL,
+ TopOfStack
+ );
+ #endif
+
return EFI_SUCCESS;
}
@@ -128,6 +193,143 @@ EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {
&mPeiLoadFilePpi
};
+#if (FixedPcdGetBool (PcdHandOffFdtEnable))
+
+/**
+ Discover Hobs data and report data into a FDT.
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+ @retval EFI_SUCCESS Hobs data is discovered.
+ @return Others No Hobs data is discovered.
+**/
+EFI_STATUS
+EFIAPI
+FdtPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+EFI_PEI_NOTIFY_DESCRIPTOR mReadyToPayloadNotifyList[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gUplReadyToPayloadPpiGuid,
+ FdtPpiNotifyCallback
+ }
+};
+#endif
+
+/**
+ Print FDT data.
+ @param[in] FdtBase Address of the Fdt data.
+**/
+VOID
+PrintFdt (
+ IN VOID *FdtBase
+ )
+{
+ UINT8 *Fdt;
+ UINT32 i;
+
+ Fdt = NULL;
+ i = 0;
+
+ DEBUG ((DEBUG_ERROR, "FDT DTB data:"));
+ for (Fdt = FdtBase, i = 0; i < Fdt32ToCpu (((FDT_HEADER *)FdtBase)->TotalSize); i++, Fdt++) {
+ if (i % 16 == 0) {
+ DEBUG ((DEBUG_ERROR, "\n"));
+ }
+
+ DEBUG ((DEBUG_ERROR, "%02x ", *Fdt));
+ }
+
+ DEBUG ((DEBUG_ERROR, "\n"));
+}
+
+/**
+ It will build FDT for UPL consumed.
+ @param[in] FdtBase Address of the Fdt data.
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to build required FDT.
+**/
+EFI_STATUS
+BuildFdtForUPL (
+ IN VOID *FdtBase
+ );
+
+#if (FixedPcdGetBool (PcdHandOffFdtEnable))
+
+/**
+ Discover Hobs data and report data into a FDT.
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+ @retval EFI_SUCCESS Hobs data is discovered.
+ @return Others No Hobs data is discovered.
+**/
+EFI_STATUS
+EFIAPI
+FdtPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ UNIVERSAL_PAYLOAD_DEVICE_TREE *Fdt;
+ UINT32 FdtSize;
+ UINTN FdtPages;
+ VOID *FdtBase;
+ UINT32 Data32;
+
+ Fdt = NULL;
+ FdtSize = PcdGet8 (PcdFDTPageSize) * EFI_PAGE_SIZE;
+ FdtPages = EFI_SIZE_TO_PAGES (FdtSize);
+ FdtBase = AllocatePages (FdtPages);
+ if (FdtBase == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: AllocatePages failed\n", __func__));
+ return EFI_NOT_FOUND;
+ }
+
+ Status = FdtCreateEmptyTree (FdtBase, (UINT32)FdtSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: cannot create FDT\n", __func__));
+ }
+
+ // Set cell property of root node
+ Data32 = CpuToFdt32 (2);
+ Status = FdtSetProperty (FdtBase, 0, "#address-cells", &Data32, sizeof (UINT32));
+ Status = FdtSetProperty (FdtBase, 0, "#size-cells", &Data32, sizeof (UINT32));
+
+ Status = BuildFdtForUPL (FdtBase);
+ ASSERT_EFI_ERROR (Status);
+
+ PrintFdt (FdtBase);
+
+ Fdt = BuildGuidHob (&gUniversalPayloadDeviceTreeGuid, sizeof (UNIVERSAL_PAYLOAD_DEVICE_TREE));
+ if (Fdt == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Build FDT Hob failed\n", __func__));
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: fdt at 0x%x (size %d)\n",
+ __func__,
+ FdtBase,
+ Fdt32ToCpu (((FDT_HEADER *)FdtBase)->TotalSize)
+ ));
+
+ Fdt->Header.Revision = UNIVERSAL_PAYLOAD_DEVICE_TREE_REVISION;
+ Fdt->Header.Length = sizeof (UNIVERSAL_PAYLOAD_DEVICE_TREE);
+ Fdt->DeviceTreeAddress = (UINT64)FdtBase;
+
+ return Status;
+}
+
+#endif
+
/**
Install Pei Load File PPI.
@param FileHandle Handle of the file being invoked.
@@ -146,5 +348,13 @@ InitializeFitPayloadLoaderPeim (
Status = PeiServicesInstallPpi (&gPpiLoadFilePpiList);
+ #if (FixedPcdGetBool (PcdHandOffFdtEnable))
+
+ //
+ // Build FDT in end of PEI notify callback.
+ //
+ Status = PeiServicesNotifyPpi (&mReadyToPayloadNotifyList[0]);
+ ASSERT_EFI_ERROR (Status);
+ #endif
return Status;
}
diff --git a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf
index cd0cb18..b891706 100644
--- a/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf
+++ b/UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf
@@ -35,7 +35,6 @@
[LibraryClasses]
PcdLib
- MemoryAllocationLib
BaseMemoryLib
PeiServicesLib
HobLib
@@ -43,17 +42,27 @@
PeimEntryPoint
DebugLib
FdtLib
+##for testing, remove this for HandOffFdtEnable == FALSE scenario: BuildFdtLib
+##Hook this lib to FitPayloadLoaderPeim.inf in platform DSC when HandOffFdtEnable == TRUE.
[Ppis]
gEfiPeiLoadFilePpiGuid ## PRODUCES
+ gUplReadyToPayloadPpiGuid ## PRODUCES
+ gEfiEndOfPeiSignalPpiGuid ## CONSUMES
[Pcd]
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister
+ gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable
+ gUefiPayloadPkgTokenSpaceGuid.PcdFDTPageSize
[Guids]
- gUniversalPayloadExtraDataGuid ## PRODUCES
gUniversalPayloadBaseGuid ## PRODUCES
+ gUniversalPayloadDeviceTreeGuid ## CONSUMES
+ gEfiGraphicsInfoHobGuid ## CONSUMES
+ gUniversalPayloadPciRootBridgeInfoGuid ## CONSUMES
+ gUniversalPayloadAcpiTableGuid ## CONSUMES
+ gUniversalPayloadSerialPortParentDeviceInfoGuid
[Depex]
TRUE
diff --git a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c b/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c
index 9f9d3c1..cdb7c1a 100644
--- a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c
+++ b/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.c
@@ -17,9 +17,49 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/PeiServicesLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
-
+#include <Guid/UniversalPayloadBase.h>
#include "ElfLib.h"
+CONST EFI_PEI_PPI_DESCRIPTOR gReadyToPayloadSignalPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gUplReadyToPayloadPpiGuid,
+ NULL
+};
+
+/**
+ Notify ReadyToPayLoad signal.
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+ @retval EFI_SUCCESS Hobs data is discovered.
+ @return Others No Hobs data is discovered.
+**/
+EFI_STATUS
+EFIAPI
+EndOfPeiPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Ready to Payload phase signal
+ //
+ Status = PeiServicesInstallPpi (&gReadyToPayloadSignalPpi);
+
+ return Status;
+}
+
+EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiNotifyList[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiEndOfPeiSignalPpiGuid,
+ EndOfPeiPpiNotifyCallback
+ }
+};
+
/**
The wrapper function of PeiLoadImageLoadImage().
@@ -47,6 +87,7 @@ PeiLoadFileLoadPayload (
EFI_STATUS Status;
VOID *Elf;
UNIVERSAL_PAYLOAD_EXTRA_DATA *ExtraData;
+ UNIVERSAL_PAYLOAD_BASE *PayloadBase;
ELF_IMAGE_CONTEXT Context;
UINT32 Index;
UINT16 ExtraDataIndex;
@@ -73,13 +114,22 @@ PeiLoadFileLoadPayload (
Status = ParseElfImage (Elf, &Context);
} while (EFI_ERROR (Status));
- DEBUG ((
- DEBUG_INFO,
- "Payload File Size: 0x%08X, Mem Size: 0x%08x, Reload: %d\n",
- Context.FileSize,
- Context.ImageSize,
- Context.ReloadRequired
- ));
+ Length = sizeof (UNIVERSAL_PAYLOAD_BASE);
+ PayloadBase = BuildGuidHob (
+ &gUniversalPayloadBaseGuid,
+ Length
+ );
+ PayloadBase->Entry = (EFI_PHYSICAL_ADDRESS)Context.FileBase;
+
+ DEBUG (
+ (
+ DEBUG_INFO,
+ "Payload File Size: 0x%08X, Mem Size: 0x%08x, Reload: %d\n",
+ Context.FileSize,
+ Context.ImageSize,
+ Context.ReloadRequired
+ )
+ );
//
// Get UNIVERSAL_PAYLOAD_INFO_HEADER and number of additional PLD sections.
@@ -153,6 +203,11 @@ PeiLoadFileLoadPayload (
*ImageSizeArg = Context.ImageSize;
}
+ DEBUG ((DEBUG_INFO, "LoadElfImage :%r, EntryPoint :%x\n", Status, (UINTN)Context.EntryPoint));
+
+ Status = PeiServicesNotifyPpi (&mEndOfPeiNotifyList[0]);
+ ASSERT_EFI_ERROR (Status);
+
return Status;
}
@@ -173,7 +228,7 @@ EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {
@param FileHandle Handle of the file being invoked.
@param PeiServices Describes the list of possible PEI Services.
- @retval EFI_SUCESS The entry point executes successfully.
+ @retval EFI_SUCCESS The entry point executes successfully.
@retval Others Some error occurs during the execution of this function.
**/
diff --git a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.inf b/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.inf
index 06e83db..8db026e 100644
--- a/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.inf
+++ b/UefiPayloadPkg/PayloadLoaderPeim/PayloadLoaderPeim.inf
@@ -52,6 +52,8 @@
[Ppis]
gEfiPeiLoadFilePpiGuid ## PRODUCES
+ gEfiEndOfPeiSignalPpiGuid ## CONSUMES
+ gUplReadyToPayloadPpiGuid ## PRODUCES
[Pcd]
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister
@@ -59,6 +61,16 @@
[Guids]
gUniversalPayloadExtraDataGuid ## PRODUCES
+ gUniversalPayloadBaseGuid ## PRODUCES
[Depex]
TRUE
+
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /wd4244
+ GCC:*_*_IA32_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_X64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_ARM_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_AARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_RISCV64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
+ GCC:*_*_LOONGARCH64_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
diff --git a/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c b/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c
index 7fc5893..8a076e1 100644
--- a/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c
+++ b/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c
@@ -25,7 +25,7 @@ LIST_ENTRY mSmmSwDispatch2Queue = INITIALIZE_LIST_HEAD_VARIABLE (mSmm
/**
Find SmmSwDispatch2Context by SwSmiInputValue.
- @param[in] SwSmiInputValue The value to indentify the SmmSwDispatch2 context
+ @param[in] SwSmiInputValue The value to identify the SmmSwDispatch2 context
@return Pointer to EFI_SMM_SW_DISPATCH2_CONTEXT context
**/
@@ -51,7 +51,7 @@ FindContextBySwSmiInputValue (
/**
Find SmmSwDispatch2Context by DispatchHandle.
- @param DispatchHandle The handle to indentify the SmmSwDispatch2 context
+ @param DispatchHandle The handle to identify the SmmSwDispatch2 context
@return Pointer to EFI_SMM_SW_DISPATCH2_CONTEXT context
**/
@@ -178,7 +178,7 @@ End:
/**
Check the SwSmiInputValue is already used
-@param[in] SwSmiInputValue To indentify the SmmSwDispatch2 context
+@param[in] SwSmiInputValue To identify the SmmSwDispatch2 context
@retval EFI_SUCCESS SwSmiInputValue could be used.
@retval EFI_INVALID_PARAMETER SwSmiInputValue is already be used.
diff --git a/UefiPayloadPkg/Readme.md b/UefiPayloadPkg/Readme.md
index 4149eab..0ddc159 100644
--- a/UefiPayloadPkg/Readme.md
+++ b/UefiPayloadPkg/Readme.md
@@ -2,10 +2,10 @@
Provide UEFI Universal Payload for different bootloader to generate EFI environment
# Spec
-UniversalPayload URL: https://universalscalablefirmware.github.io/documentation/2_universal_payload.html
-UniversalPayload URL: https://universalpayload.github.io/spec/
-ELF Format URL: https://refspecs.linuxfoundation.org/elf/elf.pdf
-FIT Format URL: https://universalpayload.github.io/spec/chapter2-payload-image-format.html
+- UniversalPayload URL: https://universalscalablefirmware.github.io/documentation/2_universal_payload.html
+- UniversalPayload URL: https://universalpayload.github.io/spec/
+- ELF Format URL: https://refspecs.linuxfoundation.org/elf/elf.pdf
+- FIT Format URL: https://universalpayload.github.io/spec/chapter2-payload-image-format.html
# Uefi UniversalPayload Format
| Binary Format | HandOffPayload - HOB |
@@ -48,29 +48,19 @@ FIT Format URL: https://universalpayload.github.io/spec/chapter2-payload-image-f
+ +-----------------------+
```
-# Environment
+# Build Environment
- ELF
```
- Download and install https://github.com/llvm/llvm-project/releases/tag/llvmorg-10.0.1
+ Install GCC compiler on linux and MSVC compiler on windows
+ Install CLANG compiler https://github.com/llvm/llvm-project/releases/tag/llvmorg-10.0.1 on windows and linux
```
- FIT
- - Windows
- ```
- Download and install swig by https://swig.org/ and also set install path into environment variable
- ```
- ```powershell
- Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
- choco install dtc-msys2
- pip3 install pefile
- pip3 install pylibfdt
- ```
- - Ubuntu
- ```bash
- sudo apt install -y u-boot-tools
- pip3 install pefile
- pip3 install swig
- pip3 install pylibfdt
- ```
+ ```
+ Install GCC compiler on linux and MSVC compiler on windows
+ pip3 install pefile
+ pip3 install pylibfdt
+ ```
+
# How to build UEFI UniversalPayload
- Windows
- edksetup Rebuild
@@ -84,6 +74,24 @@ FIT Format URL: https://universalpayload.github.io/spec/chapter2-payload-image-f
- UniversalPayload.fit
- python UefiPayloadPkg/UniversalPayloadBuild.py -t <TOOL_CHAIN_TAG> --Fit
+
+# How to dump payload binary data
+ - UniversalPayload.elf
+ - Install elf dump tools https://github.com/llvm/llvm-project/releases/tag/llvmorg-10.0.1
+ - llvm-objdump -h Build/UefiPayloadPkgX64/UniversalPayload.elf
+
+ - UniversalPayload.fit
+ - Install fdtdump tool
+ - Windows
+ ```powershell
+ Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
+ choco install dtc-msys2
+ ```
+ - Linux
+ ```bash
+ sudo apt install -y u-boot-tools
+ ```
+
- fdtdump Build/UefiPayloadPkgX64/UniversalPayload.fit
# Edk2boot + UefiUniversalPayload
diff --git a/UefiPayloadPkg/UefiPayloadEntry/AcpiTable.c b/UefiPayloadPkg/UefiPayloadEntry/AcpiTable.c
index 7487289..a7ee00f 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/AcpiTable.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/AcpiTable.c
@@ -13,7 +13,7 @@
Find the board related info from ACPI table
@param AcpiTableBase ACPI table start address in memory
- @param AcpiBoardInfo Pointer to the acpi board info strucutre
+ @param AcpiBoardInfo Pointer to the acpi board info structure
@retval RETURN_SUCCESS Successfully find out all the required information.
@retval RETURN_NOT_FOUND Failed to find the required info.
@@ -125,15 +125,6 @@ Done:
DEBUG ((DEBUG_INFO, "PcieBaseAddr 0x%lx\n", AcpiBoardInfo->PcieBaseAddress));
DEBUG ((DEBUG_INFO, "PcieBaseSize 0x%lx\n", AcpiBoardInfo->PcieBaseSize));
- //
- // Verify values for proper operation
- //
- ASSERT (Fadt->Pm1aCntBlk != 0);
- ASSERT (Fadt->PmTmrBlk != 0);
- ASSERT (Fadt->ResetReg.Address != 0);
- ASSERT (Fadt->Pm1aEvtBlk != 0);
- ASSERT (Fadt->Gpe0Blk != 0);
-
return RETURN_SUCCESS;
}
diff --git a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c
index eb0b325..7af1276 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.c
@@ -6,6 +6,9 @@
#include "UefiPayloadEntry.h"
#include <Library/FdtLib.h>
#include <Guid/UniversalPayloadBase.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Library/FdtParserLib.h>
+#include <Library/HobParserLib.h>
#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
@@ -23,6 +26,15 @@
EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
EFI_RESOURCE_ATTRIBUTE_TESTED )
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
+ { EfiACPIReclaimMemory, FixedPcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory) },
+ { EfiACPIMemoryNVS, FixedPcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS) },
+ { EfiReservedMemoryType, FixedPcdGet32 (PcdMemoryTypeEfiReservedMemoryType) },
+ { EfiRuntimeServicesData, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesData) },
+ { EfiRuntimeServicesCode, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode) },
+ { EfiMaxMemoryType, 0 }
+};
+
extern VOID *mHobList;
CHAR8 *mLineBuffer = NULL;
@@ -36,6 +48,12 @@ PrintHob (
IN CONST VOID *HobStart
);
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+ VOID
+ );
+
/**
Find the first substring.
@param String Point to the string where to find the substring.
@@ -192,187 +210,6 @@ FixUpPcdDatabase (
}
/**
- Add HOB into HOB list
- @param[in] Hob The HOB to be added into the HOB list.
-**/
-VOID
-AddNewHob (
- IN EFI_PEI_HOB_POINTERS *Hob
- )
-{
- EFI_PEI_HOB_POINTERS NewHob;
-
- if (Hob->Raw == NULL) {
- return;
- }
-
- NewHob.Header = CreateHob (Hob->Header->HobType, Hob->Header->HobLength);
- ASSERT (NewHob.Header != NULL);
- if (NewHob.Header == NULL) {
- return;
- }
-
- CopyMem (NewHob.Header + 1, Hob->Header + 1, Hob->Header->HobLength - sizeof (EFI_HOB_GENERIC_HEADER));
-}
-
-/**
- Found the Resource Descriptor HOB that contains a range (Base, Top)
- @param[in] HobList Hob start address
- @param[in] Base Memory start address
- @param[in] Top Memory end address.
- @retval The pointer to the Resource Descriptor HOB.
-**/
-EFI_HOB_RESOURCE_DESCRIPTOR *
-FindResourceDescriptorByRange (
- IN VOID *HobList,
- IN EFI_PHYSICAL_ADDRESS Base,
- IN EFI_PHYSICAL_ADDRESS Top
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
- EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
-
- for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
- //
- // Skip all HOBs except Resource Descriptor HOBs
- //
- if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
- continue;
- }
-
- //
- // Skip Resource Descriptor HOBs that do not describe tested system memory
- //
- ResourceHob = Hob.ResourceDescriptor;
- if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
- continue;
- }
-
- if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
- continue;
- }
-
- //
- // Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop
- //
- if (Base < ResourceHob->PhysicalStart) {
- continue;
- }
-
- if (Top > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) {
- continue;
- }
-
- return ResourceHob;
- }
-
- return NULL;
-}
-
-/**
- Find the highest below 4G memory resource descriptor, except the input Resource Descriptor.
- @param[in] HobList Hob start address
- @param[in] MinimalNeededSize Minimal needed size.
- @param[in] ExceptResourceHob Ignore this Resource Descriptor.
- @retval The pointer to the Resource Descriptor HOB.
-**/
-EFI_HOB_RESOURCE_DESCRIPTOR *
-FindAnotherHighestBelow4GResourceDescriptor (
- IN VOID *HobList,
- IN UINTN MinimalNeededSize,
- IN EFI_HOB_RESOURCE_DESCRIPTOR *ExceptResourceHob
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
- EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
- EFI_HOB_RESOURCE_DESCRIPTOR *ReturnResourceHob;
-
- ReturnResourceHob = NULL;
-
- for (Hob.Raw = (UINT8 *)HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
- //
- // Skip all HOBs except Resource Descriptor HOBs
- //
- if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
- continue;
- }
-
- //
- // Skip Resource Descriptor HOBs that do not describe tested system memory
- //
- ResourceHob = Hob.ResourceDescriptor;
- if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) {
- continue;
- }
-
- if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) {
- continue;
- }
-
- //
- // Skip if the Resource Descriptor HOB equals to ExceptResourceHob
- //
- if (ResourceHob == ExceptResourceHob) {
- continue;
- }
-
- //
- // Skip Resource Descriptor HOBs that are beyond 4G
- //
- if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > BASE_4GB) {
- continue;
- }
-
- //
- // Skip Resource Descriptor HOBs that are too small
- //
- if (ResourceHob->ResourceLength < MinimalNeededSize) {
- continue;
- }
-
- //
- // Return the topest Resource Descriptor
- //
- if (ReturnResourceHob == NULL) {
- ReturnResourceHob = ResourceHob;
- } else {
- if (ReturnResourceHob->PhysicalStart < ResourceHob->PhysicalStart) {
- ReturnResourceHob = ResourceHob;
- }
- }
- }
-
- return ReturnResourceHob;
-}
-
-/**
- Check the HOB and decide if it is need inside Payload
- Payload maintainer may make decision which HOB is need or needn't
- Then add the check logic in the function.
- @param[in] Hob The HOB to check
- @retval TRUE If HOB is need inside Payload
- @retval FALSE If HOB is needn't inside Payload
-**/
-BOOLEAN
-IsHobNeed (
- EFI_PEI_HOB_POINTERS Hob
- )
-{
- if (Hob.Header->HobType == EFI_HOB_TYPE_HANDOFF) {
- return FALSE;
- }
-
- if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
- if (CompareGuid (&Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
- return FALSE;
- }
- }
-
- // Arrive here mean the HOB is need
- return TRUE;
-}
-
-/**
It will build Fv HOBs based on information from bootloaders.
@param[out] DxeFv The pointer to the DXE FV in memory.
@retval EFI_SUCCESS If it completed successfully.
@@ -400,6 +237,8 @@ BuildFitLoadablesFvHob (
UINT32 DataSize;
UINT32 *Data32;
+ Fdt = NULL;
+
GuidHob = GetFirstGuidHob (&gUniversalPayloadBaseGuid);
if (GuidHob != NULL) {
PayloadBase = (UNIVERSAL_PAYLOAD_BASE *)GET_GUID_HOB_DATA (GuidHob);
@@ -407,6 +246,10 @@ BuildFitLoadablesFvHob (
DEBUG ((DEBUG_INFO, "PayloadBase Entry = 0x%08x\n", PayloadBase->Entry));
}
+ if (Fdt == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
Status = FdtCheckHeader (Fdt);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
@@ -467,31 +310,25 @@ BuildFitLoadablesFvHob (
}
/**
- It will build HOBs based on information from bootloaders.
- @param[in] BootloaderParameter The starting memory address of bootloader parameter block.
- @param[out] DxeFv The pointer to the DXE FV in memory.
- @retval EFI_SUCCESS If it completed successfully.
- @retval Others If it failed to build required HOBs.
+ *
+ Create new HOB for new HOB list
+
+ @param[in] BootloaderParameter The HOB to be added into the HOB list.
**/
-EFI_STATUS
-BuildHobs (
- IN UINTN BootloaderParameter,
- OUT EFI_FIRMWARE_VOLUME_HEADER **DxeFv
+VOID
+CreatNewHobForHoblist (
+ IN UINTN BootloaderParameter
)
{
- EFI_PEI_HOB_POINTERS Hob;
- UINTN MinimalNeededSize;
- EFI_PHYSICAL_ADDRESS FreeMemoryBottom;
- EFI_PHYSICAL_ADDRESS FreeMemoryTop;
- EFI_PHYSICAL_ADDRESS MemoryBottom;
- EFI_PHYSICAL_ADDRESS MemoryTop;
- EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob;
- EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
- UINT8 *GuidHob;
- EFI_HOB_FIRMWARE_VOLUME *FvHob;
- UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTable;
- ACPI_BOARD_INFO *AcpiBoardInfo;
- EFI_HOB_HANDOFF_INFO_TABLE *HobInfo;
+ EFI_PEI_HOB_POINTERS Hob;
+ UINTN MinimalNeededSize;
+ EFI_PHYSICAL_ADDRESS FreeMemoryBottom;
+ EFI_PHYSICAL_ADDRESS FreeMemoryTop;
+ EFI_PHYSICAL_ADDRESS MemoryBottom;
+ EFI_PHYSICAL_ADDRESS MemoryTop;
+ EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob;
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
+ EFI_HOB_HANDOFF_INFO_TABLE *HobInfo;
Hob.Raw = (UINT8 *)BootloaderParameter;
MinimalNeededSize = FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
@@ -512,7 +349,7 @@ BuildHobs (
//
ResourceHob = FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw, MinimalNeededSize, NULL);
if (ResourceHob == NULL) {
- return EFI_NOT_FOUND;
+ return;
}
MemoryBottom = ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MinimalNeededSize;
@@ -542,7 +379,7 @@ BuildHobs (
//
ResourceHob = FindAnotherHighestBelow4GResourceDescriptor (Hob.Raw, MinimalNeededSize, PhitResourceHob);
if (ResourceHob == NULL) {
- return EFI_NOT_FOUND;
+ return;
}
MemoryBottom = ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MinimalNeededSize;
@@ -553,15 +390,8 @@ BuildHobs (
HobInfo = HobConstructor ((VOID *)(UINTN)MemoryBottom, (VOID *)(UINTN)MemoryTop, (VOID *)(UINTN)FreeMemoryBottom, (VOID *)(UINTN)FreeMemoryTop);
HobInfo->BootMode = Hob.HandoffInformationTable->BootMode;
- //
- // From now on, mHobList will point to the new Hob range.
- //
//
- // Create an empty FvHob for the DXE FV that contains DXE core.
- //
- BuildFvHob ((EFI_PHYSICAL_ADDRESS)0, 0);
- //
// Since payload created new Hob, move all hobs except PHIT from boot loader hob list.
//
while (!END_OF_HOB_LIST (Hob)) {
@@ -573,7 +403,58 @@ BuildHobs (
Hob.Raw = GET_NEXT_HOB (Hob);
}
- BuildFitLoadablesFvHob (DxeFv);
+ return;
+}
+
+/**
+ It will build HOBs based on information from bootloaders.
+ @param[in] NewFdtBase The pointer to New FdtBase.
+ @param[out] DxeFv The pointer to the DXE FV in memory.
+ @retval EFI_SUCCESS If it completed successfully.
+ @retval Others If it failed to build required HOBs.
+**/
+EFI_STATUS
+FitBuildHobs (
+ IN UINTN NewFdtBase,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **DxeFv
+ )
+{
+ UINT8 *GuidHob;
+ UINT32 FdtSize;
+ EFI_HOB_FIRMWARE_VOLUME *FvHob;
+ UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTable;
+ ACPI_BOARD_INFO *AcpiBoardInfo;
+ UNIVERSAL_PAYLOAD_DEVICE_TREE *Fdt;
+
+ if (FixedPcdGetBool (PcdHandOffFdtEnable)) {
+ //
+ // Back up FDT in Reserved memory region
+ //
+ if (NewFdtBase != 0) {
+ GuidHob = GetFirstGuidHob (&gUniversalPayloadDeviceTreeGuid);
+ if (GuidHob != NULL) {
+ Fdt = (UNIVERSAL_PAYLOAD_DEVICE_TREE *)GET_GUID_HOB_DATA (GuidHob);
+ if (Fdt != NULL) {
+ DEBUG ((DEBUG_INFO, "Update FDT base to reserved memory\n"));
+ FdtSize = PcdGet8 (PcdFDTPageSize) * EFI_PAGE_SIZE;
+ CopyMem ((VOID *)NewFdtBase, (VOID *)(Fdt->DeviceTreeAddress), FdtSize);
+ Fdt->DeviceTreeAddress = NewFdtBase;
+ }
+ }
+ }
+ }
+
+ //
+ // To create Memory Type Information HOB
+ //
+ GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid);
+ if (GuidHob == NULL) {
+ BuildGuidDataHob (
+ &gEfiMemoryTypeInformationGuid,
+ mDefaultMemoryTypeInformation,
+ sizeof (mDefaultMemoryTypeInformation)
+ );
+ }
//
// Create guid hob for acpi board information
@@ -589,6 +470,12 @@ BuildHobs (
}
//
+ // Create an empty FvHob for the DXE FV that contains DXE core.
+ //
+ BuildFvHob ((EFI_PHYSICAL_ADDRESS)0, 0);
+
+ BuildFitLoadablesFvHob (DxeFv);
+ //
// Update DXE FV information to first fv hob in the hob list, which
// is the empty FvHob created before.
//
@@ -600,12 +487,12 @@ BuildHobs (
/**
Entry point to the C language phase of UEFI payload.
- @param[in] BootloaderParameter The starting address of bootloader parameter block.
+ @param[in] BootloaderParameter The starting address of FDT .
@retval It will not return if SUCCESS, and return error when passing bootloader parameter.
**/
EFI_STATUS
EFIAPI
-_ModuleEntryPoint (
+FitUplEntryPoint (
IN UINTN BootloaderParameter
)
{
@@ -614,13 +501,51 @@ _ModuleEntryPoint (
EFI_PEI_HOB_POINTERS Hob;
EFI_FIRMWARE_VOLUME_HEADER *DxeFv;
- mHobList = (VOID *)BootloaderParameter;
- DxeFv = NULL;
+ #if FixedPcdGetBool (PcdHandOffFdtEnable) == 1
+ PHYSICAL_ADDRESS HobListPtr;
+ VOID *FdtBase;
+ #endif
+ VOID *FdtBaseResvd;
+
+ if (FixedPcdGetBool (PcdHandOffFdtEnable)) {
+ mHobList = (VOID *)NULL;
+ } else {
+ mHobList = (VOID *)BootloaderParameter;
+ }
+
+ DxeFv = NULL;
+ FdtBaseResvd = 0;
// Call constructor for all libraries
ProcessLibraryConstructorList ();
DEBUG ((DEBUG_INFO, "Entering Universal Payload...\n"));
DEBUG ((DEBUG_INFO, "sizeof(UINTN) = 0x%x\n", sizeof (UINTN)));
+ DEBUG ((DEBUG_INFO, "BootloaderParameter = 0x%x\n", BootloaderParameter));
+
+ DEBUG ((DEBUG_INFO, "Start init Hobs...\n"));
+ #if FixedPcdGetBool (PcdHandOffFdtEnable) == 1
+ HobListPtr = UplInitHob ((VOID *)BootloaderParameter);
+
+ //
+ // Found hob list node
+ //
+ if (HobListPtr != 0) {
+ FdtBase = (VOID *)BootloaderParameter;
+ if (FdtCheckHeader (FdtBase) == 0) {
+ CustomFdtNodeParser ((VOID *)FdtBase, (VOID *)HobListPtr);
+ FdtBaseResvd = PayloadAllocatePages (PcdGet8 (PcdFDTPageSize), EfiReservedMemoryType);
+ }
+ }
+
+ #else
+ CreatNewHobForHoblist (BootloaderParameter);
+ #endif
+
+ // Build HOB based on information from Bootloader
+ Status = FitBuildHobs ((UINTN)FdtBaseResvd, &DxeFv);
+
+ // Call constructor for all libraries again since hobs were built
+ ProcessLibraryConstructorList ();
DEBUG_CODE (
//
@@ -629,23 +554,10 @@ _ModuleEntryPoint (
PrintHob (mHobList);
);
- // Initialize floating point operating environment to be compliant with UEFI spec.
- InitializeFloatingPointUnits ();
-
- // Build HOB based on information from Bootloader
- Status = BuildHobs (BootloaderParameter, &DxeFv);
- ASSERT_EFI_ERROR (Status);
-
FixUpPcdDatabase (DxeFv);
Status = UniversalLoadDxeCore (DxeFv, &DxeCoreEntryPoint);
ASSERT_EFI_ERROR (Status);
- //
- // Mask off all legacy 8259 interrupt sources
- //
- IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
- IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);
-
Hob.HandoffInformationTable = (EFI_HOB_HANDOFF_INFO_TABLE *)GetFirstHob (EFI_HOB_TYPE_HANDOFF);
HandOffToDxeCore (DxeCoreEntryPoint, Hob);
diff --git a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf
index b87a098..5887830 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf
+++ b/UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf
@@ -30,13 +30,17 @@
[Sources.Ia32]
X64/VirtualMemory.h
X64/VirtualMemory.c
- Ia32/DxeLoadFunc.c
+ Ia32/DxeLoadFuncFit.c
Ia32/IdtVectorAsm.nasm
[Sources.X64]
X64/VirtualMemory.h
X64/VirtualMemory.c
- X64/DxeLoadFunc.c
+ X64/DxeLoadFuncFit.c
+
+[Sources.RISCV64]
+ RiscV64/DxeLoadFunc.c
+ RiscV64/DxeLoadFuncFit.c
[Packages]
MdePkg/MdePkg.dec
@@ -54,6 +58,9 @@
PeCoffLib
CpuLib
FdtLib
+ HobPrintLib
+ CustomFdtNodeParserLib
+ PcdLib
[Guids]
gEfiMemoryTypeInformationGuid
@@ -71,6 +78,7 @@
gUniversalPayloadAcpiTableGuid
gUniversalPayloadPciRootBridgeInfoGuid
gUniversalPayloadSmbios3TableGuid
+ gUniversalPayloadDeviceTreeGuid
[FeaturePcd.IA32]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES
@@ -78,8 +86,7 @@
[FeaturePcd.X64]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables ## CONSUMES
-
-[Pcd.IA32,Pcd.X64]
+[Pcd.IA32,Pcd.X64,Pcd.RISCV64]
gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES
@@ -88,11 +95,20 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize ## CONSUMES
-
gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
-
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES
+ gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable
+ gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+ gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+ gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+ gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+ gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+ gUefiPayloadPkgTokenSpaceGuid.PcdFDTPageSize
+
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = /wd4244 /wd4305
+ GCC:*_*_*_CC_FLAGS = -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast
diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
index 61a9f01..cf9c03a 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c
@@ -15,12 +15,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
+#include <Library/FdtLib.h>
#include "VirtualMemory.h"
#include "UefiPayloadEntry.h"
#define STACK_SIZE 0x20000
#define IDT_ENTRY_COUNT 32
+extern VOID *mHobList;
+
typedef struct _X64_IDT_TABLE {
//
// Reserved 4 bytes preceding PeiService and IdtTable,
@@ -268,6 +271,15 @@ HandOffToDxeCore (
UINT32 Index;
X64_IDT_TABLE *IdtTableForX64;
+ // Initialize floating point operating environment to be compliant with UEFI spec.
+ InitializeFloatingPointUnits ();
+
+ //
+ // Mask off all legacy 8259 interrupt sources
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);
+
//
// Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
//
diff --git a/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c
new file mode 100644
index 0000000..439d5be
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFuncFit.c
@@ -0,0 +1,405 @@
+/** @file
+ Ia32-specific functionality for DxeLoad.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/FdtLib.h>
+#include "VirtualMemory.h"
+#include "UefiPayloadEntry.h"
+
+#define STACK_SIZE 0x20000
+#define IDT_ENTRY_COUNT 32
+
+extern VOID *mHobList;
+
+typedef struct _X64_IDT_TABLE {
+ //
+ // Reserved 4 bytes preceding PeiService and IdtTable,
+ // since IDT base address should be 8-byte alignment.
+ //
+ UINT32 Reserved;
+ CONST EFI_PEI_SERVICES **PeiService;
+ X64_IDT_GATE_DESCRIPTOR IdtTable[IDT_ENTRY_COUNT];
+} X64_IDT_TABLE;
+
+//
+// Global Descriptor Table (GDT)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT gGdtEntries[] = {
+ /* selector { Global Segment Descriptor } */
+ /* 0x00 */ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ }, // null descriptor
+ /* 0x08 */ {
+ { 0xffff, 0, 0, 0x2, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
+ }, // linear data segment descriptor
+ /* 0x10 */ {
+ { 0xffff, 0, 0, 0xf, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
+ }, // linear code segment descriptor
+ /* 0x18 */ {
+ { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
+ }, // system data segment descriptor
+ /* 0x20 */ {
+ { 0xffff, 0, 0, 0xa, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
+ }, // system code segment descriptor
+ /* 0x28 */ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ }, // spare segment descriptor
+ /* 0x30 */ {
+ { 0xffff, 0, 0, 0x2, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
+ }, // system data segment descriptor
+ /* 0x38 */ {
+ { 0xffff, 0, 0, 0xa, 1, 0, 1, 0xf, 0, 1, 0, 1, 0 }
+ }, // system code segment descriptor
+ /* 0x40 */ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ }, // spare segment descriptor
+};
+
+//
+// IA32 Gdt register
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR gGdt = {
+ sizeof (gGdtEntries) - 1,
+ (UINTN)gGdtEntries
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR gLidtDescriptor = {
+ sizeof (X64_IDT_GATE_DESCRIPTOR) * IDT_ENTRY_COUNT - 1,
+ 0
+};
+
+/**
+ Allocates and fills in the Page Directory and Page Table Entries to
+ establish a 4G page table.
+
+ @param[in] StackBase Stack base address.
+ @param[in] StackSize Stack size.
+
+ @return The address of page table.
+
+**/
+UINTN
+Create4GPageTablesIa32Pae (
+ IN EFI_PHYSICAL_ADDRESS StackBase,
+ IN UINTN StackSize
+ )
+{
+ UINT8 PhysicalAddressBits;
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;
+ UINTN IndexOfPdpEntries;
+ UINTN IndexOfPageDirectoryEntries;
+ UINT32 NumberOfPdpEntriesNeeded;
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageMap;
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
+ PAGE_TABLE_ENTRY *PageDirectoryEntry;
+ UINTN TotalPagesNum;
+ UINTN PageAddress;
+ UINT64 AddressEncMask;
+
+ //
+ // Make sure AddressEncMask is contained to smallest supported address field
+ //
+ AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
+
+ PhysicalAddressBits = 32;
+
+ //
+ // Calculate the table entries needed.
+ //
+ NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
+
+ TotalPagesNum = NumberOfPdpEntriesNeeded + 1;
+ PageAddress = (UINTN)AllocatePageTableMemory (TotalPagesNum);
+ ASSERT (PageAddress != 0);
+
+ PageMap = (VOID *)PageAddress;
+ PageAddress += SIZE_4KB;
+
+ PageDirectoryPointerEntry = PageMap;
+ PhysicalAddress = 0;
+
+ for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
+ //
+ // Each Directory Pointer entries points to a page of Page Directory entires.
+ // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
+ //
+ PageDirectoryEntry = (VOID *)PageAddress;
+ PageAddress += SIZE_4KB;
+
+ //
+ // Fill in a Page Directory Pointer Entries
+ //
+ PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask;
+ PageDirectoryPointerEntry->Bits.Present = 1;
+
+ for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) {
+ if ( (IsNullDetectionEnabled () && (PhysicalAddress == 0))
+ || ( (PhysicalAddress < StackBase + StackSize)
+ && ((PhysicalAddress + SIZE_2MB) > StackBase)))
+ {
+ //
+ // Need to split this 2M page that covers stack range.
+ //
+ Split2MPageTo4K (PhysicalAddress, (UINT64 *)PageDirectoryEntry, StackBase, StackSize, 0, 0);
+ } else {
+ //
+ // Fill in the Page Directory entries
+ //
+ PageDirectoryEntry->Uint64 = (UINT64)PhysicalAddress | AddressEncMask;
+ PageDirectoryEntry->Bits.ReadWrite = 1;
+ PageDirectoryEntry->Bits.Present = 1;
+ PageDirectoryEntry->Bits.MustBe1 = 1;
+ }
+ }
+ }
+
+ for ( ; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
+ ZeroMem (
+ PageDirectoryPointerEntry,
+ sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
+ );
+ }
+
+ //
+ // Protect the page table by marking the memory used for page table to be
+ // read-only.
+ //
+ EnablePageTableProtection ((UINTN)PageMap, FALSE);
+
+ return (UINTN)PageMap;
+}
+
+/**
+ The function will check if IA32 PAE is supported.
+
+ @retval TRUE IA32 PAE is supported.
+ @retval FALSE IA32 PAE is not supported.
+
+**/
+BOOLEAN
+IsIa32PaeSupport (
+ VOID
+ )
+{
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ BOOLEAN Ia32PaeSupport;
+
+ Ia32PaeSupport = FALSE;
+ AsmCpuid (0x0, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x1) {
+ AsmCpuid (0x1, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT6) != 0) {
+ Ia32PaeSupport = TRUE;
+ }
+ }
+
+ return Ia32PaeSupport;
+}
+
+/**
+ The function will check if page table should be setup or not.
+
+ @retval TRUE Page table should be created.
+ @retval FALSE Page table should not be created.
+
+**/
+BOOLEAN
+ToBuildPageTable (
+ VOID
+ )
+{
+ if (!IsIa32PaeSupport ()) {
+ return FALSE;
+ }
+
+ if (IsNullDetectionEnabled ()) {
+ return TRUE;
+ }
+
+ if (PcdGet8 (PcdHeapGuardPropertyMask) != 0) {
+ return TRUE;
+ }
+
+ if (PcdGetBool (PcdCpuStackGuard)) {
+ return TRUE;
+ }
+
+ if (IsEnableNonExecNeeded ()) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Transfers control to DxeCore.
+
+ This function performs a CPU architecture specific operations to execute
+ the entry point of DxeCore with the parameters of HobList.
+
+ @param DxeCoreEntryPoint The entry point of DxeCore.
+ @param HobList The start of HobList passed to DxeCore.
+
+**/
+VOID
+HandOffToDxeCore (
+ IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint,
+ IN EFI_PEI_HOB_POINTERS HobList
+ )
+{
+ EFI_PHYSICAL_ADDRESS BaseOfStack;
+ EFI_PHYSICAL_ADDRESS TopOfStack;
+ UINTN PageTables;
+ X64_IDT_GATE_DESCRIPTOR *IdtTable;
+ UINTN SizeOfTemplate;
+ VOID *TemplateBase;
+ EFI_PHYSICAL_ADDRESS VectorAddress;
+ UINT32 Index;
+ X64_IDT_TABLE *IdtTableForX64;
+
+ // Initialize floating point operating environment to be compliant with UEFI spec.
+ InitializeFloatingPointUnits ();
+
+ //
+ // Mask off all legacy 8259 interrupt sources
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);
+
+ //
+ // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
+ //
+ if (IsNullDetectionEnabled ()) {
+ ClearFirst4KPage (HobList.Raw);
+ BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
+ }
+
+ BaseOfStack = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
+ ASSERT (BaseOfStack != 0);
+
+ if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ //
+ // Compute the top of the stack we were allocated, which is used to load X64 dxe core.
+ // Pre-allocate a 32 bytes which confroms to x64 calling convention.
+ //
+ // The first four parameters to a function are passed in rcx, rdx, r8 and r9.
+ // Any further parameters are pushed on the stack. Furthermore, space (4 * 8bytes) for the
+ // register parameters is reserved on the stack, in case the called function
+ // wants to spill them; this is important if the function is variadic.
+ //
+ TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32;
+
+ //
+ // x64 Calling Conventions requires that the stack must be aligned to 16 bytes
+ //
+ TopOfStack = (EFI_PHYSICAL_ADDRESS)(UINTN)ALIGN_POINTER (TopOfStack, 16);
+
+ //
+ // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA
+ // memory, it may be corrupted when copying FV to high-end memory
+ //
+ AsmWriteGdtr (&gGdt);
+ //
+ // Create page table and save PageMapLevel4 to CR3
+ //
+ PageTables = CreateIdentityMappingPageTables (BaseOfStack, STACK_SIZE, 0, 0);
+
+ //
+ // Paging might be already enabled. To avoid conflict configuration,
+ // disable paging first anyway.
+ //
+ AsmWriteCr0 (AsmReadCr0 () & (~BIT31));
+ AsmWriteCr3 (PageTables);
+
+ //
+ // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
+ //
+ UpdateStackHob (BaseOfStack, STACK_SIZE);
+
+ SizeOfTemplate = AsmGetVectorTemplatInfo (&TemplateBase);
+
+ VectorAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (X64_IDT_TABLE) + SizeOfTemplate * IDT_ENTRY_COUNT));
+ ASSERT (VectorAddress != 0);
+
+ //
+ // Store EFI_PEI_SERVICES** in the 4 bytes immediately preceding IDT to avoid that
+ // it may not be gotten correctly after IDT register is re-written.
+ //
+ IdtTableForX64 = (X64_IDT_TABLE *)(UINTN)VectorAddress;
+ IdtTableForX64->PeiService = NULL;
+
+ VectorAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(IdtTableForX64 + 1);
+ IdtTable = IdtTableForX64->IdtTable;
+ for (Index = 0; Index < IDT_ENTRY_COUNT; Index++) {
+ IdtTable[Index].Ia32IdtEntry.Bits.GateType = 0x8e;
+ IdtTable[Index].Ia32IdtEntry.Bits.Reserved_0 = 0;
+ IdtTable[Index].Ia32IdtEntry.Bits.Selector = SYS_CODE64_SEL;
+
+ IdtTable[Index].Ia32IdtEntry.Bits.OffsetLow = (UINT16)VectorAddress;
+ IdtTable[Index].Ia32IdtEntry.Bits.OffsetHigh = (UINT16)(RShiftU64 (VectorAddress, 16));
+ IdtTable[Index].Offset32To63 = (UINT32)(RShiftU64 (VectorAddress, 32));
+ IdtTable[Index].Reserved = 0;
+
+ CopyMem ((VOID *)(UINTN)VectorAddress, TemplateBase, SizeOfTemplate);
+ AsmVectorFixup ((VOID *)(UINTN)VectorAddress, (UINT8)Index);
+
+ VectorAddress += SizeOfTemplate;
+ }
+
+ gLidtDescriptor.Base = (UINTN)IdtTable;
+
+ AsmWriteIdtr (&gLidtDescriptor);
+
+ DEBUG ((
+ DEBUG_INFO,
+ "%a() Stack Base: 0x%lx, Stack Size: 0x%x\n",
+ __func__,
+ BaseOfStack,
+ STACK_SIZE
+ ));
+
+ //
+ // Go to Long Mode and transfer control to DxeCore.
+ // Interrupts will not get turned on until the CPU AP is loaded.
+ // Call x64 drivers passing in single argument, a pointer to the HOBs.
+ //
+ AsmEnablePaging64 (
+ SYS_CODE64_SEL,
+ DxeCoreEntryPoint,
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw),
+ 0,
+ TopOfStack
+ );
+ } else {
+ // 32bit UEFI payload could be supported if required later.
+ DEBUG ((DEBUG_ERROR, "NOT support 32bit UEFI payload\n"));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+}
+
+/**
+ Entry point to the C language phase of UEFI payload.
+ @param[in] BootloaderParameter The starting address of bootloader parameter block.
+ @retval It will not return if SUCCESS, and return error when passing bootloader parameter.
+**/
+EFI_STATUS
+EFIAPI
+_ModuleEntryPoint (
+ IN UINTN BootloaderParameter
+ )
+{
+ return FitUplEntryPoint (BootloaderParameter);
+}
diff --git a/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c
index 83936ae..23bbf19 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c
@@ -20,6 +20,56 @@
is returned.
@param Pages The number of 4 KB pages to allocate.
+ @param MemoryType The MemoryType
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+**/
+VOID *
+EFIAPI
+PayloadAllocatePages (
+ IN UINTN Pages,
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PHYSICAL_ADDRESS Offset;
+ EFI_HOB_HANDOFF_INFO_TABLE *HobTable;
+
+ Hob.Raw = GetHobList ();
+ HobTable = Hob.HandoffInformationTable;
+
+ if (Pages == 0) {
+ return NULL;
+ }
+
+ // Make sure allocation address is page alligned.
+ Offset = HobTable->EfiFreeMemoryTop & EFI_PAGE_MASK;
+ if (Offset != 0) {
+ HobTable->EfiFreeMemoryTop -= Offset;
+ }
+
+ //
+ // Check available memory for the allocation
+ //
+ if (HobTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < HobTable->EfiFreeMemoryBottom) {
+ return NULL;
+ }
+
+ HobTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;
+ BuildMemoryAllocationHob (HobTable->EfiFreeMemoryTop, Pages * EFI_PAGE_SIZE, MemoryType);
+
+ return (VOID *)(UINTN)HobTable->EfiFreeMemoryTop;
+}
+
+/**
+ Allocates one or more pages of type EfiBootServicesData.
+
+ Allocates the number of pages of MemoryType 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 availble 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 *
@@ -39,7 +89,7 @@ AllocatePages (
return NULL;
}
- // Make sure allocation address is page alligned.
+ // Make sure allocation address is page aligned.
Offset = HobTable->EfiFreeMemoryTop & EFI_PAGE_MASK;
if (Offset != 0) {
HobTable->EfiFreeMemoryTop -= Offset;
diff --git a/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c b/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c
index b63e93c..44c9977 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c
@@ -10,51 +10,7 @@
#include <UniversalPayload/ExtraData.h>
#include <Guid/MemoryTypeInformation.h>
#include <Guid/AcpiBoardInfoGuid.h>
-
-#define ROW_LIMITER 16
-
-typedef
-EFI_STATUS
-(*HOB_PRINT_HANDLER) (
- IN VOID *Hob,
- IN UINT16 HobLength
- );
-
-typedef struct {
- UINT16 Type;
- CHAR8 *Name;
- HOB_PRINT_HANDLER PrintHandler;
-} HOB_PRINT_HANDLER_TABLE;
-
-CHAR8 *mMemoryTypeStr[] = {
- "EfiReservedMemoryType",
- "EfiLoaderCode",
- "EfiLoaderData",
- "EfiBootServicesCode",
- "EfiBootServicesData",
- "EfiRuntimeServicesCode",
- "EfiRuntimeServicesData",
- "EfiConventionalMemory",
- "EfiUnusableMemory",
- "EfiACPIReclaimMemory",
- "EfiACPIMemoryNVS",
- "EfiMemoryMappedIO",
- "EfiMemoryMappedIOPortSpace",
- "EfiPalCode",
- "EfiPersistentMemory",
- "EfiMaxMemoryType"
-};
-
-CHAR8 *mResource_Type_List[] = {
- "EFI_RESOURCE_SYSTEM_MEMORY ", // 0x00000000
- "EFI_RESOURCE_MEMORY_MAPPED_IO ", // 0x00000001
- "EFI_RESOURCE_IO ", // 0x00000002
- "EFI_RESOURCE_FIRMWARE_DEVICE ", // 0x00000003
- "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT ", // 0x00000004
- "EFI_RESOURCE_MEMORY_RESERVED ", // 0x00000005
- "EFI_RESOURCE_IO_RESERVED ", // 0x00000006
- "EFI_RESOURCE_MAX_MEMORY_TYPE " // 0x00000007
-};
+#include <Library/HobPrintLib.h>
typedef
EFI_STATUS
@@ -69,133 +25,6 @@ typedef struct {
CHAR8 *GuidName;
} GUID_HOB_PRINT_HANDLE;
-typedef struct {
- EFI_GUID *Guid;
- CHAR8 *Type;
-} PRINT_MEMORY_ALLOCCATION_HOB;
-
-/**
- Print the Hex value of a given range.
- @param[in] DataStart A pointer to the start of data to be printed.
- @param[in] DataSize The length of the data to be printed.
- @retval EFI_SUCCESS If it completed successfully.
-**/
-EFI_STATUS
-PrintHex (
- IN UINT8 *DataStart,
- IN UINT16 DataSize
- )
-{
- UINTN Index1;
- UINTN Index2;
- UINT8 *StartAddr;
-
- StartAddr = DataStart;
- for (Index1 = 0; Index1 * ROW_LIMITER < DataSize; Index1++) {
- DEBUG ((DEBUG_VERBOSE, " 0x%04p:", (DataStart - StartAddr)));
- for (Index2 = 0; (Index2 < ROW_LIMITER) && (Index1 * ROW_LIMITER + Index2 < DataSize); Index2++) {
- DEBUG ((DEBUG_VERBOSE, " %02x", *DataStart));
- DataStart++;
- }
-
- DEBUG ((DEBUG_VERBOSE, "\n"));
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Print the information in HandOffHob.
-
- @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_HANDOFF.
- @param[in] HobLength The length in bytes of HOB of type EFI_HOB_TYPE_HANDOFF.
- @retval EFI_SUCCESS If it completed successfully.
-**/
-EFI_STATUS
-PrintHandOffHob (
- IN VOID *HobStart,
- IN UINT16 HobLength
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
-
- Hob.Raw = (UINT8 *)HobStart;
- ASSERT (HobLength >= sizeof (*Hob.HandoffInformationTable));
- DEBUG ((DEBUG_INFO, " BootMode = 0x%x\n", Hob.HandoffInformationTable->BootMode));
- DEBUG ((DEBUG_INFO, " EfiMemoryTop = 0x%lx\n", Hob.HandoffInformationTable->EfiMemoryTop));
- DEBUG ((DEBUG_INFO, " EfiMemoryBottom = 0x%lx\n", Hob.HandoffInformationTable->EfiMemoryBottom));
- DEBUG ((DEBUG_INFO, " EfiFreeMemoryTop = 0x%lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop));
- DEBUG ((DEBUG_INFO, " EfiFreeMemoryBottom = 0x%lx\n", Hob.HandoffInformationTable->EfiFreeMemoryBottom));
- DEBUG ((DEBUG_INFO, " EfiEndOfHobList = 0x%lx\n", Hob.HandoffInformationTable->EfiEndOfHobList));
- return EFI_SUCCESS;
-}
-
-/**
- Print the information in Memory Allocation Hob.
- @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_MEMORY_ALLOCATION.
- @param[in] HobLength The length in bytes of HOB of type EFI_HOB_TYPE_MEMORY_ALLOCATION.
- @retval EFI_SUCCESS If it completed successfully.
-**/
-EFI_STATUS
-PrintMemoryAllocationHob (
- IN VOID *HobStart,
- IN UINT16 HobLength
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
-
- Hob.Raw = (UINT8 *)HobStart;
-
- if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocStackGuid)) {
- ASSERT (HobLength >= sizeof (*Hob.MemoryAllocationStack));
- DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_STACK\n"));
- } else if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocBspStoreGuid)) {
- ASSERT (HobLength >= sizeof (*Hob.MemoryAllocationBspStore));
- DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_BSP_STORE\n"));
- } else if (CompareGuid (&Hob.MemoryAllocation->AllocDescriptor.Name, &gEfiHobMemoryAllocModuleGuid)) {
- ASSERT (HobLength >= sizeof (*Hob.MemoryAllocationModule));
- DEBUG ((DEBUG_INFO, " Type = EFI_HOB_MEMORY_ALLOCATION_MODULE\n"));
- DEBUG ((DEBUG_INFO, " Module Name = %g\n", Hob.MemoryAllocationModule->ModuleName));
- DEBUG ((DEBUG_INFO, " Physical Address = 0x%lx\n", Hob.MemoryAllocationModule->EntryPoint));
- } else {
- ASSERT (HobLength >= sizeof (*Hob.MemoryAllocation));
- DEBUG ((DEBUG_INFO, " Type = EFI_HOB_TYPE_MEMORY_ALLOCATION\n"));
- }
-
- DEBUG ((DEBUG_INFO, " MemoryBaseAddress = 0x%lx\n", Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress));
- DEBUG ((DEBUG_INFO, " MemoryLength = 0x%lx\n", Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength));
- DEBUG ((DEBUG_INFO, " MemoryType = %a \n", mMemoryTypeStr[Hob.MemoryAllocationStack->AllocDescriptor.MemoryType]));
- return EFI_SUCCESS;
-}
-
-/**
- Print the information in Resource Discriptor Hob.
- @param[in] HobStart A pointer to HOB of type EFI_HOB_TYPE_RESOURCE_DESCRIPTOR.
- @param[in] HobLength The Length in bytes of HOB of type EFI_HOB_TYPE_RESOURCE_DESCRIPTOR.
- @retval EFI_SUCCESS If it completed successfully.
-**/
-EFI_STATUS
-PrintResourceDiscriptorHob (
- IN VOID *HobStart,
- IN UINT16 HobLength
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
-
- Hob.Raw = (UINT8 *)HobStart;
- ASSERT (HobLength >= sizeof (*Hob.ResourceDescriptor));
-
- DEBUG ((DEBUG_INFO, " ResourceType = %a\n", mResource_Type_List[Hob.ResourceDescriptor->ResourceType]));
- if (!IsZeroGuid (&Hob.ResourceDescriptor->Owner)) {
- DEBUG ((DEBUG_INFO, " Owner = %g\n", Hob.ResourceDescriptor->Owner));
- }
-
- DEBUG ((DEBUG_INFO, " ResourceAttribute = 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
- DEBUG ((DEBUG_INFO, " PhysicalStart = 0x%lx\n", Hob.ResourceDescriptor->PhysicalStart));
- DEBUG ((DEBUG_INFO, " ResourceLength = 0x%lx\n", Hob.ResourceDescriptor->ResourceLength));
- return EFI_SUCCESS;
-}
-
/**
Print the information in Acpi Guid Hob.
@@ -340,7 +169,7 @@ PrintPciRootBridgeInfoGuidHob (
Index = 0;
PciRootBridges = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)GET_GUID_HOB_DATA (HobRaw);
- Length = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES) + PciRootBridges->Count * sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE);
+ Length = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES) + (PciRootBridges->Count * sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE));
ASSERT (HobLength >= Length);
DEBUG ((DEBUG_INFO, " Revision = 0x%x\n", PciRootBridges->Header.Revision));
DEBUG ((DEBUG_INFO, " Length = 0x%x\n", PciRootBridges->Header.Length));
@@ -456,9 +285,10 @@ GUID_HOB_PRINT_HANDLE GuidHobPrintHandleTable[] = {
@param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_GUID_EXTENSION.
@param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_GUID_EXTENSION.
@retval EFI_SUCCESS If it completed successfully.
+ @retval EFI_UNSUPPORTED If the HOB GUID is not supported.
**/
EFI_STATUS
-PrintGuidHob (
+InternalPrintGuidHob (
IN VOID *HobStart,
IN UINT16 HobLength
)
@@ -478,53 +308,7 @@ PrintGuidHob (
}
}
- DEBUG ((DEBUG_INFO, " Name = %g\n", &Hob.Guid->Name));
- PrintHex (GET_GUID_HOB_DATA (Hob.Raw), GET_GUID_HOB_DATA_SIZE (Hob.Raw));
- return EFI_SUCCESS;
-}
-
-/**
- Print the information in FV Hob.
- @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV.
- @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV.
- @retval EFI_SUCCESS If it completed successfully.
-**/
-EFI_STATUS
-PrintFvHob (
- IN VOID *HobStart,
- IN UINT16 HobLength
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
-
- Hob.Raw = (UINT8 *)HobStart;
- ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume));
-
- DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume->BaseAddress));
- DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume->Length));
- return EFI_SUCCESS;
-}
-
-/**
- Print the information in Cpu Hob.
- @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_CPU.
- @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_CPU.
- @retval EFI_SUCCESS If it completed successfully.
-**/
-EFI_STATUS
-PrintCpuHob (
- IN VOID *HobStart,
- IN UINT16 HobLength
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
-
- Hob.Raw = (UINT8 *)HobStart;
- ASSERT (HobLength >= sizeof (*Hob.Cpu));
-
- DEBUG ((DEBUG_INFO, " SizeOfMemorySpace = 0x%lx\n", Hob.Cpu->SizeOfMemorySpace));
- DEBUG ((DEBUG_INFO, " SizeOfIoSpace = 0x%lx\n", Hob.Cpu->SizeOfIoSpace));
- return EFI_SUCCESS;
+ return EFI_UNSUPPORTED;
}
/**
@@ -534,7 +318,7 @@ PrintCpuHob (
@retval EFI_SUCCESS If it completed successfully.
**/
EFI_STATUS
-PrintMemoryPoolHob (
+InternalPrintMemoryPoolHob (
IN VOID *HobStart,
IN UINT16 HobLength
)
@@ -543,37 +327,16 @@ PrintMemoryPoolHob (
}
/**
- Print the information in Fv2Hob.
- @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV2.
- @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV2.
- @retval EFI_SUCCESS If it completed successfully.
-**/
-EFI_STATUS
-PrintFv2Hob (
- IN VOID *HobStart,
- IN UINT16 HobLength
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
+ HOB Print Handler to print Guid Hob.
- Hob.Raw = (UINT8 *)HobStart;
- ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume2));
-
- DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume2->BaseAddress));
- DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume2->Length));
- DEBUG ((DEBUG_INFO, " FvName = %g\n", &Hob.FirmwareVolume2->FvName));
- DEBUG ((DEBUG_INFO, " FileName = %g\n", &Hob.FirmwareVolume2->FileName));
- return EFI_SUCCESS;
-}
+ @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_GUID_EXTENSION.
+ @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_GUID_EXTENSION.
-/**
- Print the information in Capsule Hob.
- @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_UEFI_CAPSULE.
- @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_UEFI_CAPSULE.
@retval EFI_SUCCESS If it completed successfully.
+ @retval EFI_UNSUPPORTED If the HOB type is not supported.
**/
EFI_STATUS
-PrintCapsuleHob (
+InternalPrintHobs (
IN VOID *HobStart,
IN UINT16 HobLength
)
@@ -581,96 +344,24 @@ PrintCapsuleHob (
EFI_PEI_HOB_POINTERS Hob;
Hob.Raw = (UINT8 *)HobStart;
- ASSERT (HobLength >= sizeof (*Hob.Capsule));
-
- DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.Capsule->BaseAddress));
- DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.Capsule->Length));
- return EFI_SUCCESS;
-}
-/**
- Print the information in Fv3 Hob.
- @param[in] HobStart A pointer to the HOB of type EFI_HOB_TYPE_FV3.
- @param[in] HobLength The length in bytes of the HOB of type EFI_HOB_TYPE_FV3.
- @retval EFI_SUCCESS If it completed successfully.
-**/
-EFI_STATUS
-PrintFv3Hob (
- IN VOID *HobStart,
- IN UINT16 HobLength
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
+ if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
+ return InternalPrintGuidHob (Hob.Raw, HobLength);
+ } else if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_POOL) {
+ return InternalPrintMemoryPoolHob (Hob.Raw, HobLength);
+ }
- Hob.Raw = (UINT8 *)HobStart;
- ASSERT (HobLength >= sizeof (*Hob.FirmwareVolume3));
-
- DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", Hob.FirmwareVolume3->BaseAddress));
- DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Hob.FirmwareVolume3->Length));
- DEBUG ((DEBUG_INFO, " AuthenticationStatus = 0x%x\n", Hob.FirmwareVolume3->AuthenticationStatus));
- DEBUG ((DEBUG_INFO, " ExtractedFv = %a\n", (Hob.FirmwareVolume3->ExtractedFv ? "True" : "False")));
- DEBUG ((DEBUG_INFO, " FVName = %g\n", &Hob.FirmwareVolume3->FvName));
- DEBUG ((DEBUG_INFO, " FileName = %g\n", &Hob.FirmwareVolume3->FileName));
- return EFI_SUCCESS;
+ return EFI_UNSUPPORTED;
}
-//
-// Mappint table from Hob type to Hob print function.
-//
-HOB_PRINT_HANDLER_TABLE mHobHandles[] = {
- { EFI_HOB_TYPE_HANDOFF, "EFI_HOB_TYPE_HANDOFF", PrintHandOffHob },
- { EFI_HOB_TYPE_MEMORY_ALLOCATION, "EFI_HOB_TYPE_MEMORY_ALLOCATION", PrintMemoryAllocationHob },
- { EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR", PrintResourceDiscriptorHob },
- { EFI_HOB_TYPE_GUID_EXTENSION, "EFI_HOB_TYPE_GUID_EXTENSION", PrintGuidHob },
- { EFI_HOB_TYPE_FV, "EFI_HOB_TYPE_FV", PrintFvHob },
- { EFI_HOB_TYPE_CPU, "EFI_HOB_TYPE_CPU", PrintCpuHob },
- { EFI_HOB_TYPE_MEMORY_POOL, "EFI_HOB_TYPE_MEMORY_POOL", PrintMemoryPoolHob },
- { EFI_HOB_TYPE_FV2, "EFI_HOB_TYPE_FV2", PrintFv2Hob },
- { EFI_HOB_TYPE_UEFI_CAPSULE, "EFI_HOB_TYPE_UEFI_CAPSULE", PrintCapsuleHob },
- { EFI_HOB_TYPE_FV3, "EFI_HOB_TYPE_FV3", PrintFv3Hob }
-};
-
/**
Print all HOBs info from the HOB list.
@param[in] HobStart A pointer to the HOB list
- @return The pointer to the HOB list.
**/
VOID
PrintHob (
IN CONST VOID *HobStart
)
{
- EFI_PEI_HOB_POINTERS Hob;
- UINTN Count;
- UINTN Index;
-
- ASSERT (HobStart != NULL);
-
- Hob.Raw = (UINT8 *)HobStart;
- DEBUG ((DEBUG_INFO, "Print all Hob information from Hob 0x%p\n", Hob.Raw));
-
- Count = 0;
- //
- // Parse the HOB list to see which type it is, and print the information.
- //
- while (!END_OF_HOB_LIST (Hob)) {
- for (Index = 0; Index < ARRAY_SIZE (mHobHandles); Index++) {
- if (Hob.Header->HobType == mHobHandles[Index].Type) {
- DEBUG ((DEBUG_INFO, "HOB[%d]: Type = %a, Offset = 0x%p, Length = 0x%x\n", Count, mHobHandles[Index].Name, (Hob.Raw - (UINT8 *)HobStart), Hob.Header->HobLength));
- mHobHandles[Index].PrintHandler (Hob.Raw, Hob.Header->HobLength);
- break;
- }
- }
-
- if (Index == ARRAY_SIZE (mHobHandles)) {
- DEBUG ((DEBUG_INFO, "HOB[%d]: Type = %d, Offset = 0x%p, Length = 0x%x\n", Count, Hob.Header->HobType, (Hob.Raw - (UINT8 *)HobStart), Hob.Header->HobLength));
- DEBUG ((DEBUG_INFO, " Unkown Hob type\n"));
- PrintHex (Hob.Raw, Hob.Header->HobLength);
- }
-
- Count++;
- Hob.Raw = GET_NEXT_HOB (Hob);
- }
-
- DEBUG ((DEBUG_INFO, "There are totally %d Hobs, the End Hob address is %p\n", Count, Hob.Raw));
+ PrintHobList (HobStart, InternalPrintHobs);
}
diff --git a/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFunc.c
new file mode 100644
index 0000000..ecd2493
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFunc.c
@@ -0,0 +1,74 @@
+/** @file
+ RISC-V specific functionality for DxeLoad.
+
+ Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+ Copyright (c) 2023, Rivos Inc
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include "UefiPayloadEntry.h"
+
+#define STACK_SIZE 0x20000
+
+/**
+ Transfers control to DxeCore.
+
+ This function performs a CPU architecture specific operations to execute
+ the entry point of DxeCore with the parameters of HobList.
+ It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.
+
+ @param DxeCoreEntryPoint The entry point of DxeCore.
+ @param HobList The start of HobList passed to DxeCore.
+
+**/
+VOID
+HandOffToDxeCore (
+ IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint,
+ IN EFI_PEI_HOB_POINTERS HobList
+ )
+{
+ VOID *BaseOfStack;
+ VOID *TopOfStack;
+
+ //
+ //
+ // Allocate 128KB for the Stack
+ //
+ BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
+ if (BaseOfStack == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Can't allocate memory for stack.", __func__));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Compute the top of the stack we were allocated. Pre-allocate a UINTN
+ // for safety.
+ //
+ TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
+ TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
+
+ //
+ // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
+ //
+ UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)BaseOfStack, STACK_SIZE);
+
+ DEBUG ((DEBUG_INFO, "DXE Core new stack at %x, stack pointer at %x\n", BaseOfStack, TopOfStack));
+
+ //
+ // Transfer the control to the entry point of DxeCore.
+ //
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
+ HobList.Raw,
+ NULL,
+ TopOfStack
+ );
+}
diff --git a/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFuncFit.c b/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFuncFit.c
new file mode 100644
index 0000000..e74c4fa
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/RiscV64/DxeLoadFuncFit.c
@@ -0,0 +1,34 @@
+/** @file
+ x64-specifc functionality for DxeLoad.
+
+Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/FdtLib.h>
+#include <Library/PcdLib.h>
+#include "UefiPayloadEntry.h"
+
+/**
+ Entry point to the C language phase of UEFI payload.
+ @param[in] Param1, Hartid which is ignored
+ @param[in] Param2, Device Tree
+ @retval It will not return if SUCCESS, and return error when passing bootloader parameter.
+**/
+EFI_STATUS
+EFIAPI
+_ModuleEntryPoint (
+ IN UINTN Param1,
+ IN UINTN Param2
+ )
+{
+ return FitUplEntryPoint (Param2);
+}
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
index 030a5ba..abda593 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.c
@@ -432,6 +432,14 @@ _ModuleEntryPoint (
UniversalSerialPort->RegisterBase = SerialPortInfo.BaseAddr;
UniversalSerialPort->BaudRate = SerialPortInfo.Baud;
UniversalSerialPort->RegisterStride = (UINT8)SerialPortInfo.RegWidth;
+ // Set PCD here (vs in PlatformHookLib.c) to avoid adding a new field to UniversalSerialPort struct
+ if (SerialPortInfo.InputHertz > 0) {
+ Status = PcdSet32S (PcdSerialClockRate, SerialPortInfo.InputHertz);
+ if (RETURN_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to set PcdSerialClockRate; Status = %r\n", Status));
+ return Status;
+ }
+ }
}
// The library constructors might depend on serial port, so call it after serial port hob
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
index 80ccc50..09fce8d 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
+++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h
@@ -35,6 +35,7 @@
#include <UniversalPayload/UniversalPayload.h>
#include <UniversalPayload/ExtraData.h>
#include <UniversalPayload/SerialPortInfo.h>
+#include <UniversalPayload/DeviceTree.h>
#include <Guid/PcdDataBaseSignatureGuid.h>
#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
@@ -135,6 +136,31 @@ UniversalLoadDxeCore (
);
/**
+ It will Parse FDT -node based on information.
+ @param[in] FdtBase The starting memory address of FdtBase
+ @retval HobList The base address of Hoblist.
+
+**/
+UINT64
+EFIAPI
+FdtNodeParser (
+ IN VOID *FdtBase
+ );
+
+/**
+ It will Parse FDT -custom node based on information.
+ @param[in] FdtBase The starting memory address of FdtBase
+ @param[in] HostList The starting memory address of New Hob list.
+
+**/
+UINTN
+EFIAPI
+CustomFdtNodeParser (
+ IN VOID *FdtBase,
+ IN VOID *HostList
+ );
+
+/**
Transfers control to DxeCore.
This function performs a CPU architecture specific operations to execute
@@ -206,4 +232,46 @@ BuildHobFromAcpi (
IN UINT64 AcpiTableBase
);
+/**
+ Allocates one or more pages .
+
+ Allocates the number of pages of MemoryType 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 availble to satisfy the request, then NULL
+ is returned.
+
+ @param Pages The number of 4 KB pages to allocate.
+ @param MemoryType The Memorytype
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+**/
+VOID *
+EFIAPI
+PayloadAllocatePages (
+ IN UINTN Pages,
+ IN EFI_MEMORY_TYPE MemoryType
+ );
+
+/**
+ Entry point to the C language phase of UEFI payload.
+ @param[in] FdtPrt The starting address of FDT .
+ @retval It will not return if SUCCESS, and return error when passing bootloader parameter.
+**/
+EFI_STATUS
+EFIAPI
+FitUplEntryPoint (
+ IN UINTN BootloaderParameter
+ );
+
+/**
+ Entry point to the C language phase of UEFI payload.
+ @param[in] BootloaderParameter The starting address of bootloader parameter block.
+ @retval It will not return if SUCCESS, and return error when passing bootloader parameter.
+**/
+EFI_STATUS
+EFIAPI
+UplEntryPoint (
+ IN UINTN BootloaderParameter
+ );
+
#endif
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
index a3ff4b8..e84ef66 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
+++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
@@ -96,3 +96,4 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate ## PRODUCES
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c
index f37c00f..5b864ee 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c
@@ -486,12 +486,6 @@ _ModuleEntryPoint (
Status = UniversalLoadDxeCore (DxeFv, &DxeCoreEntryPoint);
ASSERT_EFI_ERROR (Status);
- //
- // Mask off all legacy 8259 interrupt sources
- //
- IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
- IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);
-
Hob.HandoffInformationTable = (EFI_HOB_HANDOFF_INFO_TABLE *)GetFirstHob (EFI_HOB_TYPE_HANDOFF);
HandOffToDxeCore (DxeCoreEntryPoint, Hob);
diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf
index a62da5c..01bb9a1 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf
+++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf
@@ -6,44 +6,37 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
-
[Defines]
INF_VERSION = 1.30
BASE_NAME = UniversalPayloadEntry
FILE_GUID = D4F0F269-1209-4A66-8039-C4D5A700EA4E
MODULE_TYPE = SEC
VERSION_STRING = 1.0
-
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
-
[Sources]
UniversalPayloadEntry.c
LoadDxeCore.c
MemoryAllocation.c
PrintHob.c
AcpiTable.c
-
[Sources.Ia32]
X64/VirtualMemory.h
X64/VirtualMemory.c
Ia32/DxeLoadFunc.c
Ia32/IdtVectorAsm.nasm
-
[Sources.X64]
X64/VirtualMemory.h
X64/VirtualMemory.c
X64/DxeLoadFunc.c
-
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
UefiPayloadPkg/UefiPayloadPkg.dec
-
[LibraryClasses]
BaseMemoryLib
DebugLib
@@ -53,6 +46,7 @@
HobLib
PeCoffLib
CpuLib
+ HobPrintLib
[Guids]
gEfiMemoryTypeInformationGuid
@@ -69,14 +63,10 @@
gUniversalPayloadAcpiTableGuid
gUniversalPayloadPciRootBridgeInfoGuid
gUniversalPayloadSmbios3TableGuid
-
[FeaturePcd.IA32]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES
-
[FeaturePcd.X64]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables ## CONSUMES
-
-
[Pcd.IA32,Pcd.X64]
gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES
@@ -86,12 +76,9 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize ## CONSUMES
-
gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase
gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
-
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES
-
diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
index 346e3fe..6c3603f 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFunc.c
@@ -13,10 +13,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
+#include <Library/FdtLib.h>
#include "X64/VirtualMemory.h"
#include "UefiPayloadEntry.h"
#define STACK_SIZE 0x20000
+extern VOID *mHobList;
+
/**
Transfers control to DxeCore.
@@ -40,6 +43,15 @@ HandOffToDxeCore (
VOID *GhcbBase;
UINTN GhcbSize;
+ // Initialize floating point operating environment to be compliant with UEFI spec.
+ InitializeFloatingPointUnits ();
+
+ //
+ // Mask off all legacy 8259 interrupt sources
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);
+
//
// Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
//
diff --git a/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFuncFit.c b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFuncFit.c
new file mode 100644
index 0000000..35b52a9
--- /dev/null
+++ b/UefiPayloadPkg/UefiPayloadEntry/X64/DxeLoadFuncFit.c
@@ -0,0 +1,135 @@
+/** @file
+ x64-specifc functionality for DxeLoad.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/FdtLib.h>
+#include <Library/PcdLib.h>
+#include "X64/VirtualMemory.h"
+#include "UefiPayloadEntry.h"
+#define STACK_SIZE 0x20000
+
+extern VOID *mHobList;
+
+/**
+ Transfers control to DxeCore.
+
+ This function performs a CPU architecture specific operations to execute
+ the entry point of DxeCore with the parameters of HobList.
+ It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.
+
+ @param DxeCoreEntryPoint The entry point of DxeCore.
+ @param HobList The start of HobList passed to DxeCore.
+
+**/
+VOID
+HandOffToDxeCore (
+ IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint,
+ IN EFI_PEI_HOB_POINTERS HobList
+ )
+{
+ VOID *BaseOfStack;
+ VOID *TopOfStack;
+ UINTN PageTables;
+ VOID *GhcbBase;
+ UINTN GhcbSize;
+
+ // Initialize floating point operating environment to be compliant with UEFI spec.
+ InitializeFloatingPointUnits ();
+
+ //
+ // Mask off all legacy 8259 interrupt sources
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);
+
+ //
+ // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
+ //
+ if (IsNullDetectionEnabled ()) {
+ ClearFirst4KPage (HobList.Raw);
+ BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
+ }
+
+ //
+ // Allocate 128KB for the Stack
+ //
+ BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
+ ASSERT (BaseOfStack != NULL);
+
+ //
+ // Compute the top of the stack we were allocated. Pre-allocate a UINTN
+ // for safety.
+ //
+ TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
+ TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
+
+ //
+ // Get the address and size of the GHCB pages
+ //
+ GhcbBase = 0;
+ GhcbSize = 0;
+
+ PageTables = 0;
+ if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
+ //
+ // Create page table and save PageMapLevel4 to CR3
+ //
+ PageTables = CreateIdentityMappingPageTables (
+ (EFI_PHYSICAL_ADDRESS)(UINTN)BaseOfStack,
+ STACK_SIZE,
+ (EFI_PHYSICAL_ADDRESS)(UINTN)GhcbBase,
+ GhcbSize
+ );
+ } else {
+ //
+ // Set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE
+ // for the DxeIpl and the DxeCore are both X64.
+ //
+ ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE);
+ ASSERT (PcdGetBool (PcdCpuStackGuard) == FALSE);
+ }
+
+ if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
+ AsmWriteCr3 (PageTables);
+ }
+
+ //
+ // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
+ //
+ UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)BaseOfStack, STACK_SIZE);
+
+ //
+ // Transfer the control to the entry point of DxeCore.
+ //
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
+ HobList.Raw,
+ NULL,
+ TopOfStack
+ );
+}
+
+/**
+ Entry point to the C language phase of UEFI payload.
+ @param[in] BootloaderParameter The starting address of bootloader parameter block.
+ @retval It will not return if SUCCESS, and return error when passing bootloader parameter.
+**/
+EFI_STATUS
+EFIAPI
+_ModuleEntryPoint (
+ IN UINTN BootloaderParameter
+ )
+{
+ return FitUplEntryPoint (BootloaderParameter);
+}
diff --git a/UefiPayloadPkg/UefiPayloadPkg.ci.yaml b/UefiPayloadPkg/UefiPayloadPkg.ci.yaml
index 0ceff5b..ac43a7a 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.ci.yaml
+++ b/UefiPayloadPkg/UefiPayloadPkg.ci.yaml
@@ -5,6 +5,9 @@
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
+ "PrEval": {
+ "DscPath": "UefiPayloadPkg.dsc",
+ },
## options defined .pytool/Plugin/LicenseCheck
"LicenseCheck": {
"IgnoreFiles": []
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec
index 23dcdf9..900642b 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dec
+++ b/UefiPayloadPkg/UefiPayloadPkg.dec
@@ -27,6 +27,11 @@
## Include/Guid/UniversalPayloadBase.h
gUniversalPayloadBaseGuid = { 0x03d4c61d, 0x2713, 0x4ec5, {0xa1, 0xcc, 0x88, 0x3b, 0xe9, 0xdc, 0x18, 0xe5 } }
+ ## Include/Guid/UniversalPayloadSerialPortDeviceParentInfo.h
+ gUniversalPayloadSerialPortParentDeviceInfoGuid = { 0xc89c359c, 0xd316, 0x4ff8, {0xa9, 0x8f, 0x60, 0x7d, 0x2c, 0xed, 0x1f, 0xed } }
+
+ ## Include/UniversalPayload/DeviceTree.h
+ gUniversalPayloadDeviceTreeGuid = { 0x6784b889, 0xb13c, 0x4c3b, {0xae, 0x4b, 0xf, 0xa, 0x2e, 0x32, 0xe, 0xa3 } }
gEdkiiDebugPrintErrorLevelGuid = { 0xad82f436, 0x75c5, 0x4aa9, { 0x92, 0x93, 0xc5, 0x55, 0x0a, 0x7f, 0xf9, 0x71 }}
gUefiAcpiBoardInfoGuid = {0xad3d31b, 0xb3d8, 0x4506, {0xae, 0x71, 0x2e, 0xf1, 0x10, 0x6, 0xd9, 0xf}}
gUefiSerialPortInfoGuid = { 0x6c6872fe, 0x56a9, 0x4403, { 0xbb, 0x98, 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1 } }
@@ -38,10 +43,18 @@
gSpiFlashInfoGuid = { 0x2d4aac1b, 0x91a5, 0x4cd5, { 0x9b, 0x5c, 0xb4, 0x0f, 0x5d, 0x28, 0x51, 0xa1 } }
gSmmRegisterInfoGuid = { 0xaa9bd7a7, 0xcafb, 0x4499, { 0xa4, 0xa9, 0xb, 0x34, 0x6b, 0x40, 0xa6, 0x22 } }
gS3CommunicationGuid = { 0x88e31ba1, 0x1856, 0x4b8b, { 0xbb, 0xdf, 0xf8, 0x16, 0xdd, 0x94, 0xa, 0xef } }
+ gUplPciSegmentInfoHobGuid = {0x37e0e3a9, 0xb3fc, 0x4e85, { 0x97, 0x2b, 0x40, 0x82, 0xfc, 0x79, 0x40, 0x54 } }
[Ppis]
gEfiPayLoadHobBasePpiGuid = { 0xdbe23aa1, 0xa342, 0x4b97, {0x85, 0xb6, 0xb2, 0x26, 0xf1, 0x61, 0x73, 0x89} }
+ #
+ # This PPI is used to trigger Payload callback event in end of PEI.
+ #
+ gUplReadyToPayloadPpiGuid = { 0x67c8dfb1, 0x61f4, 0x439c, { 0x84, 0x4e, 0x2b, 0xdf, 0xf1, 0x07, 0xad, 0x51 }}
+
+[Protocols]
+
################################################################################
#
# PCD Declarations section - list of all PCDs Declared by this Package
@@ -75,3 +88,18 @@ gUefiPayloadPkgTokenSpaceGuid.PcdBootManagerEscape|FALSE|BOOLEAN|0x00000020
## FFS filename to find the default variable initial data file.
# @Prompt FFS Name of variable initial data file
gUefiPayloadPkgTokenSpaceGuid.PcdNvsDataFile |{ 0x1a, 0xf1, 0xb1, 0xae, 0x42, 0xcc, 0xcf, 0x4e, 0xac, 0x60, 0xdb, 0xab, 0xf6, 0xca, 0x69, 0xe6 }|VOID*|0x00000025
+
+
+## Indicates if Universal payload support FDT
+#- PcdHandOffFdtEnable is TRUE, HandOffData is FDT
+#- PcdHandOffFdtEnable is FALSE, HandOffData is HOB
+gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable|FALSE|BOOLEAN|0x00000026
+
+
+gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemBase |0xFFFFFFFF |UINT32|0x00000027
+gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemLimit |0x00000000 |UINT32|0x00000028
+gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBBase |0xFFFFFFFFFFFFFFFF |UINT64|0x00000029
+gUefiPayloadPkgTokenSpaceGuid.PcdPciReservedPMemAbove4GBLimit|0x0000000000000000 |UINT64|0x0000002A
+
+gUefiPayloadPkgTokenSpaceGuid.SizeOfIoSpace|0|UINT8|0x0000002B
+gUefiPayloadPkgTokenSpaceGuid.PcdFDTPageSize|8|UINT8|0x0000002C
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 2860a65..fe7987f 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -42,6 +42,7 @@
DEFINE BOOTSPLASH_IMAGE = FALSE
DEFINE NVME_ENABLE = TRUE
DEFINE CAPSULE_SUPPORT = FALSE
+ DEFINE LOCKBOX_SUPPORT = FALSE
#
# Crypto Support
@@ -226,6 +227,7 @@
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
HobLib|UefiPayloadPkg/Library/DxeHobLib/DxeHobLib.inf
+ CustomFdtNodeParserLib|UefiPayloadPkg/Library/CustomFdtNodeParserNullLib/CustomFdtNodeParserNullLib.inf
#
# UEFI & PI
@@ -297,7 +299,11 @@
!endif
DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
+!if $(LOCKBOX_SUPPORT) == TRUE
+ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
+!else
LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+!endif
FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
!if $(VARIABLE_SUPPORT) == "EMU"
@@ -317,6 +323,8 @@
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
SmmRelocationLib|UefiCpuPkg/Library/SmmRelocationLib/SmmRelocationLib.inf
+ HobPrintLib|MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf
+ BuildFdtLib|UefiPayloadPkg/Library/BuildFdtLib/BuildFdtLib.inf
[LibraryClasses.common]
!if $(BOOTSPLASH_IMAGE)
@@ -349,6 +357,9 @@
SerialPortLib|UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf
!endif
+ # StackCheckLib is not linked for SEC modules by default, this package can link it against its SEC modules
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[LibraryClasses.common.DXE_CORE]
DxeHobListLib|UefiPayloadPkg/Library/DxeHobListLibNull/DxeHobListLibNull.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
@@ -470,6 +481,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable|TRUE
+ gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable|FALSE
+
gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile|{ 0x57, 0x72, 0xcf, 0x80, 0xab, 0x87, 0xf9, 0x47, 0xa3, 0xfe, 0xD5, 0x0B, 0x76, 0xd8, 0x95, 0x41 }
@@ -513,10 +526,13 @@
!endif
!endif
+
[PcdsPatchableInModule.X64]
!if $(NETWORK_DRIVER_ENABLE) == TRUE
gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|TRUE
!endif
+ gUefiPayloadPkgTokenSpaceGuid.SizeOfIoSpace|16
+ gUefiPayloadPkgTokenSpaceGuid.PcdFDTPageSize|8
[PcdsPatchableInModule.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
@@ -540,7 +556,7 @@
# The following parameters are set by Library/PlatformHookLib
#
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|FALSE
- gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x3F8
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|$(BAUD_RATE)
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1
@@ -574,6 +590,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPcieResizableBarSupport|FALSE
gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize|0x1
gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode|1
@@ -635,7 +652,15 @@
!if $(UNIVERSAL_PAYLOAD_FORMAT) == "ELF"
UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf
!elseif $(UNIVERSAL_PAYLOAD_FORMAT) == "FIT"
- UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf
+ UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf {
+ <LibraryClasses>
+ !if gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable == TRUE
+ FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
+ CustomFdtNodeParserLib|UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf
+ NULL|UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
+ !endif
+ NULL|UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf
+ }
!else
UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
!endif
@@ -648,7 +673,15 @@
!if $(UNIVERSAL_PAYLOAD_FORMAT) == "ELF"
UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf
!elseif $(UNIVERSAL_PAYLOAD_FORMAT) == "FIT"
- UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf
+ UefiPayloadPkg/UefiPayloadEntry/FitUniversalPayloadEntry.inf {
+ <LibraryClasses>
+ !if gUefiPayloadPkgTokenSpaceGuid.PcdHandOffFdtEnable == TRUE
+ FdtLib|MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
+ CustomFdtNodeParserLib|UefiPayloadPkg/Library/CustomFdtNodeParserLib/CustomFdtNodeParserLib.inf
+ NULL|UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
+ !endif
+ NULL|UefiPayloadPkg/Library/HobParseLib/HobParseLib.inf
+ }
!else
UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
!endif
diff --git a/UefiPayloadPkg/UniversalPayloadBuild.py b/UefiPayloadPkg/UniversalPayloadBuild.py
index 59c78a2..c3d02cb 100644
--- a/UefiPayloadPkg/UniversalPayloadBuild.py
+++ b/UefiPayloadPkg/UniversalPayloadBuild.py
@@ -269,7 +269,7 @@ def BuildUniversalPayload(Args):
continue
Type = entry.type
Offset = entry.rva + fit_image_info_header.DataOffset
- RelocBinary += Type.to_bytes (8, 'little') + Offset.to_bytes (8, 'little')
+ RelocBinary += Offset.to_bytes (8, 'little') + Type.to_bytes (8, 'little')
RelocBinary += b'\x00' * (0x1000 - (len(RelocBinary) % 0x1000))
#
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc
new file mode 100644
index 0000000..0de6e43
--- /dev/null
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc
@@ -0,0 +1,22 @@
+## @file
+# UnitTestFrameworkPkg DSC include file for host and target based test DSC
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[LibraryClasses]
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf
+ UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+
+[PcdsFixedAtBuild]
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+
+[BuildOptions]
+ MSFT:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED
+ GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED
+ XCODE:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
index 83d3205..c56db18 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
@@ -6,7 +6,7 @@
#
##
-!include UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc
[LibraryClasses.common.HOST_APPLICATION]
BaseLib|MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
@@ -23,6 +23,7 @@
UefiBootServicesTableLib|UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.inf
PeiServicesTablePointerLib|UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.inf
NULL|UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.inf
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNullHostApplication.inf
[BuildOptions]
MSFT:*_*_*_CC_FLAGS = /MT
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
index 1a059ed..c0c546d 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
@@ -6,6 +6,8 @@
#
##
+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgCommon.dsc.inc
+
[LibraryClasses]
#
# Entry point
@@ -15,20 +17,18 @@
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
- BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
- PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
- PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf
UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf
UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf
+ NULL|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
[LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM]
NULL|UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf
@@ -45,20 +45,6 @@
[LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
NULL|UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf
-[LibraryClasses.ARM, LibraryClasses.AARCH64]
- #
- # It is not possible to prevent ARM compiler calls to generic intrinsic functions.
- # This library provides the instrinsic functions generated by a given compiler.
- # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
- #
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
- #
- # Since software stack checking may be heuristically enabled by the compiler
- # include BaseStackCheckLib unconditionally.
- #
- NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
-
[LibraryClasses.common.PEIM]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
@@ -66,11 +52,3 @@
[LibraryClasses.common.UEFI_APPLICATION]
UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.inf
-
-[PcdsFixedAtBuild]
- gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
-
-[BuildOptions]
- MSFT:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED
- GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED
- XCODE:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -D EDKII_UNIT_TEST_FRAMEWORK_ENABLED
diff --git a/edksetup.bat b/edksetup.bat
index 71ceefb..0695388 100755
--- a/edksetup.bat
+++ b/edksetup.bat
@@ -146,6 +146,7 @@ if defined CYGWIN_HOME (
:cygwin_done
if /I "%1"=="Rebuild" shift
if /I "%1"=="ForceRebuild" shift
+if /I "%1"=="VS2022" shift
if /I "%1"=="VS2019" shift
if /I "%1"=="VS2017" shift
if /I "%1"=="VS2015" shift
@@ -161,6 +162,7 @@ if "%1"=="" goto end
@echo VS2015 Set the env for VS2015 build.
@echo VS2017 Set the env for VS2017 build.
@echo VS2019 Set the env for VS2019 build.
+ @echo VS2022 Set the env for VS2022 build.
@echo.
@echo Note that target.template, tools_def.template and build_rules.template
@echo will only be copied to target.txt, tools_def.txt and build_rule.txt
diff --git a/pip-requirements.txt b/pip-requirements.txt
index e07b9ca..c8de90f 100644
--- a/pip-requirements.txt
+++ b/pip-requirements.txt
@@ -8,13 +8,12 @@
#
# https://pypi.org/project/pip/
# https://pip.pypa.io/en/stable/user_guide/#requirements-files
-# https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format
+# https://pip.pypa.io/en/stable/reference/requirements-file-format
# https://www.python.org/dev/peps/pep-0440/#version-specifiers
##
-edk2-pytool-library==0.21.8
-edk2-pytool-extensions==0.27.6
-edk2-basetools==0.1.51
-antlr4-python3-runtime==4.7.1
+edk2-pytool-library~=0.21.9
+edk2-pytool-extensions~=0.27.10
+antlr4-python3-runtime>=4.7.1
lcov-cobertura==2.0.2
-regex==2024.5.15
+regex==2024.7.24